@@ -518,6 +518,7 @@ template<typename T>
518518inline v8::Local<v8::Value> v8js_named_property_callback (v8::Local<v8::String> property, const v8::PropertyCallbackInfo<T> &info, property_op_t callback_type, v8::Local<v8::Value> set_value) /* {{{ */
519519{
520520 v8::Isolate *isolate = info.GetIsolate ();
521+ v8js_ctx *ctx = (v8js_ctx *) isolate->GetData (0 );
521522 v8::String::Utf8Value cstr (property);
522523 const char *name = ToCString (cstr);
523524 uint name_len = strlen (name);
@@ -535,9 +536,8 @@ inline v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::String> p
535536 zval *php_value;
536537
537538 zval *object = reinterpret_cast <zval *>(v8::External::Cast (*self->GetHiddenValue (V8JS_SYM (PHPJS_OBJECT_KEY)))->Value ());
538- v8::Local<v8::FunctionTemplate> tmpl =
539- v8::Local<v8::FunctionTemplate>::New
540- (isolate, *reinterpret_cast <v8js_tmpl_t *>(self->GetAlignedPointerFromInternalField (0 )));
539+ v8js_tmpl_t *tmpl_ptr = reinterpret_cast <v8js_tmpl_t *>(self->GetAlignedPointerFromInternalField (0 ));
540+ v8::Local<v8::FunctionTemplate> tmpl = v8::Local<v8::FunctionTemplate>::New (isolate, *tmpl_ptr);
541541 ce = scope = Z_OBJCE_P (object);
542542
543543 /* First, check the (case-insensitive) method table */
@@ -568,14 +568,35 @@ inline v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::String> p
568568 // Fake __call implementation
569569 // (only use this if method_ptr==NULL, which means
570570 // there is no actual PHP __call() implementation)
571- v8::Local<v8::Function> cb =
572- v8::FunctionTemplate::New (isolate,
573- v8js_fake_call_impl, V8JS_NULL,
574- v8::Signature::New (isolate, tmpl))->GetFunction ();
571+ v8::Local<v8::FunctionTemplate> ft;
572+ try {
573+ ft = v8::Local<v8::FunctionTemplate>::New
574+ (isolate, ctx->call_impls .at (tmpl_ptr));
575+ }
576+ catch (const std::out_of_range &) {
577+ ft = v8::FunctionTemplate::New (isolate,
578+ v8js_fake_call_impl, V8JS_NULL,
579+ v8::Signature::New (isolate, tmpl));
580+ v8js_tmpl_t *persistent_ft = &ctx->call_impls [tmpl_ptr];
581+ persistent_ft->Reset (isolate, ft);
582+ }
583+ v8::Local<v8::Function> cb = ft->GetFunction ();
575584 cb->SetName (property);
576585 ret_value = cb;
577586 } else {
578- ret_value = PHP_V8JS_CALLBACK (isolate, method_ptr, tmpl);
587+ v8::Local<v8::FunctionTemplate> ft;
588+ try {
589+ ft = v8::Local<v8::FunctionTemplate>::New
590+ (isolate, ctx->method_tmpls .at (method_ptr));
591+ }
592+ catch (const std::out_of_range &) {
593+ ft = v8::FunctionTemplate::New (isolate, v8js_php_callback,
594+ v8::External::New ((isolate), method_ptr),
595+ v8::Signature::New ((isolate), tmpl));
596+ v8js_tmpl_t *persistent_ft = &ctx->method_tmpls [method_ptr];
597+ persistent_ft->Reset (isolate, ft);
598+ }
599+ ret_value = ft->GetFunction ();
579600 }
580601 }
581602 } else if (callback_type == V8JS_PROP_QUERY) {
0 commit comments