Skip to content

Commit 97be5a3

Browse files
authoredMay 9, 2024
Add js_resolve_proxy (bellard#293)
- simplify `JS_IsArray` for proxy chains - remove `js_proxy_isArray`
1 parent f3f2f42 commit 97be5a3

File tree

1 file changed

+35
-20
lines changed

1 file changed

+35
-20
lines changed
 

‎quickjs.c

+35-20
Original file line numberDiff line numberDiff line change
@@ -1175,9 +1175,10 @@ static JSValue JS_ThrowTypeErrorRevokedProxy(JSContext *ctx);
11751175
static JSValue js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj);
11761176
static int js_proxy_setPrototypeOf(JSContext *ctx, JSValueConst obj,
11771177
JSValueConst proto_val, BOOL throw_flag);
1178+
1179+
static int js_resolve_proxy(JSContext *ctx, JSValueConst *pval, int throw_exception);
11781180
static int js_proxy_isExtensible(JSContext *ctx, JSValueConst obj);
11791181
static int js_proxy_preventExtensions(JSContext *ctx, JSValueConst obj);
1180-
static int js_proxy_isArray(JSContext *ctx, JSValueConst obj);
11811182
static int JS_CreateProperty(JSContext *ctx, JSObject *p,
11821183
JSAtom prop, JSValueConst val,
11831184
JSValueConst getter, JSValueConst setter,
@@ -12109,15 +12110,14 @@ static __maybe_unused void JS_PrintValue(JSContext *ctx,
1210912110
}
1211012111

1211112112
/* return -1 if exception (proxy case) or TRUE/FALSE */
12113+
// TODO: should take flags to make proxy resolution and exceptions optional
1211212114
int JS_IsArray(JSContext *ctx, JSValueConst val)
1211312115
{
12114-
JSObject *p;
12116+
if (js_resolve_proxy(ctx, &val, TRUE))
12117+
return -1;
1211512118
if (JS_VALUE_GET_TAG(val) == JS_TAG_OBJECT) {
12116-
p = JS_VALUE_GET_OBJ(val);
12117-
if (unlikely(p->class_id == JS_CLASS_PROXY))
12118-
return js_proxy_isArray(ctx, val);
12119-
else
12120-
return p->class_id == JS_CLASS_ARRAY;
12119+
JSObject *p = JS_VALUE_GET_OBJ(val);
12120+
return p->class_id == JS_CLASS_ARRAY;
1212112121
} else {
1212212122
return FALSE;
1212312123
}
@@ -46713,20 +46713,35 @@ static JSValue js_proxy_call(JSContext *ctx, JSValueConst func_obj,
4671346713
return ret;
4671446714
}
4671546715

46716-
static int js_proxy_isArray(JSContext *ctx, JSValueConst obj)
46717-
{
46718-
JSProxyData *s = JS_GetOpaque(obj, JS_CLASS_PROXY);
46719-
if (!s)
46720-
return FALSE;
46721-
if (js_check_stack_overflow(ctx->rt, 0)) {
46722-
JS_ThrowStackOverflow(ctx);
46723-
return -1;
46724-
}
46725-
if (s->is_revoked) {
46726-
JS_ThrowTypeErrorRevokedProxy(ctx);
46727-
return -1;
46716+
/* `js_resolve_proxy`: resolve the proxy chain
46717+
`*pval` is updated with to ultimate proxy target
46718+
`throw_exception` controls whether exceptions are thown or not
46719+
- return -1 in case of error
46720+
- otherwise return 0
46721+
*/
46722+
static int js_resolve_proxy(JSContext *ctx, JSValueConst *pval, BOOL throw_exception) {
46723+
int depth = 0;
46724+
JSObject *p;
46725+
JSProxyData *s;
46726+
46727+
while (JS_VALUE_GET_TAG(*pval) == JS_TAG_OBJECT) {
46728+
p = JS_VALUE_GET_OBJ(*pval);
46729+
if (p->class_id != JS_CLASS_PROXY)
46730+
break;
46731+
if (depth++ > 1000) {
46732+
if (throw_exception)
46733+
JS_ThrowStackOverflow(ctx);
46734+
return -1;
46735+
}
46736+
s = p->u.opaque;
46737+
if (s->is_revoked) {
46738+
if (throw_exception)
46739+
JS_ThrowTypeErrorRevokedProxy(ctx);
46740+
return -1;
46741+
}
46742+
*pval = s->target;
4672846743
}
46729-
return JS_IsArray(ctx, s->target);
46744+
return 0;
4673046745
}
4673146746

4673246747
static const JSClassExoticMethods js_proxy_exotic_methods = {

0 commit comments

Comments
 (0)