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:
parent
8e84f99830
commit
f6105ff3cf
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user