0
0
mirror of https://github.com/phpv8/v8js.git synced 2024-12-22 23:51:51 +00:00

v8js_class pt.1: pending_exception, module_loader, weak_objects, jsext

This commit is contained in:
Stefan Siegl 2015-08-24 22:05:27 +02:00
parent 8e84f99830
commit f6105ff3cf
3 changed files with 38 additions and 41 deletions

View File

@ -61,8 +61,8 @@ struct v8js_jsext {
HashTable *deps_ht; HashTable *deps_ht;
const char **deps; const char **deps;
int deps_count; int deps_count;
char *name; zend_string *name;
char *source; zend_string *source;
v8::Extension *extension; v8::Extension *extension;
}; };
/* }}} */ /* }}} */
@ -84,14 +84,8 @@ static void v8js_free_storage(void *object TSRMLS_DC) /* {{{ */
v8js_ctx *c = (v8js_ctx *) object; v8js_ctx *c = (v8js_ctx *) object;
zend_object_std_dtor(&c->std TSRMLS_CC); zend_object_std_dtor(&c->std TSRMLS_CC);
zval_dtor(&c->pending_exception);
if (c->pending_exception) { zval_dtor(&c->module_loader);
zval_ptr_dtor(&c->pending_exception);
}
if (c->module_loader) {
zval_ptr_dtor(&c->module_loader);
}
/* Delete PHP global object from JavaScript */ /* Delete PHP global object from JavaScript */
if (!c->context.IsEmpty()) { if (!c->context.IsEmpty()) {
@ -130,10 +124,12 @@ static void v8js_free_storage(void *object TSRMLS_DC) /* {{{ */
c->context.~Persistent(); c->context.~Persistent();
/* Dispose yet undisposed weak refs */ /* Dispose yet undisposed weak refs */
for (std::map<zval *, v8js_persistent_obj_t>::iterator it = c->weak_objects.begin(); for (std::map<zend_object *, v8js_persistent_obj_t>::iterator it = c->weak_objects.begin();
it != c->weak_objects.end(); ++it) { it != c->weak_objects.end(); ++it) {
zval *value = it->first; zend_object *object = it->first;
zval_ptr_dtor(&value); zval value;
ZVAL_OBJ(&value, object);
zval_dtor(&value);
c->isolate->AdjustAmountOfExternalAllocatedMemory(-1024); c->isolate->AdjustAmountOfExternalAllocatedMemory(-1024);
it->second.Reset(); it->second.Reset();
} }
@ -187,7 +183,7 @@ static void v8js_free_storage(void *object TSRMLS_DC) /* {{{ */
} }
/* }}} */ /* }}} */
static zend_object_value v8js_new(zend_class_entry *ce TSRMLS_DC) /* {{{ */ static zend_object* v8js_new(zend_class_entry *ce TSRMLS_DC) /* {{{ */
{ {
zend_object_value retval; zend_object_value retval;
v8js_ctx *c; v8js_ctx *c;
@ -210,7 +206,7 @@ static zend_object_value v8js_new(zend_class_entry *ce TSRMLS_DC) /* {{{ */
new(&c->accessor_list) std::vector<v8js_accessor_ctx *>(); new(&c->accessor_list) std::vector<v8js_accessor_ctx *>();
new(&c->weak_closures) std::map<v8js_tmpl_t *, v8js_persistent_obj_t>(); 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->weak_objects) std::map<zend_object *, v8js_persistent_obj_t>();
new(&c->v8js_v8objects) std::list<v8js_v8object *>(); new(&c->v8js_v8objects) std::list<v8js_v8object *>();
new(&c->script_objects) std::vector<v8js_script *>(); new(&c->script_objects) std::vector<v8js_script *>();
@ -247,8 +243,8 @@ static void v8js_jsext_dtor(v8js_jsext *jsext) /* {{{ */
v8js_free_ext_strarr(jsext->deps, jsext->deps_count); v8js_free_ext_strarr(jsext->deps, jsext->deps_count);
} }
delete jsext->extension; delete jsext->extension;
free(jsext->name); zend_string_release(jsext->name);
free(jsext->source); zend_string_release(jsext->source);
} }
/* }}} */ /* }}} */
@ -318,7 +314,7 @@ static PHP_METHOD(V8Js, __construct)
/* Throw PHP exception if uncaught exceptions exist */ /* Throw PHP exception if uncaught exceptions exist */
c->report_uncaught = report_uncaught; c->report_uncaught = report_uncaught;
c->pending_exception = NULL; ZVAL_NULL(&c->pending_exception);
c->in_execution = 0; c->in_execution = 0;
#if PHP_V8_API_VERSION >= 4004044 #if PHP_V8_API_VERSION >= 4004044
@ -337,7 +333,7 @@ static PHP_METHOD(V8Js, __construct)
c->memory_limit = 0; c->memory_limit = 0;
c->memory_limit_hit = false; c->memory_limit_hit = false;
c->module_loader = NULL; ZVAL_NULL(&c->module_loader);
/* Include extensions used by this context */ /* Include extensions used by this context */
/* Note: Extensions registered with auto_enable do not need to be added separately like this. */ /* Note: Extensions registered with auto_enable do not need to be added separately like this. */
@ -662,7 +658,7 @@ static PHP_METHOD(V8Js, clearPendingException)
static PHP_METHOD(V8Js, setModuleLoader) static PHP_METHOD(V8Js, setModuleLoader)
{ {
v8js_ctx *c; v8js_ctx *c;
zval *callable; zval callable;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &callable) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &callable) == FAILURE) {
return; return;
@ -670,8 +666,7 @@ static PHP_METHOD(V8Js, setModuleLoader)
c = (v8js_ctx *) zend_object_store_get_object(getThis() TSRMLS_CC); c = (v8js_ctx *) zend_object_store_get_object(getThis() TSRMLS_CC);
c->module_loader = callable; ZVAL_COPY(&c->module_loader, &callable);
Z_ADDREF_P(c->module_loader);
} }
/* }}} */ /* }}} */
@ -792,14 +787,14 @@ static void v8js_script_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
} }
/* }}} */ /* }}} */
static int v8js_register_extension(char *name, uint name_len, char *source, uint source_len, zval *deps_arr, zend_bool auto_enable TSRMLS_DC) /* {{{ */ static int v8js_register_extension(zend_string *name, zend_string *source, zval *deps_arr, zend_bool auto_enable TSRMLS_DC) /* {{{ */
{ {
v8js_jsext *jsext = NULL; v8js_jsext *jsext = NULL;
if (!V8JSG(extensions)) { if (!V8JSG(extensions)) {
V8JSG(extensions) = (HashTable *) malloc(sizeof(HashTable)); V8JSG(extensions) = (HashTable *) malloc(sizeof(HashTable));
zend_hash_init(V8JSG(extensions), 1, NULL, (dtor_func_t) v8js_jsext_dtor, 1); zend_hash_init(V8JSG(extensions), 1, NULL, (dtor_func_t) v8js_jsext_dtor, 1);
} else if (zend_hash_exists(V8JSG(extensions), name, name_len + 1)) { } else if (zend_hash_exists(V8JSG(extensions), name)) {
return FAILURE; return FAILURE;
} }
@ -817,8 +812,8 @@ static int v8js_register_extension(char *name, uint name_len, char *source, uint
} }
jsext->auto_enable = auto_enable; jsext->auto_enable = auto_enable;
jsext->name = zend_strndup(name, name_len); jsext->name = zend_string_copy(name);
jsext->source = zend_strndup(source, source_len); jsext->source = zend_string_copy(source);
if (jsext->deps) { if (jsext->deps) {
jsext->deps_ht = (HashTable *) malloc(sizeof(HashTable)); jsext->deps_ht = (HashTable *) malloc(sizeof(HashTable));
@ -826,9 +821,9 @@ static int v8js_register_extension(char *name, uint name_len, char *source, uint
zend_hash_copy(jsext->deps_ht, Z_ARRVAL_P(deps_arr), (copy_ctor_func_t) v8js_persistent_zval_ctor, NULL, sizeof(zval *)); zend_hash_copy(jsext->deps_ht, Z_ARRVAL_P(deps_arr), (copy_ctor_func_t) v8js_persistent_zval_ctor, NULL, sizeof(zval *));
} }
jsext->extension = new v8::Extension(jsext->name, jsext->source, jsext->deps_count, jsext->deps); jsext->extension = new v8::Extension(jsext->name->val, jsext->source, jsext->deps_count, jsext->deps);
if (zend_hash_add(V8JSG(extensions), name, name_len + 1, jsext, sizeof(v8js_jsext), NULL) == FAILURE) { if (zend_hash_add_ptr(V8JSG(extensions), name, jsext) == FAILURE) {
v8js_jsext_dtor(jsext); v8js_jsext_dtor(jsext);
free(jsext); free(jsext);
return FAILURE; return FAILURE;

View File

@ -36,7 +36,7 @@ struct v8js_ctx {
v8::Persistent<v8::String> object_name; v8::Persistent<v8::String> object_name;
v8::Persistent<v8::Context> context; v8::Persistent<v8::Context> context;
zend_bool report_uncaught; zend_bool report_uncaught;
zval *pending_exception; zval pending_exception;
int in_execution; int in_execution;
v8::Isolate *isolate; v8::Isolate *isolate;
@ -47,13 +47,13 @@ struct v8js_ctx {
v8::Persistent<v8::FunctionTemplate> global_template; v8::Persistent<v8::FunctionTemplate> global_template;
zval *module_loader; zval module_loader;
std::vector<char *> modules_stack; std::vector<char *> modules_stack;
std::vector<char *> modules_base; std::vector<char *> modules_base;
std::map<char *, v8js_persistent_obj_t, cmp_str> modules_loaded; std::map<char *, v8js_persistent_obj_t, cmp_str> modules_loaded;
std::map<const char *,v8js_tmpl_t> template_cache; std::map<const char *,v8js_tmpl_t> template_cache;
std::map<zval *, v8js_persistent_obj_t> weak_objects; std::map<zend_object *, v8js_persistent_obj_t> weak_objects;
std::map<v8js_tmpl_t *, v8js_persistent_obj_t> weak_closures; std::map<v8js_tmpl_t *, v8js_persistent_obj_t> weak_closures;
std::list<v8js_v8object *> v8js_v8objects; std::list<v8js_v8object *> v8js_v8objects;

View File

@ -189,7 +189,7 @@ static void v8js_construct_callback(const v8::FunctionCallbackInfo<v8::Value>& i
// @todo assert constructor call // @todo assert constructor call
v8::Handle<v8::Object> newobj = info.This(); v8::Handle<v8::Object> newobj = info.This();
v8::Local<v8::External> php_object; v8::Local<v8::External> php_object;
zval *value; zval value;
if (!info.IsConstructCall()) { if (!info.IsConstructCall()) {
return; return;
@ -205,9 +205,9 @@ static void v8js_construct_callback(const v8::FunctionCallbackInfo<v8::Value>& i
// Object created by v8js in v8js_hash_to_jsobj, PHP object passed as v8::External. // Object created by v8js in v8js_hash_to_jsobj, PHP object passed as v8::External.
php_object = v8::Local<v8::External>::Cast(info[0]); php_object = v8::Local<v8::External>::Cast(info[0]);
zend_object *object = reinterpret_cast<zval *>(php_object->Value()); zend_object *object = reinterpret_cast<zval *>(php_object->Value());
value = NULL; // @fixme wrap object in zval ZVAL_OBJ(&value, object);
if(ctx->weak_objects.count(value)) { if(ctx->weak_objects.count(object)) {
// We already exported this object, hence no need to add another // We already exported this object, hence no need to add another
// ref, v8 won't give us a second weak-object callback anyways. // ref, v8 won't give us a second weak-object callback anyways.
newobj->SetAlignedPointerInInternalField(0, ext_tmpl->Value()); newobj->SetAlignedPointerInInternalField(0, ext_tmpl->Value());
@ -246,8 +246,8 @@ static void v8js_construct_callback(const v8::FunctionCallbackInfo<v8::Value>& i
// Since we got to decrease the reference count again, in case v8 garbage collector // Since we got to decrease the reference count again, in case v8 garbage collector
// decides to dispose the JS object, we add a weak persistent handle and register // decides to dispose the JS object, we add a weak persistent handle and register
// a callback function that removes the reference. // a callback function that removes the reference.
ctx->weak_objects[value].Reset(isolate, newobj); ctx->weak_objects[Z_OBJ(value)].Reset(isolate, newobj);
ctx->weak_objects[value].SetWeak(value, v8js_weak_object_callback); ctx->weak_objects[Z_OBJ(value)].SetWeak(value, v8js_weak_object_callback);
// Just tell v8 that we're allocating some external memory // Just tell v8 that we're allocating some external memory
// (for the moment we just always tell 1k instead of trying to find out actual values) // (for the moment we just always tell 1k instead of trying to find out actual values)
@ -256,16 +256,18 @@ static void v8js_construct_callback(const v8::FunctionCallbackInfo<v8::Value>& i
/* }}} */ /* }}} */
static void v8js_weak_object_callback(const v8::WeakCallbackData<v8::Object, zval> &data) { static void v8js_weak_object_callback(const v8::WeakCallbackData<v8::Object, zend_object> &data) {
v8::Isolate *isolate = data.GetIsolate(); v8::Isolate *isolate = data.GetIsolate();
zval *value = data.GetParameter(); zend_object *object = data.GetParameter();
zval_ptr_dtor(&value); zval value;
ZVAL_OBJ(&value, object);
zval_dtor(&value);
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0); v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
ctx->weak_objects.at(value).Reset(); ctx->weak_objects.at(object).Reset();
ctx->weak_objects.erase(value); ctx->weak_objects.erase(object);
isolate->AdjustAmountOfExternalAllocatedMemory(-1024); isolate->AdjustAmountOfExternalAllocatedMemory(-1024);
} }