@@ -7936,6 +7936,61 @@ JSAtom JS_ValueToAtom(JSContext *ctx, JSValue val)
79367936 return atom;
79377937}
79387938
7939+ static BOOL js_get_fast_array_element(JSContext *ctx, JSObject *p,
7940+ uint32_t idx, JSValue *pval)
7941+ {
7942+ switch(p->class_id) {
7943+ case JS_CLASS_ARRAY:
7944+ case JS_CLASS_ARGUMENTS:
7945+ if (unlikely(idx >= p->u.array.count)) return FALSE;
7946+ *pval = js_dup(p->u.array.u.values[idx]);
7947+ return TRUE;
7948+ case JS_CLASS_INT8_ARRAY:
7949+ if (unlikely(idx >= p->u.array.count)) return FALSE;
7950+ *pval = js_int32(p->u.array.u.int8_ptr[idx]);
7951+ return TRUE;
7952+ case JS_CLASS_UINT8C_ARRAY:
7953+ case JS_CLASS_UINT8_ARRAY:
7954+ if (unlikely(idx >= p->u.array.count)) return FALSE;
7955+ *pval = js_int32(p->u.array.u.uint8_ptr[idx]);
7956+ return TRUE;
7957+ case JS_CLASS_INT16_ARRAY:
7958+ if (unlikely(idx >= p->u.array.count)) return FALSE;
7959+ *pval = js_int32(p->u.array.u.int16_ptr[idx]);
7960+ return TRUE;
7961+ case JS_CLASS_UINT16_ARRAY:
7962+ if (unlikely(idx >= p->u.array.count)) return FALSE;
7963+ *pval = js_int32(p->u.array.u.uint16_ptr[idx]);
7964+ return TRUE;
7965+ case JS_CLASS_INT32_ARRAY:
7966+ if (unlikely(idx >= p->u.array.count)) return FALSE;
7967+ *pval = js_int32(p->u.array.u.int32_ptr[idx]);
7968+ return TRUE;
7969+ case JS_CLASS_UINT32_ARRAY:
7970+ if (unlikely(idx >= p->u.array.count)) return FALSE;
7971+ *pval = js_uint32(p->u.array.u.uint32_ptr[idx]);
7972+ return TRUE;
7973+ case JS_CLASS_BIG_INT64_ARRAY:
7974+ if (unlikely(idx >= p->u.array.count)) return FALSE;
7975+ *pval = JS_NewBigInt64(ctx, p->u.array.u.int64_ptr[idx]);
7976+ return TRUE;
7977+ case JS_CLASS_BIG_UINT64_ARRAY:
7978+ if (unlikely(idx >= p->u.array.count)) return FALSE;
7979+ *pval = JS_NewBigUint64(ctx, p->u.array.u.uint64_ptr[idx]);
7980+ return TRUE;
7981+ case JS_CLASS_FLOAT32_ARRAY:
7982+ if (unlikely(idx >= p->u.array.count)) return FALSE;
7983+ *pval = js_float64(p->u.array.u.float_ptr[idx]);
7984+ return TRUE;
7985+ case JS_CLASS_FLOAT64_ARRAY:
7986+ if (unlikely(idx >= p->u.array.count)) return FALSE;
7987+ *pval = js_float64(p->u.array.u.double_ptr[idx]);
7988+ return TRUE;
7989+ default:
7990+ return FALSE;
7991+ }
7992+ }
7993+
79397994static JSValue JS_GetPropertyValue(JSContext *ctx, JSValue this_obj,
79407995 JSValue prop)
79417996{
@@ -7944,99 +7999,59 @@ static JSValue JS_GetPropertyValue(JSContext *ctx, JSValue this_obj,
79447999
79458000 if (likely(JS_VALUE_GET_TAG(this_obj) == JS_TAG_OBJECT &&
79468001 JS_VALUE_GET_TAG(prop) == JS_TAG_INT)) {
7947- JSObject *p;
7948- uint32_t idx;
7949- /* fast path for array access */
7950- p = JS_VALUE_GET_OBJ(this_obj);
7951- idx = JS_VALUE_GET_INT(prop);
7952- switch(p->class_id) {
7953- case JS_CLASS_ARRAY:
7954- case JS_CLASS_ARGUMENTS:
7955- if (unlikely(idx >= p->u.array.count)) goto slow_path;
7956- return js_dup(p->u.array.u.values[idx]);
7957- case JS_CLASS_INT8_ARRAY:
7958- if (unlikely(idx >= p->u.array.count)) goto slow_path;
7959- return js_int32(p->u.array.u.int8_ptr[idx]);
7960- case JS_CLASS_UINT8C_ARRAY:
7961- case JS_CLASS_UINT8_ARRAY:
7962- if (unlikely(idx >= p->u.array.count)) goto slow_path;
7963- return js_int32(p->u.array.u.uint8_ptr[idx]);
7964- case JS_CLASS_INT16_ARRAY:
7965- if (unlikely(idx >= p->u.array.count)) goto slow_path;
7966- return js_int32(p->u.array.u.int16_ptr[idx]);
7967- case JS_CLASS_UINT16_ARRAY:
7968- if (unlikely(idx >= p->u.array.count)) goto slow_path;
7969- return js_int32(p->u.array.u.uint16_ptr[idx]);
7970- case JS_CLASS_INT32_ARRAY:
7971- if (unlikely(idx >= p->u.array.count)) goto slow_path;
7972- return js_int32(p->u.array.u.int32_ptr[idx]);
7973- case JS_CLASS_UINT32_ARRAY:
7974- if (unlikely(idx >= p->u.array.count)) goto slow_path;
7975- return js_uint32(p->u.array.u.uint32_ptr[idx]);
7976- case JS_CLASS_BIG_INT64_ARRAY:
7977- if (unlikely(idx >= p->u.array.count)) goto slow_path;
7978- return JS_NewBigInt64(ctx, p->u.array.u.int64_ptr[idx]);
7979- case JS_CLASS_BIG_UINT64_ARRAY:
7980- if (unlikely(idx >= p->u.array.count)) goto slow_path;
7981- return JS_NewBigUint64(ctx, p->u.array.u.uint64_ptr[idx]);
7982- case JS_CLASS_FLOAT32_ARRAY:
7983- if (unlikely(idx >= p->u.array.count)) goto slow_path;
7984- return js_float64(p->u.array.u.float_ptr[idx]);
7985- case JS_CLASS_FLOAT64_ARRAY:
7986- if (unlikely(idx >= p->u.array.count)) goto slow_path;
7987- return js_float64(p->u.array.u.double_ptr[idx]);
7988- default:
7989- goto slow_path;
7990- }
7991- } else {
7992- slow_path:
7993- atom = JS_ValueToAtom(ctx, prop);
7994- JS_FreeValue(ctx, prop);
7995- if (unlikely(atom == JS_ATOM_NULL))
7996- return JS_EXCEPTION;
7997- ret = JS_GetProperty(ctx, this_obj, atom);
7998- JS_FreeAtom(ctx, atom);
7999- return ret;
8002+ JSObject *p = JS_VALUE_GET_OBJ(this_obj);
8003+ uint32_t idx = JS_VALUE_GET_INT(prop);
8004+ JSValue val;
8005+ /* fast path for array and typed array access */
8006+ if (js_get_fast_array_element(ctx, p, idx, &val))
8007+ return val;
80008008 }
8009+ atom = JS_ValueToAtom(ctx, prop);
8010+ JS_FreeValue(ctx, prop);
8011+ if (unlikely(atom == JS_ATOM_NULL))
8012+ return JS_EXCEPTION;
8013+ ret = JS_GetProperty(ctx, this_obj, atom);
8014+ JS_FreeAtom(ctx, atom);
8015+ return ret;
80018016}
80028017
80038018JSValue JS_GetPropertyUint32(JSContext *ctx, JSValue this_obj,
80048019 uint32_t idx)
80058020{
8006- return JS_GetPropertyValue (ctx, this_obj, js_uint32( idx) );
8021+ return JS_GetPropertyInt64 (ctx, this_obj, idx);
80078022}
80088023
80098024/* Check if an object has a generalized numeric property. Return value:
8010- -1 for exception,
8025+ -1 for exception, *pval set to JS_EXCEPTION
80118026 TRUE if property exists, stored into *pval,
8012- FALSE if proprty does not exist.
8027+ FALSE if property does not exist. *pval set to JS_UNDEFINED .
80138028 */
80148029static int JS_TryGetPropertyInt64(JSContext *ctx, JSValue obj, int64_t idx, JSValue *pval)
80158030{
8016- JSValue val = JS_UNDEFINED ;
8031+ JSValue val;
80178032 JSAtom prop;
80188033 int present;
80198034
8020- if (likely((uint64_t)idx <= JS_ATOM_MAX_INT)) {
8021- /* fast path */
8022- present = JS_HasProperty(ctx, obj, __JS_AtomFromUInt32(idx));
8035+ if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT &&
8036+ (uint64_t)idx <= INT32_MAX)) {
8037+ /* fast path for array and typed array access */
8038+ JSObject *p = JS_VALUE_GET_OBJ(obj);
8039+ if (js_get_fast_array_element(ctx, p, idx, pval))
8040+ return TRUE;
8041+ }
8042+ val = JS_EXCEPTION;
8043+ present = -1;
8044+ prop = JS_NewAtomInt64(ctx, idx);
8045+ if (likely(prop != JS_ATOM_NULL)) {
8046+ present = JS_HasProperty(ctx, obj, prop);
80238047 if (present > 0) {
8024- val = JS_GetPropertyValue (ctx, obj, js_int32(idx) );
8048+ val = JS_GetProperty (ctx, obj, prop );
80258049 if (unlikely(JS_IsException(val)))
80268050 present = -1;
8051+ } else if (present == FALSE) {
8052+ val = JS_UNDEFINED;
80278053 }
8028- } else {
8029- prop = JS_NewAtomInt64(ctx, idx);
8030- present = -1;
8031- if (likely(prop != JS_ATOM_NULL)) {
8032- present = JS_HasProperty(ctx, obj, prop);
8033- if (present > 0) {
8034- val = JS_GetProperty(ctx, obj, prop);
8035- if (unlikely(JS_IsException(val)))
8036- present = -1;
8037- }
8038- JS_FreeAtom(ctx, prop);
8039- }
8054+ JS_FreeAtom(ctx, prop);
80408055 }
80418056 *pval = val;
80428057 return present;
@@ -8047,9 +8062,12 @@ JSValue JS_GetPropertyInt64(JSContext *ctx, JSValue obj, int64_t idx)
80478062 JSAtom prop;
80488063 JSValue val;
80498064
8050- if ((uint64_t)idx <= INT32_MAX) {
8051- /* fast path for fast arrays */
8052- return JS_GetPropertyValue(ctx, obj, js_int32(idx));
8065+ if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT &&
8066+ (uint64_t)idx <= INT32_MAX)) {
8067+ /* fast path for array and typed array access */
8068+ JSObject *p = JS_VALUE_GET_OBJ(obj);
8069+ if (js_get_fast_array_element(ctx, p, idx, &val))
8070+ return val;
80538071 }
80548072 prop = JS_NewAtomInt64(ctx, idx);
80558073 if (prop == JS_ATOM_NULL)
@@ -34907,6 +34925,7 @@ static int js_obj_to_desc(JSContext *ctx, JSPropertyDescriptor *d,
3490734925 JSValue desc)
3490834926{
3490934927 JSValue val, getter, setter;
34928+ int present;
3491034929 int flags;
3491134930
3491234931 if (!JS_IsObject(desc)) {
@@ -34917,37 +34936,52 @@ static int js_obj_to_desc(JSContext *ctx, JSPropertyDescriptor *d,
3491734936 val = JS_UNDEFINED;
3491834937 getter = JS_UNDEFINED;
3491934938 setter = JS_UNDEFINED;
34920- if (JS_HasProperty(ctx, desc, JS_ATOM_enumerable)) {
34939+ present = JS_HasProperty(ctx, desc, JS_ATOM_enumerable);
34940+ if (present < 0)
34941+ goto fail;
34942+ if (present) {
3492134943 JSValue prop = JS_GetProperty(ctx, desc, JS_ATOM_enumerable);
3492234944 if (JS_IsException(prop))
3492334945 goto fail;
3492434946 flags |= JS_PROP_HAS_ENUMERABLE;
3492534947 if (JS_ToBoolFree(ctx, prop))
3492634948 flags |= JS_PROP_ENUMERABLE;
3492734949 }
34928- if (JS_HasProperty(ctx, desc, JS_ATOM_configurable)) {
34950+ present = JS_HasProperty(ctx, desc, JS_ATOM_configurable);
34951+ if (present < 0)
34952+ goto fail;
34953+ if (present) {
3492934954 JSValue prop = JS_GetProperty(ctx, desc, JS_ATOM_configurable);
3493034955 if (JS_IsException(prop))
3493134956 goto fail;
3493234957 flags |= JS_PROP_HAS_CONFIGURABLE;
3493334958 if (JS_ToBoolFree(ctx, prop))
3493434959 flags |= JS_PROP_CONFIGURABLE;
3493534960 }
34936- if (JS_HasProperty(ctx, desc, JS_ATOM_value)) {
34961+ present = JS_HasProperty(ctx, desc, JS_ATOM_value);
34962+ if (present < 0)
34963+ goto fail;
34964+ if (present) {
3493734965 flags |= JS_PROP_HAS_VALUE;
3493834966 val = JS_GetProperty(ctx, desc, JS_ATOM_value);
3493934967 if (JS_IsException(val))
3494034968 goto fail;
3494134969 }
34942- if (JS_HasProperty(ctx, desc, JS_ATOM_writable)) {
34970+ present = JS_HasProperty(ctx, desc, JS_ATOM_writable);
34971+ if (present < 0)
34972+ goto fail;
34973+ if (present) {
3494334974 JSValue prop = JS_GetProperty(ctx, desc, JS_ATOM_writable);
3494434975 if (JS_IsException(prop))
3494534976 goto fail;
3494634977 flags |= JS_PROP_HAS_WRITABLE;
3494734978 if (JS_ToBoolFree(ctx, prop))
3494834979 flags |= JS_PROP_WRITABLE;
3494934980 }
34950- if (JS_HasProperty(ctx, desc, JS_ATOM_get)) {
34981+ present = JS_HasProperty(ctx, desc, JS_ATOM_get);
34982+ if (present < 0)
34983+ goto fail;
34984+ if (present) {
3495134985 flags |= JS_PROP_HAS_GET;
3495234986 getter = JS_GetProperty(ctx, desc, JS_ATOM_get);
3495334987 if (JS_IsException(getter) ||
@@ -34956,7 +34990,10 @@ static int js_obj_to_desc(JSContext *ctx, JSPropertyDescriptor *d,
3495634990 goto fail;
3495734991 }
3495834992 }
34959- if (JS_HasProperty(ctx, desc, JS_ATOM_set)) {
34993+ present = JS_HasProperty(ctx, desc, JS_ATOM_set);
34994+ if (present < 0)
34995+ goto fail;
34996+ if (present) {
3496034997 flags |= JS_PROP_HAS_SET;
3496134998 setter = JS_GetProperty(ctx, desc, JS_ATOM_set);
3496234999 if (JS_IsException(setter) ||
@@ -36995,10 +37032,8 @@ static JSValue js_array_at(JSContext *ctx, JSValue this_val,
3699537032
3699637033 if (idx < 0 || idx >= len) {
3699737034 ret = JS_UNDEFINED;
36998- } else if (js_get_fast_array(ctx, obj, &arrp, &count) && count == len) {
36999- ret = js_dup(arrp[idx]);
37000- } else if (!JS_TryGetPropertyInt64(ctx, obj, idx, &ret)) {
37001- ret = JS_UNDEFINED;
37035+ } else {
37036+ ret = JS_GetPropertyInt64(ctx, obj, idx);
3700237037 }
3700337038
3700437039 exception:
0 commit comments