mirror of
https://github.com/phpv8/v8js.git
synced 2024-11-08 14:48:40 +00:00
Cache v8::FunctionTemplates created by v8js_named_property_callback
This commit is contained in:
parent
53995ac616
commit
78dd0a9ff0
@ -109,6 +109,20 @@ static void v8js_free_storage(void *object TSRMLS_DC) /* {{{ */
|
||||
c->global_template.Reset();
|
||||
c->global_template.~Persistent();
|
||||
|
||||
/* Clear persistent call_impl & method_tmpls templates */
|
||||
for (std::map<v8js_tmpl_t *, v8js_tmpl_t>::iterator it = c->call_impls.begin();
|
||||
it != c->call_impls.end(); ++it) {
|
||||
// No need to free it->first, as it is stored in c->template_cache and freed below
|
||||
it->second.Reset();
|
||||
}
|
||||
c->call_impls.~map();
|
||||
|
||||
for (std::map<zend_function *, v8js_tmpl_t>::iterator it = c->method_tmpls.begin();
|
||||
it != c->method_tmpls.end(); ++it) {
|
||||
it->second.Reset();
|
||||
}
|
||||
c->method_tmpls.~map();
|
||||
|
||||
/* Clear persistent handles in template cache */
|
||||
for (std::map<const char *,v8js_tmpl_t>::iterator it = c->template_cache.begin();
|
||||
it != c->template_cache.end(); ++it) {
|
||||
@ -217,6 +231,8 @@ static zend_object_value v8js_new(zend_class_entry *ce TSRMLS_DC) /* {{{ */
|
||||
|
||||
new(&c->weak_closures) std::map<v8js_tmpl_t *, v8js_persistent_obj_t>();
|
||||
new(&c->weak_objects) std::map<zval *, v8js_persistent_obj_t>();
|
||||
new(&c->call_impls) std::map<v8js_tmpl_t *, v8js_tmpl_t>();
|
||||
new(&c->method_tmpls) std::map<zend_function *, v8js_tmpl_t>();
|
||||
|
||||
new(&c->v8js_v8objects) std::list<v8js_v8object *>();
|
||||
new(&c->script_objects) std::vector<v8js_script *>();
|
||||
|
@ -55,6 +55,8 @@ struct v8js_ctx {
|
||||
|
||||
std::map<zval *, v8js_persistent_obj_t> weak_objects;
|
||||
std::map<v8js_tmpl_t *, v8js_persistent_obj_t> weak_closures;
|
||||
std::map<v8js_tmpl_t *, v8js_tmpl_t> call_impls;
|
||||
std::map<zend_function *, v8js_tmpl_t> method_tmpls;
|
||||
|
||||
std::list<v8js_v8object *> v8js_v8objects;
|
||||
|
||||
|
@ -518,6 +518,7 @@ template<typename T>
|
||||
inline 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) /* {{{ */
|
||||
{
|
||||
v8::Isolate *isolate = info.GetIsolate();
|
||||
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
|
||||
v8::String::Utf8Value cstr(property);
|
||||
const char *name = ToCString(cstr);
|
||||
uint name_len = strlen(name);
|
||||
@ -535,9 +536,8 @@ inline v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::String> p
|
||||
zval *php_value;
|
||||
|
||||
zval *object = reinterpret_cast<zval *>(v8::External::Cast(*self->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY)))->Value());
|
||||
v8::Local<v8::FunctionTemplate> tmpl =
|
||||
v8::Local<v8::FunctionTemplate>::New
|
||||
(isolate, *reinterpret_cast<v8js_tmpl_t *>(self->GetAlignedPointerFromInternalField(0)));
|
||||
v8js_tmpl_t *tmpl_ptr = reinterpret_cast<v8js_tmpl_t *>(self->GetAlignedPointerFromInternalField(0));
|
||||
v8::Local<v8::FunctionTemplate> tmpl = v8::Local<v8::FunctionTemplate>::New(isolate, *tmpl_ptr);
|
||||
ce = scope = Z_OBJCE_P(object);
|
||||
|
||||
/* 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
|
||||
// Fake __call implementation
|
||||
// (only use this if method_ptr==NULL, which means
|
||||
// there is no actual PHP __call() implementation)
|
||||
v8::Local<v8::Function> cb =
|
||||
v8::FunctionTemplate::New(isolate,
|
||||
v8js_fake_call_impl, V8JS_NULL,
|
||||
v8::Signature::New(isolate, tmpl))->GetFunction();
|
||||
v8::Local<v8::FunctionTemplate> ft;
|
||||
try {
|
||||
ft = v8::Local<v8::FunctionTemplate>::New
|
||||
(isolate, ctx->call_impls.at(tmpl_ptr));
|
||||
}
|
||||
catch (const std::out_of_range &) {
|
||||
ft = v8::FunctionTemplate::New(isolate,
|
||||
v8js_fake_call_impl, V8JS_NULL,
|
||||
v8::Signature::New(isolate, tmpl));
|
||||
v8js_tmpl_t *persistent_ft = &ctx->call_impls[tmpl_ptr];
|
||||
persistent_ft->Reset(isolate, ft);
|
||||
}
|
||||
v8::Local<v8::Function> cb = ft->GetFunction();
|
||||
cb->SetName(property);
|
||||
ret_value = cb;
|
||||
} else {
|
||||
ret_value = PHP_V8JS_CALLBACK(isolate, method_ptr, tmpl);
|
||||
v8::Local<v8::FunctionTemplate> ft;
|
||||
try {
|
||||
ft = v8::Local<v8::FunctionTemplate>::New
|
||||
(isolate, ctx->method_tmpls.at(method_ptr));
|
||||
}
|
||||
catch (const std::out_of_range &) {
|
||||
ft = v8::FunctionTemplate::New(isolate, v8js_php_callback,
|
||||
v8::External::New((isolate), method_ptr),
|
||||
v8::Signature::New((isolate), tmpl));
|
||||
v8js_tmpl_t *persistent_ft = &ctx->method_tmpls[method_ptr];
|
||||
persistent_ft->Reset(isolate, ft);
|
||||
}
|
||||
ret_value = ft->GetFunction();
|
||||
}
|
||||
}
|
||||
} else if (callback_type == V8JS_PROP_QUERY) {
|
||||
|
Loading…
Reference in New Issue
Block a user