@@ -1175,9 +1175,10 @@ static JSValue JS_ThrowTypeErrorRevokedProxy(JSContext *ctx);
1175
1175
static JSValue js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj);
1176
1176
static int js_proxy_setPrototypeOf(JSContext *ctx, JSValueConst obj,
1177
1177
JSValueConst proto_val, BOOL throw_flag);
1178
+
1179
+ static int js_resolve_proxy(JSContext *ctx, JSValueConst *pval, int throw_exception);
1178
1180
static int js_proxy_isExtensible(JSContext *ctx, JSValueConst obj);
1179
1181
static int js_proxy_preventExtensions(JSContext *ctx, JSValueConst obj);
1180
- static int js_proxy_isArray(JSContext *ctx, JSValueConst obj);
1181
1182
static int JS_CreateProperty(JSContext *ctx, JSObject *p,
1182
1183
JSAtom prop, JSValueConst val,
1183
1184
JSValueConst getter, JSValueConst setter,
@@ -12109,15 +12110,14 @@ static __maybe_unused void JS_PrintValue(JSContext *ctx,
12109
12110
}
12110
12111
12111
12112
/* return -1 if exception (proxy case) or TRUE/FALSE */
12113
+ // TODO: should take flags to make proxy resolution and exceptions optional
12112
12114
int JS_IsArray(JSContext *ctx, JSValueConst val)
12113
12115
{
12114
- JSObject *p;
12116
+ if (js_resolve_proxy(ctx, &val, TRUE))
12117
+ return -1;
12115
12118
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;
12121
12121
} else {
12122
12122
return FALSE;
12123
12123
}
@@ -46713,20 +46713,35 @@ static JSValue js_proxy_call(JSContext *ctx, JSValueConst func_obj,
46713
46713
return ret;
46714
46714
}
46715
46715
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;
46728
46743
}
46729
- return JS_IsArray(ctx, s->target) ;
46744
+ return 0 ;
46730
46745
}
46731
46746
46732
46747
static const JSClassExoticMethods js_proxy_exotic_methods = {
0 commit comments