remove proxy and many exotic methods
This commit is contained in:
161
source/quickjs.c
161
source/quickjs.c
@@ -1197,7 +1197,7 @@ JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque)
|
|||||||
countof(js_std_class_def)) < 0)
|
countof(js_std_class_def)) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
rt->class_array[JS_CLASS_STRING].exotic = &js_string_exotic_methods;
|
rt->class_array[JS_CLASS_STRING].exotic = &js_string_exotic_methods;
|
||||||
|
|
||||||
rt->class_array[JS_CLASS_C_FUNCTION].call = js_call_c_function;
|
rt->class_array[JS_CLASS_C_FUNCTION].call = js_call_c_function;
|
||||||
rt->class_array[JS_CLASS_C_FUNCTION_DATA].call = js_c_function_data_call;
|
rt->class_array[JS_CLASS_C_FUNCTION_DATA].call = js_c_function_data_call;
|
||||||
rt->class_array[JS_CLASS_BOUND_FUNCTION].call = js_call_bound_function;
|
rt->class_array[JS_CLASS_BOUND_FUNCTION].call = js_call_bound_function;
|
||||||
@@ -6323,22 +6323,16 @@ static void JS_SetImmutablePrototype(JSContext *ctx, JSValueConst obj)
|
|||||||
p->has_immutable_prototype = TRUE;
|
p->has_immutable_prototype = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return -1 (exception) or TRUE/FALSE. 'throw_flag' = FALSE indicates
|
/* Return -1 (exception) or TRUE. */
|
||||||
that it is called from Reflect.setPrototypeOf(). */
|
|
||||||
static int JS_SetPrototypeInternal(JSContext *ctx, JSValueConst obj,
|
static int JS_SetPrototypeInternal(JSContext *ctx, JSValueConst obj,
|
||||||
JSValueConst proto_val,
|
JSValueConst proto_val)
|
||||||
BOOL throw_flag)
|
|
||||||
{
|
{
|
||||||
JSObject *proto, *p, *p1;
|
JSObject *proto, *p, *p1;
|
||||||
JSShape *sh;
|
JSShape *sh;
|
||||||
|
|
||||||
if (throw_flag) {
|
if (JS_VALUE_GET_TAG(obj) == JS_TAG_NULL)
|
||||||
if (JS_VALUE_GET_TAG(obj) == JS_TAG_NULL)
|
goto not_obj;
|
||||||
goto not_obj;
|
|
||||||
} else {
|
|
||||||
if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)
|
|
||||||
goto not_obj;
|
|
||||||
}
|
|
||||||
p = JS_VALUE_GET_OBJ(obj);
|
p = JS_VALUE_GET_OBJ(obj);
|
||||||
if (JS_VALUE_GET_TAG(proto_val) != JS_TAG_OBJECT) {
|
if (JS_VALUE_GET_TAG(proto_val) != JS_TAG_OBJECT) {
|
||||||
if (JS_VALUE_GET_TAG(proto_val) != JS_TAG_NULL) {
|
if (JS_VALUE_GET_TAG(proto_val) != JS_TAG_NULL) {
|
||||||
@@ -6347,57 +6341,30 @@ static int JS_SetPrototypeInternal(JSContext *ctx, JSValueConst obj,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
proto = NULL;
|
proto = NULL;
|
||||||
} else {
|
} else
|
||||||
proto = JS_VALUE_GET_OBJ(proto_val);
|
proto = JS_VALUE_GET_OBJ(proto_val);
|
||||||
}
|
|
||||||
|
|
||||||
if (throw_flag && JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)
|
if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (unlikely(p->is_exotic)) {
|
|
||||||
const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic;
|
|
||||||
int ret;
|
|
||||||
if (em && em->set_prototype) {
|
|
||||||
ret = em->set_prototype(ctx, obj, proto_val);
|
|
||||||
if (ret == 0 && throw_flag) {
|
|
||||||
JS_ThrowTypeError(ctx, "proxy: bad prototype");
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sh = p->shape;
|
sh = p->shape;
|
||||||
if (sh->proto == proto)
|
if (sh->proto == proto)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (unlikely(p->has_immutable_prototype)) {
|
if (unlikely(p->has_immutable_prototype)) {
|
||||||
if (throw_flag) {
|
JS_ThrowTypeError(ctx, "prototype is immutable");
|
||||||
JS_ThrowTypeError(ctx, "prototype is immutable");
|
return -1;
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (unlikely(!p->extensible)) {
|
if (unlikely(!p->extensible)) {
|
||||||
if (throw_flag) {
|
JS_ThrowTypeError(ctx, "object is not extensible");
|
||||||
JS_ThrowTypeError(ctx, "object is not extensible");
|
return -1;
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (proto) {
|
if (proto) {
|
||||||
/* check if there is a cycle */
|
/* check if there is a cycle */
|
||||||
p1 = proto;
|
p1 = proto;
|
||||||
do {
|
do {
|
||||||
if (p1 == p) {
|
if (p1 == p) {
|
||||||
if (throw_flag) {
|
JS_ThrowTypeError(ctx, "circular prototype chain");
|
||||||
JS_ThrowTypeError(ctx, "circular prototype chain");
|
return -1;
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* Note: for Proxy objects, proto is NULL */
|
/* Note: for Proxy objects, proto is NULL */
|
||||||
p1 = p1->shape->proto;
|
p1 = p1->shape->proto;
|
||||||
@@ -6417,7 +6384,7 @@ static int JS_SetPrototypeInternal(JSContext *ctx, JSValueConst obj,
|
|||||||
/* return -1 (exception) or TRUE/FALSE */
|
/* return -1 (exception) or TRUE/FALSE */
|
||||||
int JS_SetPrototype(JSContext *ctx, JSValueConst obj, JSValueConst proto_val)
|
int JS_SetPrototype(JSContext *ctx, JSValueConst obj, JSValueConst proto_val)
|
||||||
{
|
{
|
||||||
return JS_SetPrototypeInternal(ctx, obj, proto_val, TRUE);
|
return JS_SetPrototypeInternal(ctx, obj, proto_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only works for primitive types, otherwise return JS_NULL. */
|
/* Only works for primitive types, otherwise return JS_NULL. */
|
||||||
@@ -6454,12 +6421,6 @@ JSValue JS_GetPrototype(JSContext *ctx, JSValueConst obj)
|
|||||||
if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) {
|
if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) {
|
||||||
JSObject *p;
|
JSObject *p;
|
||||||
p = JS_VALUE_GET_OBJ(obj);
|
p = JS_VALUE_GET_OBJ(obj);
|
||||||
if (unlikely(p->is_exotic)) {
|
|
||||||
const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic;
|
|
||||||
if (em && em->get_prototype) {
|
|
||||||
return em->get_prototype(ctx, obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p = p->shape->proto;
|
p = p->shape->proto;
|
||||||
if (!p)
|
if (!p)
|
||||||
val = JS_NULL;
|
val = JS_NULL;
|
||||||
@@ -6709,16 +6670,6 @@ JSValue JS_GetPropertyInternal(JSContext *ctx, JSValueConst obj,
|
|||||||
} else {
|
} else {
|
||||||
const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic;
|
const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic;
|
||||||
if (em) {
|
if (em) {
|
||||||
if (em->get_property) {
|
|
||||||
JSValue obj1, retval;
|
|
||||||
/* XXX: should pass throw_ref_error */
|
|
||||||
/* Note: if 'p' is a prototype, it can be
|
|
||||||
freed in the called function */
|
|
||||||
obj1 = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p));
|
|
||||||
retval = em->get_property(ctx, obj1, prop, this_obj);
|
|
||||||
JS_FreeValue(ctx, obj1);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
if (em->get_own_property) {
|
if (em->get_own_property) {
|
||||||
JSPropertyDescriptor desc;
|
JSPropertyDescriptor desc;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -6865,40 +6816,7 @@ static int __exception JS_GetOwnPropertyNamesInternal(JSContext *ctx,
|
|||||||
if (flags & JS_GPN_STRING_MASK) {
|
if (flags & JS_GPN_STRING_MASK) {
|
||||||
num_keys_count += js_string_obj_get_length(ctx, JS_MKPTR(JS_TAG_OBJECT, p));
|
num_keys_count += js_string_obj_get_length(ctx, JS_MKPTR(JS_TAG_OBJECT, p));
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic;
|
|
||||||
if (em && em->get_own_property_names) {
|
|
||||||
if (em->get_own_property_names(ctx, &tab_exotic, &exotic_count,
|
|
||||||
JS_MKPTR(JS_TAG_OBJECT, p)))
|
|
||||||
return -1;
|
|
||||||
for(i = 0; i < exotic_count; i++) {
|
|
||||||
atom = tab_exotic[i].atom;
|
|
||||||
kind = JS_AtomGetKind(ctx, atom);
|
|
||||||
if (((flags >> kind) & 1) != 0) {
|
|
||||||
is_enumerable = FALSE;
|
|
||||||
if (flags & (JS_GPN_SET_ENUM | JS_GPN_ENUM_ONLY)) {
|
|
||||||
JSPropertyDescriptor desc;
|
|
||||||
int res;
|
|
||||||
/* set the "is_enumerable" field if necessary */
|
|
||||||
res = JS_GetOwnPropertyInternal(ctx, &desc, p, atom);
|
|
||||||
if (res < 0) {
|
|
||||||
JS_FreePropertyEnum(ctx, tab_exotic, exotic_count);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (res) {
|
|
||||||
is_enumerable =
|
|
||||||
((desc.flags & JS_PROP_ENUMERABLE) != 0);
|
|
||||||
js_free_desc(ctx, &desc);
|
|
||||||
}
|
|
||||||
tab_exotic[i].is_enumerable = is_enumerable;
|
|
||||||
}
|
|
||||||
if (!(flags & JS_GPN_ENUM_ONLY) || is_enumerable) {
|
|
||||||
exotic_keys_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fill them */
|
/* fill them */
|
||||||
@@ -7115,12 +7033,6 @@ int JS_IsExtensible(JSContext *ctx, JSValueConst obj)
|
|||||||
if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT))
|
if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
p = JS_VALUE_GET_OBJ(obj);
|
p = JS_VALUE_GET_OBJ(obj);
|
||||||
if (unlikely(p->is_exotic)) {
|
|
||||||
const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic;
|
|
||||||
if (em && em->is_extensible) {
|
|
||||||
return em->is_extensible(ctx, obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return p->extensible;
|
return p->extensible;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7132,12 +7044,6 @@ int JS_PreventExtensions(JSContext *ctx, JSValueConst obj)
|
|||||||
if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT))
|
if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
p = JS_VALUE_GET_OBJ(obj);
|
p = JS_VALUE_GET_OBJ(obj);
|
||||||
if (unlikely(p->is_exotic)) {
|
|
||||||
const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic;
|
|
||||||
if (em && em->prevent_extensions) {
|
|
||||||
return em->prevent_extensions(ctx, obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p->extensible = FALSE;
|
p->extensible = FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -7153,16 +7059,6 @@ int JS_HasProperty(JSContext *ctx, JSValueConst obj, JSAtom prop)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
p = JS_VALUE_GET_OBJ(obj);
|
p = JS_VALUE_GET_OBJ(obj);
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (p->is_exotic) {
|
|
||||||
const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic;
|
|
||||||
if (em && em->has_property) {
|
|
||||||
/* has_property can free the prototype */
|
|
||||||
obj1 = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p));
|
|
||||||
ret = em->has_property(ctx, obj1, prop);
|
|
||||||
JS_FreeValue(ctx, obj1);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* JS_GetOwnPropertyInternal can free the prototype */
|
/* JS_GetOwnPropertyInternal can free the prototype */
|
||||||
JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p));
|
JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p));
|
||||||
ret = JS_GetOwnPropertyInternal(ctx, NULL, p, prop);
|
ret = JS_GetOwnPropertyInternal(ctx, NULL, p, prop);
|
||||||
@@ -7768,15 +7664,6 @@ int JS_SetPropertyInternal(JSContext *ctx, JSValueConst obj,
|
|||||||
const JSClassExoticMethods *em = ctx->rt->class_array[p1->class_id].exotic;
|
const JSClassExoticMethods *em = ctx->rt->class_array[p1->class_id].exotic;
|
||||||
if (em) {
|
if (em) {
|
||||||
JSValue obj1;
|
JSValue obj1;
|
||||||
if (em->set_property) {
|
|
||||||
/* set_property can free the prototype */
|
|
||||||
obj1 = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p1));
|
|
||||||
ret = em->set_property(ctx, obj1, prop,
|
|
||||||
val, this_obj, flags);
|
|
||||||
JS_FreeValue(ctx, obj1);
|
|
||||||
JS_FreeValue(ctx, val);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if (em->get_own_property) {
|
if (em->get_own_property) {
|
||||||
/* get_own_property can free the prototype */
|
/* get_own_property can free the prototype */
|
||||||
obj1 = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p1));
|
obj1 = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p1));
|
||||||
@@ -12003,14 +11890,6 @@ static __exception int JS_CopyDataProperties(JSContext *ctx,
|
|||||||
p = JS_VALUE_GET_OBJ(source);
|
p = JS_VALUE_GET_OBJ(source);
|
||||||
|
|
||||||
gpn_flags = JS_GPN_STRING_MASK | JS_GPN_SYMBOL_MASK | JS_GPN_ENUM_ONLY;
|
gpn_flags = JS_GPN_STRING_MASK | JS_GPN_SYMBOL_MASK | JS_GPN_ENUM_ONLY;
|
||||||
if (p->is_exotic) {
|
|
||||||
const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic;
|
|
||||||
/* cannot use JS_GPN_ENUM_ONLY with e.g. proxies because it
|
|
||||||
introduces a visible change */
|
|
||||||
if (em && em->get_own_property_names) {
|
|
||||||
gpn_flags &= ~JS_GPN_ENUM_ONLY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (JS_GetOwnPropertyNamesInternal(ctx, &tab_atom, &tab_atom_count, p,
|
if (JS_GetOwnPropertyNamesInternal(ctx, &tab_atom, &tab_atom_count, p,
|
||||||
gpn_flags))
|
gpn_flags))
|
||||||
return -1;
|
return -1;
|
||||||
@@ -13836,7 +13715,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
|
|||||||
sf->cur_pc = pc;
|
sf->cur_pc = pc;
|
||||||
proto = sp[-1];
|
proto = sp[-1];
|
||||||
if (JS_IsObject(proto) || JS_IsNull(proto)) {
|
if (JS_IsObject(proto) || JS_IsNull(proto)) {
|
||||||
if (JS_SetPrototypeInternal(ctx, sp[-2], proto, TRUE) < 0)
|
if (JS_SetPrototypeInternal(ctx, sp[-2], proto) < 0)
|
||||||
goto exception;
|
goto exception;
|
||||||
}
|
}
|
||||||
JS_FreeValue(ctx, proto);
|
JS_FreeValue(ctx, proto);
|
||||||
@@ -27715,7 +27594,7 @@ static JSValue js_object_setPrototypeOf(JSContext *ctx, JSValueConst this_val,
|
|||||||
{
|
{
|
||||||
JSValueConst obj;
|
JSValueConst obj;
|
||||||
obj = argv[0];
|
obj = argv[0];
|
||||||
if (JS_SetPrototypeInternal(ctx, obj, argv[1], TRUE) < 0)
|
if (JS_SetPrototypeInternal(ctx, obj, argv[1]) < 0)
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
return JS_DupValue(ctx, obj);
|
return JS_DupValue(ctx, obj);
|
||||||
}
|
}
|
||||||
@@ -28449,7 +28328,7 @@ static JSValue js_object_set___proto__(JSContext *ctx, JSValueConst this_val,
|
|||||||
return JS_ThrowTypeErrorNotAnObject(ctx);
|
return JS_ThrowTypeErrorNotAnObject(ctx);
|
||||||
if (!JS_IsObject(proto) && !JS_IsNull(proto))
|
if (!JS_IsObject(proto) && !JS_IsNull(proto))
|
||||||
return JS_NULL;
|
return JS_NULL;
|
||||||
if (JS_SetPrototypeInternal(ctx, this_val, proto, TRUE) < 0)
|
if (JS_SetPrototypeInternal(ctx, this_val, proto) < 0)
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
else
|
else
|
||||||
return JS_NULL;
|
return JS_NULL;
|
||||||
@@ -28668,7 +28547,7 @@ static JSValue js_function_constructor(JSContext *ctx, JSValueConst new_target,
|
|||||||
goto fail1;
|
goto fail1;
|
||||||
proto = JS_DupValue(ctx, realm->class_proto[JS_CLASS_BYTECODE_FUNCTION]);
|
proto = JS_DupValue(ctx, realm->class_proto[JS_CLASS_BYTECODE_FUNCTION]);
|
||||||
}
|
}
|
||||||
ret = JS_SetPrototypeInternal(ctx, obj, proto, TRUE);
|
ret = JS_SetPrototypeInternal(ctx, obj, proto);
|
||||||
JS_FreeValue(ctx, proto);
|
JS_FreeValue(ctx, proto);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail1;
|
goto fail1;
|
||||||
|
|||||||
@@ -455,12 +455,7 @@ typedef struct JSClassExoticMethods {
|
|||||||
returned, the property descriptor 'desc' is filled if != NULL. */
|
returned, the property descriptor 'desc' is filled if != NULL. */
|
||||||
int (*get_own_property)(JSContext *ctx, JSPropertyDescriptor *desc,
|
int (*get_own_property)(JSContext *ctx, JSPropertyDescriptor *desc,
|
||||||
JSValueConst obj, JSAtom prop);
|
JSValueConst obj, JSAtom prop);
|
||||||
/* '*ptab' should hold the '*plen' property keys. Return 0 if OK,
|
|
||||||
-1 if exception. The 'is_enumerable' field is ignored.
|
|
||||||
*/
|
|
||||||
int (*get_own_property_names)(JSContext *ctx, JSPropertyEnum **ptab,
|
|
||||||
uint32_t *plen,
|
|
||||||
JSValueConst obj);
|
|
||||||
/* return < 0 if exception, or TRUE/FALSE */
|
/* return < 0 if exception, or TRUE/FALSE */
|
||||||
int (*delete_property)(JSContext *ctx, JSValueConst obj, JSAtom prop);
|
int (*delete_property)(JSContext *ctx, JSValueConst obj, JSAtom prop);
|
||||||
/* return < 0 if exception or TRUE/FALSE */
|
/* return < 0 if exception or TRUE/FALSE */
|
||||||
@@ -468,26 +463,6 @@ typedef struct JSClassExoticMethods {
|
|||||||
JSAtom prop, JSValueConst val,
|
JSAtom prop, JSValueConst val,
|
||||||
JSValueConst getter, JSValueConst setter,
|
JSValueConst getter, JSValueConst setter,
|
||||||
int flags);
|
int flags);
|
||||||
/* The following methods can be emulated with the previous ones,
|
|
||||||
so they are usually not needed */
|
|
||||||
/* return < 0 if exception or TRUE/FALSE */
|
|
||||||
int (*has_property)(JSContext *ctx, JSValueConst obj, JSAtom atom);
|
|
||||||
JSValue (*get_property)(JSContext *ctx, JSValueConst obj, JSAtom atom,
|
|
||||||
JSValueConst receiver);
|
|
||||||
/* return < 0 if exception or TRUE/FALSE */
|
|
||||||
int (*set_property)(JSContext *ctx, JSValueConst obj, JSAtom atom,
|
|
||||||
JSValueConst value, JSValueConst receiver, int flags);
|
|
||||||
|
|
||||||
/* To get a consistent object behavior when get_prototype != NULL,
|
|
||||||
get_property, set_property and set_prototype must be != NULL
|
|
||||||
and the object must be created with a JS_NULL prototype. */
|
|
||||||
JSValue (*get_prototype)(JSContext *ctx, JSValueConst obj);
|
|
||||||
/* return < 0 if exception or TRUE/FALSE */
|
|
||||||
int (*set_prototype)(JSContext *ctx, JSValueConst obj, JSValueConst proto_val);
|
|
||||||
/* return < 0 if exception or TRUE/FALSE */
|
|
||||||
int (*is_extensible)(JSContext *ctx, JSValueConst obj);
|
|
||||||
/* return < 0 if exception or TRUE/FALSE */
|
|
||||||
int (*prevent_extensions)(JSContext *ctx, JSValueConst obj);
|
|
||||||
} JSClassExoticMethods;
|
} JSClassExoticMethods;
|
||||||
|
|
||||||
typedef void JSClassFinalizer(JSRuntime *rt, JSValue val);
|
typedef void JSClassFinalizer(JSRuntime *rt, JSValue val);
|
||||||
|
|||||||
Reference in New Issue
Block a user