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

support php8

This commit is contained in:
Albert 2021-06-03 09:33:51 +08:00
parent 6a7753a43a
commit 97cc819ade
10 changed files with 628 additions and 165 deletions

View File

@ -50,7 +50,11 @@ static zval v8js_array_access_dispatch(zend_object *object, const char *method_n
fci.params = params;
fci.object = object;
#if (PHP_MAJOR_VERSION < 8)
fci.no_separation = 0;
#else
fci.named_params = NULL;
#endif
zend_call_function(&fci, NULL);
zval_dtor(&fci.function_name);

View File

@ -506,7 +506,11 @@ static PHP_METHOD(V8Js, __construct)
V8JS_GLOBAL(isolate)->DefineOwnProperty(context, object_name_js, php_obj, v8::ReadOnly);
/* Export public property values */
#if (PHP_MAJOR_VERSION < 8)
HashTable *properties = zend_std_get_properties(getThis());
#else
HashTable *properties = zend_std_get_properties(Z_OBJ_P(getThis()));
#endif
zval *value;
zend_string *member;
@ -665,7 +669,6 @@ static void v8js_compile_script(zval *this_ptr, const zend_string *str, const ze
static void v8js_execute_script(zval *this_ptr, v8js_script *res, long flags, long time_limit, size_t memory_limit, zval **return_value)
{
v8js_ctx *c = Z_V8JS_CTX_OBJ_P(this_ptr);
if (res->ctx != c) {
zend_error(E_WARNING, "Script resource from wrong V8Js object passed");
ZVAL_BOOL(*return_value, 0);
@ -1306,7 +1309,33 @@ const zend_function_entry v8js_methods[] = { /* {{{ */
/* V8Js object handlers */
#if PHP_VERSION_ID >= 80000
static SINCE74(zval*, void) v8js_write_property(zend_object *object, zend_string *member, zval *value, void **cache_slot) /* {{{ */
{
v8js_ctx *c = Z_V8JS_CTX_OBJ(object);
V8JS_CTX_PROLOGUE_EX(c, SINCE74(value,));
/* Check whether member is public, if so, export to V8. */
zend_property_info *property_info = zend_get_property_info(c->std.ce, member, 1);
if(!property_info ||
(property_info != ZEND_WRONG_PROPERTY_INFO &&
(property_info->flags & ZEND_ACC_PUBLIC))) {
/* Global PHP JS object */
v8::Local<v8::String> object_name_js = v8::Local<v8::String>::New(isolate, c->object_name);
v8::Local<v8::Object> jsobj = V8JS_GLOBAL(isolate)->Get(v8_context, object_name_js).ToLocalChecked()->ToObject(v8_context).ToLocalChecked();
if (ZSTR_LEN(member) > std::numeric_limits<int>::max()) {
zend_throw_exception(php_ce_v8js_exception,
"Property name exceeds maximum supported length", 0);
return SINCE74(value,);
}
/* Write value to PHP JS object */
v8::Local<v8::Name> key = V8JS_SYML(ZSTR_VAL(member), static_cast<int>(ZSTR_LEN(member)));
jsobj->DefineOwnProperty(v8_context, key, zval_to_v8js(value, isolate), v8::ReadOnly);
}
#else
static SINCE74(zval*, void) v8js_write_property(zval *object, zval *member, zval *value, void **cache_slot) /* {{{ */
{
v8js_ctx *c = Z_V8JS_CTX_OBJ_P(object);
@ -1314,6 +1343,7 @@ static SINCE74(zval*, void) v8js_write_property(zval *object, zval *member, zval
/* Check whether member is public, if so, export to V8. */
zend_property_info *property_info = zend_get_property_info(c->std.ce, Z_STR_P(member), 1);
if(!property_info ||
(property_info != ZEND_WRONG_PROPERTY_INFO &&
(property_info->flags & ZEND_ACC_PUBLIC))) {
@ -1331,12 +1361,31 @@ static SINCE74(zval*, void) v8js_write_property(zval *object, zval *member, zval
v8::Local<v8::Name> key = V8JS_SYML(Z_STRVAL_P(member), static_cast<int>(Z_STRLEN_P(member)));
jsobj->DefineOwnProperty(v8_context, key, zval_to_v8js(value, isolate), v8::ReadOnly);
}
#endif
/* Write value to PHP object */
SINCE74(return,) std_object_handlers.write_property(object, member, value, NULL);
}
/* }}} */
#if PHP_VERSION_ID >= 80000
static void v8js_unset_property(zend_object *object, zend_string *member, void **cache_slot) /* {{{ */
{
V8JS_BEGIN_CTX_OBJ(c, object)
/* Global PHP JS object */
v8::Local<v8::String> object_name_js = v8::Local<v8::String>::New(isolate, c->object_name);
v8::Local<v8::Object> jsobj = V8JS_GLOBAL(isolate)->Get(v8_context, object_name_js).ToLocalChecked()->ToObject(v8_context).ToLocalChecked();
if (ZSTR_LEN(member) > std::numeric_limits<int>::max()) {
zend_throw_exception(php_ce_v8js_exception,
"Property name exceeds maximum supported length", 0);
return;
}
/* Delete value from PHP JS object */
v8::Local<v8::Value> key = V8JS_SYML(ZSTR_VAL(member), static_cast<int>(ZSTR_LEN(member)));
#else
static void v8js_unset_property(zval *object, zval *member, void **cache_slot) /* {{{ */
{
V8JS_BEGIN_CTX(c, object)
@ -1353,6 +1402,8 @@ static void v8js_unset_property(zval *object, zval *member, void **cache_slot) /
/* Delete value from PHP JS object */
v8::Local<v8::Value> key = V8JS_SYML(Z_STRVAL_P(member), static_cast<int>(Z_STRLEN_P(member)));
#endif
jsobj->Delete(v8_context, key);
/* Unset from PHP object */

View File

@ -84,8 +84,13 @@ static inline struct v8js_ctx *v8js_ctx_fetch_object(zend_object *obj) {
}
#define Z_V8JS_CTX_OBJ_P(zv) v8js_ctx_fetch_object(Z_OBJ_P(zv));
#define Z_V8JS_CTX_OBJ(zv) v8js_ctx_fetch_object(zv);
#if PHP_VERSION_ID >= 80000
#define ZEND_ACC_DTOR 0
#endif
PHP_MINIT_FUNCTION(v8js_class);
#endif /* V8JS_CLASS_H */

View File

@ -148,7 +148,11 @@ v8::Local<v8::Value> zval_to_v8js(zval *value, v8::Isolate *isolate) /* {{{ */
ce = php_date_get_date_ce();
if (instanceof_function(Z_OBJCE_P(value), ce)) {
zval dtval;
#if PHP_VERSION_ID >= 80000
zend_call_method_with_0_params(Z_OBJ_P(value), NULL, NULL, "getTimestamp", &dtval);
#else
zend_call_method_with_0_params(value, NULL, NULL, "getTimestamp", &dtval);
#endif
v8::Date::New(isolate->GetEnteredOrMicrotaskContext(), ((double)Z_LVAL(dtval) * 1000.0)).ToLocal(&jsValue);
zval_dtor(&dtval);
} else

View File

@ -50,8 +50,14 @@ void v8js_create_script_exception(zval *return_value, v8::Isolate *isolate, v8::
object_init_ex(return_value, php_ce_v8js_script_exception);
#if PHP_VERSION_ID >= 80000
#define PHPV8_EXPROP(type, name, value) \
zend_update_property##type(php_ce_v8js_script_exception, Z_OBJ_P(return_value), #name, sizeof(#name) - 1, value);
#else
#define PHPV8_EXPROP(type, name, value) \
zend_update_property##type(php_ce_v8js_script_exception, return_value, #name, sizeof(#name) - 1, value);
#endif
if (tc_message.IsEmpty()) {
spprintf(&message_string, 0, "%s", exception_string);
@ -128,7 +134,19 @@ void v8js_throw_script_exception(v8::Isolate *isolate, v8::TryCatch *try_catch)
}
}
/* }}} */
#if PHP_VERSION_ID >= 80000
#define V8JS_EXCEPTION_METHOD(property) \
static PHP_METHOD(V8JsScriptException, get##property) \
{ \
zval *value, rv; \
\
if (zend_parse_parameters_none() == FAILURE) { \
return; \
} \
value = zend_read_property(php_ce_v8js_script_exception, Z_OBJ_P(getThis()), #property, sizeof(#property) - 1, 0, &rv); \
RETURN_ZVAL(value, 1, 0); \
}
#else
#define V8JS_EXCEPTION_METHOD(property) \
static PHP_METHOD(V8JsScriptException, get##property) \
{ \
@ -140,6 +158,8 @@ void v8js_throw_script_exception(v8::Isolate *isolate, v8::TryCatch *try_catch)
value = zend_read_property(php_ce_v8js_script_exception, getThis(), #property, sizeof(#property) - 1, 0, &rv); \
RETURN_ZVAL(value, 1, 0); \
}
#endif
/* {{{ proto string V8JsEScriptxception::getJsFileName()
*/

View File

@ -311,8 +311,13 @@ V8JS_METHOD(require)
ZVAL_STRING(&params[0], module_base_cstr);
ZVAL_STRING(&params[1], module_id);
#if (PHP_MAJOR_VERSION < 8)
call_result = call_user_function_ex(EG(function_table), NULL, &c->module_normaliser,
&normaliser_result, 2, params, 0, NULL);
#else
call_result = call_user_function(EG(function_table), NULL, &c->module_normaliser,
&normaliser_result, 2, params);
#endif
}
isolate->Enter();
@ -435,7 +440,11 @@ V8JS_METHOD(require)
zend_try {
ZVAL_STRING(&params[0], normalised_module_id);
#if (PHP_MAJOR_VERSION < 8)
call_result = call_user_function_ex(EG(function_table), NULL, &c->module_loader, &module_code, 1, params, 0, NULL);
#else
call_result = call_user_function(EG(function_table), NULL, &c->module_loader, &module_code, 1, params);
#endif
}
zend_catch {
v8js_terminate_execution(isolate);

View File

@ -137,8 +137,11 @@ static void v8js_call_php_func(zend_object *object, zend_function *method_ptr, c
} else {
fci.params = NULL;
}
#if (PHP_MAJOR_VERSION < 8)
fci.no_separation = 1;
#else
fci.named_params = NULL;
#endif
info.GetReturnValue().Set(V8JS_NULL);
{
@ -640,8 +643,12 @@ v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::Name> property_n
zval php_value;
zend_object *object = reinterpret_cast<zend_object *>(self->GetAlignedPointerFromInternalField(1));
#if PHP_VERSION_ID >= 80000
zend_object &zobject = *object;
#else
zval zobject;
ZVAL_OBJ(&zobject, object);
#endif
v8js_function_tmpl_t *tmpl_ptr = reinterpret_cast<v8js_function_tmpl_t *>(self->GetAlignedPointerFromInternalField(0));
v8::Local<v8::FunctionTemplate> tmpl = v8::Local<v8::FunctionTemplate>::New(isolate, *tmpl_ptr);
@ -796,7 +803,11 @@ v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::Name> property_n
const zend_object_handlers *h = object->handlers;
if (callback_type == V8JS_PROP_QUERY) {
#if PHP_VERSION_ID >= 80000
if (h->has_property(&zobject, Z_STR_P(&zname), 0, NULL)) {
#else
if (h->has_property(&zobject, &zname, 0, NULL)) {
#endif
ret_value = V8JS_UINT(v8::None);
} else {
ret_value = v8::Local<v8::Value>(); // empty handle
@ -807,7 +818,11 @@ v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::Name> property_n
if(!property_info ||
(property_info != ZEND_WRONG_PROPERTY_INFO &&
property_info->flags & ZEND_ACC_PUBLIC)) {
#if PHP_VERSION_ID >= 80000
h->unset_property(&zobject, Z_STR_P(&zname), NULL);
#else
h->unset_property(&zobject, &zname, NULL);
#endif
ret_value = V8JS_TRUE();
}
else {

View File

@ -82,6 +82,11 @@ int v8js_get_properties_hash(v8::Local<v8::Value> jsValue, HashTable *retval, in
(ctx) = Z_V8JS_CTX_OBJ_P(object); \
V8JS_CTX_PROLOGUE(ctx);
#define V8JS_BEGIN_CTX_OBJ(ctx, object) \
v8js_ctx *(ctx); \
(ctx) = Z_V8JS_CTX_OBJ(object); \
V8JS_CTX_PROLOGUE(ctx);
#if PHP_VERSION_ID < 70400
#define SINCE74(x,y) y

View File

@ -21,7 +21,8 @@
#include "v8js_v8.h"
#include "v8js_v8object_class.h"
extern "C" {
extern "C"
{
#include "ext/date/php_date.h"
#include "ext/standard/php_string.h"
#include "zend_interfaces.h"
@ -43,9 +44,38 @@ static zend_object_handlers v8js_v8generator_handlers;
#define V8JS_V8_INVOKE_FUNC_NAME "V8Js::V8::Invoke"
/* V8 Object handlers */
#if PHP_VERSION_ID >= 80000
static int v8js_v8object_has_property(zend_object *object, zend_string *member, int has_set_exists, void **cache_slot) /* {{{ */
{
int retval = false;
v8js_v8object *obj = Z_V8JS_V8OBJECT_OBJ(object);
if (!obj->ctx)
{
zend_throw_exception(php_ce_v8js_exception,
"Can't access V8Object after V8Js instance is destroyed!", 0);
return false;
}
V8JS_CTX_PROLOGUE_EX(obj->ctx, false);
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
v8::Local<v8::Object> jsObj;
if (!v8obj->IsObject() || !v8obj->ToObject(v8_context).ToLocal(&jsObj))
{
return false;
}
if (ZSTR_LEN(member) > std::numeric_limits<int>::max())
{
zend_throw_exception(php_ce_v8js_exception,
"Member name length exceeds maximum supported length", 0);
return false;
}
v8::Local<v8::String> jsKey = V8JS_ZSYM(member);
#else
static int v8js_v8object_has_property(zval *object, zval *member, int has_set_exists, void **cache_slot) /* {{{ */
{
/* param has_set_exists:
@ -56,7 +86,8 @@ static int v8js_v8object_has_property(zval *object, zval *member, int has_set_ex
int retval = false;
v8js_v8object *obj = Z_V8JS_V8OBJECT_OBJ_P(object);
if (!obj->ctx) {
if (!obj->ctx)
{
zend_throw_exception(php_ce_v8js_exception,
"Can't access V8Object after V8Js instance is destroyed!", 0);
return false;
@ -66,25 +97,28 @@ static int v8js_v8object_has_property(zval *object, zval *member, int has_set_ex
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
v8::Local<v8::Object> jsObj;
if (Z_TYPE_P(member) != IS_STRING || !v8obj->IsObject() || !v8obj->ToObject(v8_context).ToLocal(&jsObj)) {
if (Z_TYPE_P(member) != IS_STRING || !v8obj->IsObject() || !v8obj->ToObject(v8_context).ToLocal(&jsObj))
{
return false;
}
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max()) {
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max())
{
zend_throw_exception(php_ce_v8js_exception,
"Member name length exceeds maximum supported length", 0);
return false;
}
v8::Local<v8::String> jsKey = V8JS_ZSYM(Z_STR_P(member));
#endif
/* Skip any prototype properties */
if (!jsObj->HasRealNamedProperty(v8_context, jsKey).FromMaybe(false)
&& !jsObj->HasRealNamedCallbackProperty(v8_context, jsKey).FromMaybe(false)) {
if (!jsObj->HasRealNamedProperty(v8_context, jsKey).FromMaybe(false) && !jsObj->HasRealNamedCallbackProperty(v8_context, jsKey).FromMaybe(false))
{
return false;
}
if (has_set_exists == 2) {
if (has_set_exists == 2)
{
/* property_exists(), that's enough! */
return true;
}
@ -92,7 +126,8 @@ static int v8js_v8object_has_property(zval *object, zval *member, int has_set_ex
/* We need to look at the value. */
v8::Local<v8::Value> jsVal = jsObj->Get(v8_context, jsKey).ToLocalChecked();
if (has_set_exists == 0 ) {
if (has_set_exists == 0)
{
/* isset(): We make 'undefined' equivalent to 'null' */
return !(jsVal->IsNull() || jsVal->IsUndefined());
}
@ -101,18 +136,20 @@ static int v8js_v8object_has_property(zval *object, zval *member, int has_set_ex
retval = jsVal->BooleanValue(isolate);
/* for PHP compatibility, [] should also be empty */
if (jsVal->IsArray() && retval) {
if (jsVal->IsArray() && retval)
{
v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(jsVal);
retval = (array->Length() != 0);
}
/* for PHP compatibility, '0' should also be empty */
v8::Local<v8::String> str;
if (jsVal->IsString() && retval && jsVal->ToString(v8_context).ToLocal(&str)
&& str->Length() == 1) {
if (jsVal->IsString() && retval && jsVal->ToString(v8_context).ToLocal(&str) && str->Length() == 1)
{
uint16_t c = 0;
str->Write(isolate, &c, 0, 1);
if (c == '0') {
if (c == '0')
{
retval = false;
}
}
@ -121,12 +158,41 @@ static int v8js_v8object_has_property(zval *object, zval *member, int has_set_ex
}
/* }}} */
#if PHP_VERSION_ID >= 80000
static zval *v8js_v8object_read_property(zend_object *object, zend_string *member, int type, void **cache_slot, zval *rv) /* {{{ */
{
zval *retval = rv;
v8js_v8object *obj = Z_V8JS_V8OBJECT_OBJ(object);
if (!obj->ctx)
{
zend_throw_exception(php_ce_v8js_exception,
"Can't access V8Object after V8Js instance is destroyed!", 0);
return retval;
}
V8JS_CTX_PROLOGUE_EX(obj->ctx, retval);
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
if (v8obj->IsObject())
{
if (ZSTR_LEN(member) > std::numeric_limits<int>::max())
{
zend_throw_exception(php_ce_v8js_exception,
"Member name length exceeds maximum supported length", 0);
return retval;
}
v8::Local<v8::String> jsKey = V8JS_ZSYM(member);
v8::Local<v8::Object> jsObj = v8obj->ToObject(v8_context).ToLocalChecked();
#else
static zval *v8js_v8object_read_property(zval *object, zval *member, int type, void **cache_slot, zval *rv) /* {{{ */
{
zval *retval = rv;
v8js_v8object *obj = Z_V8JS_V8OBJECT_OBJ_P(object);
if (!obj->ctx) {
if (!obj->ctx)
{
zend_throw_exception(php_ce_v8js_exception,
"Can't access V8Object after V8Js instance is destroyed!", 0);
return SINCE74(object, retval);
@ -137,7 +203,8 @@ static zval *v8js_v8object_read_property(zval *object, zval *member, int type, v
if (Z_TYPE_P(member) == IS_STRING && v8obj->IsObject())
{
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max()) {
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max())
{
zend_throw_exception(php_ce_v8js_exception,
"Member name length exceeds maximum supported length", 0);
return retval;
@ -145,13 +212,14 @@ static zval *v8js_v8object_read_property(zval *object, zval *member, int type, v
v8::Local<v8::String> jsKey = V8JS_ZSYM(Z_STR_P(member));
v8::Local<v8::Object> jsObj = v8obj->ToObject(v8_context).ToLocalChecked();
#endif
/* Skip any prototype properties */
if (jsObj->HasRealNamedProperty(v8_context, jsKey).FromMaybe(false)
|| jsObj->HasRealNamedCallbackProperty(v8_context, jsKey).FromMaybe(false)) {
if (jsObj->HasRealNamedProperty(v8_context, jsKey).FromMaybe(false) || jsObj->HasRealNamedCallbackProperty(v8_context, jsKey).FromMaybe(false))
{
v8::MaybeLocal<v8::Value> jsVal = jsObj->Get(v8_context, jsKey);
if (!jsVal.IsEmpty() && v8js_to_zval(jsVal.ToLocalChecked(), retval, obj->flags, isolate) == SUCCESS) {
if (!jsVal.IsEmpty() && v8js_to_zval(jsVal.ToLocalChecked(), retval, obj->flags, isolate) == SUCCESS)
{
return retval;
}
}
@ -161,17 +229,23 @@ static zval *v8js_v8object_read_property(zval *object, zval *member, int type, v
}
/* }}} */
#if PHP_VERSION_ID >= 80000
static zval *v8js_v8object_get_property_ptr_ptr(zend_object *object, zend_string *member, int type, void **cache_slot) /* {{{ */
#else
static zval *v8js_v8object_get_property_ptr_ptr(zval *object, zval *member, int type, void **cache_slot) /* {{{ */
#endif
{
return NULL;
}
/* }}} */
static SINCE74(zval*, void) v8js_v8object_write_property(zval *object, zval *member, zval *value, void **cache_slot ) /* {{{ */
#if PHP_VERSION_ID >= 80000
static SINCE74(zval *, void) v8js_v8object_write_property(zend_object *object, zend_string *member, zval *value, void **cache_slot) /* {{{ */
{
v8js_v8object *obj = Z_V8JS_V8OBJECT_OBJ_P(object);
v8js_v8object *obj = Z_V8JS_V8OBJECT_OBJ(object);
if (!obj->ctx) {
if (!obj->ctx)
{
zend_throw_exception(php_ce_v8js_exception,
"Can't access V8Object after V8Js instance is destroyed!", 0);
return SINCE74(value, );
@ -180,26 +254,57 @@ static SINCE74(zval*, void) v8js_v8object_write_property(zval *object, zval *mem
V8JS_CTX_PROLOGUE_EX(obj->ctx, SINCE74(value, ));
v8::Local<v8::Value> v8objHandle = v8::Local<v8::Value>::New(isolate, obj->v8obj);
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max()) {
if (ZSTR_LEN(member) > std::numeric_limits<int>::max())
{
zend_throw_exception(php_ce_v8js_exception,
"Member name length exceeds maximum supported length", 0);
return SINCE74(value, );
}
v8::Local<v8::Object> v8obj;
if (v8objHandle->IsObject() && v8objHandle->ToObject(v8_context).ToLocal(&v8obj)) {
v8obj->CreateDataProperty(v8_context, V8JS_ZSYM(Z_STR_P(member)), zval_to_v8js(value, isolate));
if (v8objHandle->IsObject() && v8objHandle->ToObject(v8_context).ToLocal(&v8obj))
{
v8obj->CreateDataProperty(v8_context, V8JS_ZSYM(member), zval_to_v8js(value, isolate));
}
#else
static SINCE74(zval *, void) v8js_v8object_write_property(zval *object, zval *member, zval *value, void **cache_slot) /* {{{ */
{
v8js_v8object *obj = Z_V8JS_V8OBJECT_OBJ_P(object);
if (!obj->ctx)
{
zend_throw_exception(php_ce_v8js_exception,
"Can't access V8Object after V8Js instance is destroyed!", 0);
return SINCE74(value, );
}
V8JS_CTX_PROLOGUE_EX(obj->ctx, SINCE74(value, ));
v8::Local<v8::Value> v8objHandle = v8::Local<v8::Value>::New(isolate, obj->v8obj);
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max())
{
zend_throw_exception(php_ce_v8js_exception,
"Member name length exceeds maximum supported length", 0);
return SINCE74(value, );
}
v8::Local<v8::Object> v8obj;
if (v8objHandle->IsObject() && v8objHandle->ToObject(v8_context).ToLocal(&v8obj))
{
v8obj->CreateDataProperty(v8_context, V8JS_ZSYM(Z_STR_P(member)), zval_to_v8js(value, isolate));
}
#endif
return SINCE74(value, );
}
/* }}} */
static void v8js_v8object_unset_property(zval *object, zval *member, void **cache_slot) /* {{{ */
#if PHP_VERSION_ID >= 80000
static void v8js_v8object_unset_property(zend_object *object, zend_string *member, void **cache_slot) /* {{{ */
{
v8js_v8object *obj = Z_V8JS_V8OBJECT_OBJ_P(object);
v8js_v8object *obj = Z_V8JS_V8OBJECT_OBJ(object);
if (!obj->ctx) {
if (!obj->ctx)
{
zend_throw_exception(php_ce_v8js_exception,
"Can't access V8Object after V8Js instance is destroyed!", 0);
return;
@ -208,26 +313,64 @@ static void v8js_v8object_unset_property(zval *object, zval *member, void **cach
V8JS_CTX_PROLOGUE(obj->ctx);
v8::Local<v8::Value> v8objHandle = v8::Local<v8::Value>::New(isolate, obj->v8obj);
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max()) {
if (ZSTR_LEN(member) > std::numeric_limits<int>::max())
{
zend_throw_exception(php_ce_v8js_exception,
"Member name length exceeds maximum supported length", 0);
return;
}
v8::Local<v8::Object> v8obj;
if (v8objHandle->IsObject() && v8objHandle->ToObject(v8_context).ToLocal(&v8obj)) {
v8obj->Delete(v8_context, V8JS_ZSYM(Z_STR_P(member)));
if (v8objHandle->IsObject() && v8objHandle->ToObject(v8_context).ToLocal(&v8obj))
{
v8obj->Delete(v8_context, V8JS_ZSYM(member));
}
}
/* }}} */
static HashTable *v8js_v8object_get_properties(zval *object) /* {{{ */
#else
static void v8js_v8object_unset_property(zval *object, zval *member, void **cache_slot) /* {{{ */
{
v8js_v8object *obj = Z_V8JS_V8OBJECT_OBJ_P(object);
if (obj->properties == NULL) {
if (!obj->ctx)
{
zend_throw_exception(php_ce_v8js_exception,
"Can't access V8Object after V8Js instance is destroyed!", 0);
return;
}
V8JS_CTX_PROLOGUE(obj->ctx);
v8::Local<v8::Value> v8objHandle = v8::Local<v8::Value>::New(isolate, obj->v8obj);
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max())
{
zend_throw_exception(php_ce_v8js_exception,
"Member name length exceeds maximum supported length", 0);
return;
}
v8::Local<v8::Object> v8obj;
if (v8objHandle->IsObject() && v8objHandle->ToObject(v8_context).ToLocal(&v8obj))
{
v8obj->Delete(v8_context, V8JS_ZSYM(Z_STR_P(member)));
}
}
#endif
/* }}} */
#if PHP_VERSION_ID >= 80000
static HashTable *v8js_v8object_get_properties(zend_object *object) /* {{{ */
{
v8js_v8object *obj = Z_V8JS_V8OBJECT_OBJ(object);
#else
static HashTable *v8js_v8object_get_properties(zval *object) /* {{{ */
{
v8js_v8object *obj = Z_V8JS_V8OBJECT_OBJ_P(object);
#endif
if (obj->properties == NULL)
{
#if PHP_VERSION_ID < 70300
if (GC_G(gc_active)) {
if (GC_G(gc_active))
{
/* the garbage collector is running, don't create more zvals */
return NULL;
}
@ -236,17 +379,21 @@ static HashTable *v8js_v8object_get_properties(zval *object) /* {{{ */
ALLOC_HASHTABLE(obj->properties);
zend_hash_init(obj->properties, 0, NULL, ZVAL_PTR_DTOR, 0);
if (!obj->ctx) {
if (!obj->ctx)
{
/* Half-constructed object, probably due to unserialize call.
* Just pass back properties hash so unserialize can write to
* it (instead of crashing the engine). */
return obj->properties;
}
} else if (!obj->properties->u.v.nIteratorsCount) {
}
else if (!obj->properties->u.v.nIteratorsCount)
{
zend_hash_clean(obj->properties);
}
if (!obj->ctx) {
if (!obj->ctx)
{
zend_throw_exception(php_ce_v8js_exception,
"Can't access V8Object after V8Js instance is destroyed!", 0);
return NULL;
@ -255,7 +402,8 @@ static HashTable *v8js_v8object_get_properties(zval *object) /* {{{ */
V8JS_CTX_PROLOGUE_EX(obj->ctx, NULL);
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
if (v8js_get_properties_hash(v8obj, obj->properties, obj->flags, isolate) == SUCCESS) {
if (v8js_get_properties_hash(v8obj, obj->properties, obj->flags, isolate) == SUCCESS)
{
return obj->properties;
}
@ -263,25 +411,154 @@ static HashTable *v8js_v8object_get_properties(zval *object) /* {{{ */
}
/* }}} */
#if PHP_VERSION_ID >= 80000
static HashTable *v8js_v8object_get_debug_info(zend_object *object, int *is_temp) /* {{{ */
#else
static HashTable *v8js_v8object_get_debug_info(zval *object, int *is_temp) /* {{{ */
#endif
{
*is_temp = 0;
return v8js_v8object_get_properties(object);
}
/* }}} */
static ZEND_FUNCTION(zend_v8object_func)
{
RETVAL_STR_COPY(EX(func)->common.function_name);
zval *argv = NULL;
int argc = ZEND_NUM_ARGS();
zend_string *method = EX(func)->common.function_name;
zend_object *object = Z_OBJ_P(getThis());
/* Cleanup trampoline */
ZEND_ASSERT(EX(func)->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE);
zend_string_release(EX(func)->common.function_name);
zend_free_trampoline(EX(func));
EX(func) = NULL;
v8js_v8object *obj = v8js_v8object_fetch_object(object);
if (!obj->ctx)
{
zend_throw_exception(php_ce_v8js_exception,
"Can't access V8Object after V8Js instance is destroyed!", 0);
return;
}
if (obj->v8obj.IsEmpty())
{
return;
}
if (ZSTR_LEN(method) > std::numeric_limits<int>::max())
{
zend_throw_exception(php_ce_v8js_exception,
"Method name length exceeds maximum supported length", 0);
return;
}
if (argc > 0)
{
argv = (zval *)safe_emalloc(sizeof(zval), argc, 0);
zend_get_parameters_array_ex(argc, argv);
}
/* std::function relies on its dtor to be executed, otherwise it leaks
* some memory on bailout. */
{
std::function<v8::MaybeLocal<v8::Value>(v8::Isolate *)> v8_call = [obj, method, argc, argv, object, &return_value](v8::Isolate *isolate)
{
int i = 0;
v8::Local<v8::Context> v8_context = isolate->GetEnteredOrMicrotaskContext();
v8::Local<v8::String> method_name = V8JS_SYML(ZSTR_VAL(method), static_cast<int>(ZSTR_LEN(method)));
v8::Local<v8::Object> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj)->ToObject(v8_context).ToLocalChecked();
v8::Local<v8::Object> thisObj;
v8::Local<v8::Function> cb;
if (method_name->Equals(v8_context, V8JS_SYM(V8JS_V8_INVOKE_FUNC_NAME)).FromMaybe(false))
{
cb = v8::Local<v8::Function>::Cast(v8obj);
}
else
{
v8::Local<v8::Value> slot;
if (!v8obj->Get(v8_context, method_name).ToLocal(&slot))
{
return v8::MaybeLocal<v8::Value>();
}
cb = v8::Local<v8::Function>::Cast(slot);
}
// If a method is invoked on V8Object, then set the object itself as
// "this" on JS side. Otherwise fall back to global object.
if (obj->std.ce == php_ce_v8object)
{
thisObj = v8obj;
}
else
{
thisObj = V8JS_GLOBAL(isolate);
}
v8::Local<v8::Value> *jsArgv = static_cast<v8::Local<v8::Value> *>(alloca(sizeof(v8::Local<v8::Value>) * argc));
for (i = 0; i < argc; i++)
{
new (&jsArgv[i]) v8::Local<v8::Value>;
jsArgv[i] = v8::Local<v8::Value>::New(isolate, zval_to_v8js(&argv[i], isolate));
}
v8::MaybeLocal<v8::Value> result = cb->Call(v8_context, thisObj, argc, jsArgv);
if (obj->std.ce == php_ce_v8object && !result.IsEmpty() && result.ToLocalChecked()->StrictEquals(thisObj))
{
/* JS code did "return this", retain object identity */
ZVAL_OBJ(return_value, object);
zval_copy_ctor(return_value);
result = v8::MaybeLocal<v8::Value>();
}
return result;
};
v8js_v8_call(obj->ctx, &return_value, obj->flags, obj->ctx->time_limit, obj->ctx->memory_limit, v8_call);
}
if (argc > 0)
{
efree(argv);
}
if (V8JSG(fatal_error_abort))
{
/* Check for fatal error marker possibly set by v8js_error_handler; just
* rethrow the error since we're now out of V8. */
zend_bailout();
}
}
static zend_function *v8js_v8object_get_method(zend_object **object_ptr, zend_string *method, const zval *key) /* {{{ */
{
v8js_v8object *obj = v8js_v8object_fetch_object(*object_ptr);
#if PHP_VERSION_ID < 80000
zend_function *f;
#else
zend_internal_function *f;
#endif
if (!obj->ctx) {
if (!obj->ctx)
{
zend_throw_exception(php_ce_v8js_exception,
"Can't access V8Object after V8Js instance is destroyed!", 0);
return NULL;
}
if (ZSTR_LEN(method) > std::numeric_limits<int>::max()) {
if (ZSTR_LEN(method) > std::numeric_limits<int>::max())
{
zend_throw_exception(php_ce_v8js_exception,
"Method name length exceeds maximum supported length", 0);
return NULL;
@ -291,18 +568,25 @@ static zend_function *v8js_v8object_get_method(zend_object **object_ptr, zend_st
v8::Local<v8::String> jsKey = V8JS_STRL(ZSTR_VAL(method), static_cast<int>(ZSTR_LEN(method)));
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
if (!obj->v8obj.IsEmpty() && v8obj->IsObject() && !v8obj->IsFunction()) {
if (!obj->v8obj.IsEmpty() && v8obj->IsObject() && !v8obj->IsFunction())
{
v8::Local<v8::Object> jsObj;
v8::Local<v8::Value> jsObjSlot;
if (v8obj->ToObject(v8_context).ToLocal(&jsObj)
&& jsObj->Has(v8_context, jsKey).FromMaybe(false)
&& jsObj->Get(v8_context, jsKey).ToLocal(&jsObjSlot)
&& jsObjSlot->IsFunction()) {
if (v8obj->ToObject(v8_context).ToLocal(&jsObj) && jsObj->Has(v8_context, jsKey).FromMaybe(false) && jsObj->Get(v8_context, jsKey).ToLocal(&jsObjSlot) && jsObjSlot->IsFunction())
{
#if PHP_VERSION_ID < 80000
f = (zend_function *)ecalloc(1, sizeof(*f));
f->type = ZEND_OVERLOADED_FUNCTION_TEMPORARY;
f->common.function_name = zend_string_copy(method);
return f;
#else
f = (zend_internal_function *)ecalloc(1, sizeof(*f));
f->type = ZEND_ACC_CALL_VIA_HANDLER;
f->handler = ZEND_FN(zend_v8object_func);
f->function_name = zend_string_copy(method);
return (zend_function *)f;
#endif
}
}
@ -317,23 +601,27 @@ static int v8js_v8object_call_method(zend_string *method, zend_object *object, I
v8js_v8object *obj = v8js_v8object_fetch_object(object);
if (!obj->ctx) {
if (!obj->ctx)
{
zend_throw_exception(php_ce_v8js_exception,
"Can't access V8Object after V8Js instance is destroyed!", 0);
return FAILURE;
}
if (obj->v8obj.IsEmpty()) {
if (obj->v8obj.IsEmpty())
{
return FAILURE;
}
if (ZSTR_LEN(method) > std::numeric_limits<int>::max()) {
if (ZSTR_LEN(method) > std::numeric_limits<int>::max())
{
zend_throw_exception(php_ce_v8js_exception,
"Method name length exceeds maximum supported length", 0);
return FAILURE;
}
if (argc > 0) {
if (argc > 0)
{
argv = (zval *)safe_emalloc(sizeof(zval), argc, 0);
zend_get_parameters_array_ex(argc, argv);
}
@ -341,7 +629,8 @@ static int v8js_v8object_call_method(zend_string *method, zend_object *object, I
/* std::function relies on its dtor to be executed, otherwise it leaks
* some memory on bailout. */
{
std::function< v8::MaybeLocal<v8::Value>(v8::Isolate *) > v8_call = [obj, method, argc, argv, object, &return_value](v8::Isolate *isolate) {
std::function<v8::MaybeLocal<v8::Value>(v8::Isolate *)> v8_call = [obj, method, argc, argv, object, &return_value](v8::Isolate *isolate)
{
int i = 0;
v8::Local<v8::Context> v8_context = isolate->GetEnteredOrMicrotaskContext();
@ -350,12 +639,16 @@ static int v8js_v8object_call_method(zend_string *method, zend_object *object, I
v8::Local<v8::Object> thisObj;
v8::Local<v8::Function> cb;
if (method_name->Equals(v8_context, V8JS_SYM(V8JS_V8_INVOKE_FUNC_NAME)).FromMaybe(false)) {
if (method_name->Equals(v8_context, V8JS_SYM(V8JS_V8_INVOKE_FUNC_NAME)).FromMaybe(false))
{
cb = v8::Local<v8::Function>::Cast(v8obj);
} else {
}
else
{
v8::Local<v8::Value> slot;
if (!v8obj->Get(v8_context, method_name).ToLocal(&slot)) {
if (!v8obj->Get(v8_context, method_name).ToLocal(&slot))
{
return v8::MaybeLocal<v8::Value>();
}
@ -364,23 +657,27 @@ static int v8js_v8object_call_method(zend_string *method, zend_object *object, I
// If a method is invoked on V8Object, then set the object itself as
// "this" on JS side. Otherwise fall back to global object.
if (obj->std.ce == php_ce_v8object) {
if (obj->std.ce == php_ce_v8object)
{
thisObj = v8obj;
}
else {
else
{
thisObj = V8JS_GLOBAL(isolate);
}
v8::Local<v8::Value> *jsArgv = static_cast<v8::Local<v8::Value> *>(alloca(sizeof(v8::Local<v8::Value>) * argc));
for (i = 0; i < argc; i++) {
for (i = 0; i < argc; i++)
{
new (&jsArgv[i]) v8::Local<v8::Value>;
jsArgv[i] = v8::Local<v8::Value>::New(isolate, zval_to_v8js(&argv[i], isolate));
}
v8::MaybeLocal<v8::Value> result = cb->Call(v8_context, thisObj, argc, jsArgv);
if (obj->std.ce == php_ce_v8object && !result.IsEmpty() && result.ToLocalChecked()->StrictEquals(thisObj)) {
if (obj->std.ce == php_ce_v8object && !result.IsEmpty() && result.ToLocalChecked()->StrictEquals(thisObj))
{
/* JS code did "return this", retain object identity */
ZVAL_OBJ(return_value, object);
zval_copy_ctor(return_value);
@ -393,11 +690,13 @@ static int v8js_v8object_call_method(zend_string *method, zend_object *object, I
v8js_v8_call(obj->ctx, &return_value, obj->flags, obj->ctx->time_limit, obj->ctx->memory_limit, v8_call);
}
if (argc > 0) {
if (argc > 0)
{
efree(argv);
}
if(V8JSG(fatal_error_abort)) {
if (V8JSG(fatal_error_abort))
{
/* Check for fatal error marker possibly set by v8js_error_handler; just
* rethrow the error since we're now out of V8. */
zend_bailout();
@ -407,12 +706,19 @@ static int v8js_v8object_call_method(zend_string *method, zend_object *object, I
}
/* }}} */
#if PHP_VERSION_ID >= 80000
static int v8js_v8object_get_closure(zend_object *object, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **zobj_ptr, bool call) /* {{{ */
{
zend_internal_function *invoke;
v8js_v8object *obj = Z_V8JS_V8OBJECT_OBJ(object);
#else
static int v8js_v8object_get_closure(zval *object, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **zobj_ptr) /* {{{ */
{
zend_function *invoke;
v8js_v8object *obj = Z_V8JS_V8OBJECT_OBJ_P(object);
if (!obj->ctx) {
#endif
if (!obj->ctx)
{
zend_throw_exception(php_ce_v8js_exception,
"Can't access V8Object after V8Js instance is destroyed!", 0);
return FAILURE;
@ -421,18 +727,31 @@ static int v8js_v8object_get_closure(zval *object, zend_class_entry **ce_ptr, ze
V8JS_CTX_PROLOGUE_EX(obj->ctx, FAILURE);
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
if (!v8obj->IsFunction()) {
if (!v8obj->IsFunction())
{
return FAILURE;
}
#if PHP_VERSION_ID < 80000
invoke = (zend_function *)ecalloc(1, sizeof(*invoke));
invoke->type = ZEND_OVERLOADED_FUNCTION_TEMPORARY;
invoke->common.function_name = zend_string_init(V8JS_V8_INVOKE_FUNC_NAME, sizeof(V8JS_V8_INVOKE_FUNC_NAME) - 1, 0);
*fptr_ptr = invoke;
#else
invoke = (zend_internal_function *)ecalloc(1, sizeof(*invoke));
invoke->type = ZEND_ACC_CALL_VIA_HANDLER;
invoke->handler = ZEND_FN(zend_v8object_func);
invoke->function_name = zend_string_init(V8JS_V8_INVOKE_FUNC_NAME, sizeof(V8JS_V8_INVOKE_FUNC_NAME) - 1, 0);
*fptr_ptr = (zend_function *)invoke;
#endif
if (zobj_ptr) {
if (zobj_ptr)
{
#if PHP_VERSION_ID >= 80000
*zobj_ptr = object;
#else
*zobj_ptr = Z_OBJ_P(object);
#endif
}
*ce_ptr = NULL;
@ -445,7 +764,8 @@ static void v8js_v8object_free_storage(zend_object *object) /* {{{ */
{
v8js_v8object *c = v8js_v8object_fetch_object(object);
if (c->properties) {
if (c->properties)
{
zend_hash_destroy(c->properties);
FREE_HASHTABLE(c->properties);
c->properties = NULL;
@ -453,7 +773,8 @@ static void v8js_v8object_free_storage(zend_object *object) /* {{{ */
zend_object_std_dtor(&c->std);
if(c->ctx) {
if (c->ctx)
{
c->v8obj.Reset();
c->ctx->v8js_v8objects.remove(c);
}
@ -538,7 +859,6 @@ PHP_METHOD(V8Function, __wakeup)
}
/* }}} */
static void v8js_v8generator_free_storage(zend_object *object) /* {{{ */
{
v8js_v8generator *c = v8js_v8generator_fetch_object(object);
@ -563,7 +883,8 @@ static zend_object *v8js_v8generator_new(zend_class_entry *ce) /* {{{ */
static void v8js_v8generator_next(v8js_v8generator *g) /* {{{ */
{
if (!g->v8obj.ctx) {
if (!g->v8obj.ctx)
{
zend_throw_exception(php_ce_v8js_exception,
"Can't access V8Generator after V8Js instance is destroyed!", 0);
return;
@ -572,26 +893,29 @@ static void v8js_v8generator_next(v8js_v8generator *g) /* {{{ */
/* std::function relies on its dtor to be executed, otherwise it leaks
* some memory on bailout. */
{
std::function< v8::MaybeLocal<v8::Value>(v8::Isolate *) > v8_call = [g](v8::Isolate *isolate) {
std::function<v8::MaybeLocal<v8::Value>(v8::Isolate *)> v8_call = [g](v8::Isolate *isolate)
{
v8::Local<v8::Context> v8_context = isolate->GetEnteredOrMicrotaskContext();
v8::Local<v8::String> method_name = V8JS_SYM("next");
v8::Local<v8::Object> v8obj = v8::Local<v8::Value>::New(isolate, g->v8obj.v8obj)->ToObject(v8_context).ToLocalChecked();
v8::Local<v8::Function> cb = v8::Local<v8::Function>::Cast(v8obj->Get(v8_context, method_name).ToLocalChecked());;
v8::Local<v8::Function> cb = v8::Local<v8::Function>::Cast(v8obj->Get(v8_context, method_name).ToLocalChecked());
;
v8::MaybeLocal<v8::Value> result = cb->Call(v8_context, v8obj, 0, NULL);
if(result.IsEmpty()) {
if (result.IsEmpty())
{
/* cb->Call probably threw (and already threw a zend exception), just return */
return V8JS_NULL;
}
if(!result.ToLocalChecked()->IsObject()) {
if (!result.ToLocalChecked()->IsObject())
{
zend_throw_exception(php_ce_v8js_exception,
"V8Generator returned non-object on next()", 0);
return V8JS_NULL;
}
v8::Local<v8::Object> resultObj = result.ToLocalChecked()->ToObject(v8_context).ToLocalChecked();
v8::Local<v8::Value> val = resultObj->Get(v8_context, V8JS_SYM("value")).ToLocalChecked();
v8::Local<v8::Value> done = resultObj->Get(v8_context, V8JS_SYM("done")).ToLocalChecked();
@ -607,7 +931,8 @@ static void v8js_v8generator_next(v8js_v8generator *g) /* {{{ */
v8js_v8_call(g->v8obj.ctx, NULL, g->v8obj.flags, g->v8obj.ctx->time_limit, g->v8obj.ctx->memory_limit, v8_call);
}
if(V8JSG(fatal_error_abort)) {
if (V8JSG(fatal_error_abort))
{
/* Check for fatal error marker possibly set by v8js_error_handler; just
* rethrow the error since we're now out of V8. */
zend_bailout();
@ -619,7 +944,8 @@ static zend_function *v8js_v8generator_get_method(zend_object **object_ptr, zend
{
zend_function *result = std_object_handlers.get_method(object_ptr, method, key);
if(!result) {
if (!result)
{
result = v8js_v8object_get_method(object_ptr, method, key);
}
@ -663,7 +989,8 @@ PHP_METHOD(V8Generator, current)
{
v8js_v8generator *g = Z_V8JS_V8GENERATOR_OBJ_P(getThis());
if(!g->primed) {
if (!g->primed)
{
v8js_v8generator_next(g);
}
@ -694,10 +1021,10 @@ PHP_METHOD(V8Generator, rewind)
{
v8js_v8generator *g = Z_V8JS_V8GENERATOR_OBJ_P(getThis());
if(g->primed) {
if (g->primed)
{
zend_throw_exception(php_ce_v8js_exception,
"V8Generator::rewind not supported by ES6", 0);
}
RETURN_FALSE;
@ -710,7 +1037,8 @@ PHP_METHOD(V8Generator, valid)
{
v8js_v8generator *g = Z_V8JS_V8GENERATOR_OBJ_P(getThis());
if(!g->primed) {
if (!g->primed)
{
v8js_v8generator_next(g);
}
@ -718,18 +1046,20 @@ PHP_METHOD(V8Generator, valid)
}
/* }}} */
void v8js_v8object_create(zval *res, v8::Local<v8::Value> value, int flags, v8::Isolate *isolate) /* {{{ */
{
v8js_ctx *ctx = (v8js_ctx *)isolate->GetData(0);
if(value->IsGeneratorObject()) {
if (value->IsGeneratorObject())
{
object_init_ex(res, php_ce_v8generator);
}
else if(value->IsFunction()) {
else if (value->IsFunction())
{
object_init_ex(res, php_ce_v8function);
}
else {
else
{
object_init_ex(res, php_ce_v8object);
}
@ -743,23 +1073,45 @@ void v8js_v8object_create(zval *res, v8::Local<v8::Value> value, int flags, v8::
}
/* }}} */
ZEND_BEGIN_ARG_INFO(arginfo_v8object_construct, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_v8object_sleep, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_v8object_wakeup, 0)
ZEND_END_ARG_INFO()
static const zend_function_entry v8js_v8object_methods[] = {/* {{{ */
PHP_ME(V8Object, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
PHP_ME(V8Object, __sleep, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(V8Object, __wakeup, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
{NULL, NULL, NULL}
};
PHP_ME(V8Object, __construct, arginfo_v8object_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_ME(V8Object, __sleep, arginfo_v8object_sleep, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(V8Object, __wakeup, arginfo_v8object_wakeup, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL){NULL, NULL, NULL}};
/* }}} */
ZEND_BEGIN_ARG_INFO(arginfo_v8function_construct, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_v8function_sleep, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_v8function_wakeup, 0)
ZEND_END_ARG_INFO()
static const zend_function_entry v8js_v8function_methods[] = {/* {{{ */
PHP_ME(V8Function, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
PHP_ME(V8Function, __sleep, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(V8Function, __wakeup, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
{NULL, NULL, NULL}
};
PHP_ME(V8Function, __construct, arginfo_v8function_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_ME(V8Function, __sleep, arginfo_v8function_sleep, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(V8Function, __wakeup, arginfo_v8function_wakeup, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL){NULL, NULL, NULL}};
/* }}} */
ZEND_BEGIN_ARG_INFO(arginfo_v8generator_construct, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_v8generator_sleep, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_v8generator_wakeup, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_v8generator_current, 0)
ZEND_END_ARG_INFO()
@ -776,9 +1128,9 @@ ZEND_BEGIN_ARG_INFO(arginfo_v8generator_valid, 0)
ZEND_END_ARG_INFO()
static const zend_function_entry v8js_v8generator_methods[] = {/* {{{ */
PHP_ME(V8Generator, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
PHP_ME(V8Generator, __sleep, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(V8Generator, __wakeup, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(V8Generator, __construct, arginfo_v8generator_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_ME(V8Generator, __sleep, arginfo_v8generator_sleep, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(V8Generator, __wakeup, arginfo_v8generator_wakeup, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(V8Generator, current, arginfo_v8generator_current, ZEND_ACC_PUBLIC)
PHP_ME(V8Generator, key, arginfo_v8generator_key, ZEND_ACC_PUBLIC)
@ -786,11 +1138,9 @@ static const zend_function_entry v8js_v8generator_methods[] = { /* {{{ */
PHP_ME(V8Generator, rewind, arginfo_v8generator_rewind, ZEND_ACC_PUBLIC)
PHP_ME(V8Generator, valid, arginfo_v8generator_valid, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
{NULL, NULL, NULL}};
/* }}} */
PHP_MINIT_FUNCTION(v8js_v8object_class) /* {{{ */
{
zend_class_entry ce;
@ -815,7 +1165,6 @@ PHP_MINIT_FUNCTION(v8js_v8object_class) /* {{{ */
zend_class_implements(php_ce_v8generator, 1, zend_ce_iterator);
/* V8<Object|Function> handlers */
memcpy(&v8js_v8object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
v8js_v8object_handlers.clone_obj = NULL;
@ -827,7 +1176,9 @@ PHP_MINIT_FUNCTION(v8js_v8object_class) /* {{{ */
v8js_v8object_handlers.unset_property = v8js_v8object_unset_property;
v8js_v8object_handlers.get_properties = v8js_v8object_get_properties;
v8js_v8object_handlers.get_method = v8js_v8object_get_method;
#if PHP_VERSION_ID < 80000
v8js_v8object_handlers.call_method = v8js_v8object_call_method;
#endif
v8js_v8object_handlers.get_debug_info = v8js_v8object_get_debug_info;
v8js_v8object_handlers.get_closure = v8js_v8object_get_closure;
v8js_v8object_handlers.offset = XtOffsetOf(struct v8js_v8object, std);
@ -842,7 +1193,6 @@ PHP_MINIT_FUNCTION(v8js_v8object_class) /* {{{ */
return SUCCESS;
} /* }}} */
/*
* Local variables:
* tab-width: 4

View File

@ -35,7 +35,7 @@ static inline v8js_v8object *v8js_v8object_fetch_object(zend_object *obj) {
}
#define Z_V8JS_V8OBJECT_OBJ_P(zv) v8js_v8object_fetch_object(Z_OBJ_P(zv));
#define Z_V8JS_V8OBJECT_OBJ(zv) v8js_v8object_fetch_object(zv);
/* {{{ Generator container */
struct v8js_v8generator {