0
0
mirror of https://github.com/phpv8/v8js.git synced 2024-12-22 18:41:52 +00:00

Merge pull request #161 from stesie/method-tmpl-cache

Cache v8::FunctionTemplates created by v8js_named_property_callback
This commit is contained in:
Stefan Siegl 2015-08-27 15:29:19 +02:00
commit 415b64c7e5
3 changed files with 47 additions and 8 deletions

View File

@ -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 *>();

View File

@ -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;

View File

@ -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) {