modified js_allocate_fast_array() so that the array is fully initialized. It is slightly slower but avoids several nasty bugs (#471)

This commit is contained in:
Fabrice Bellard 2026-03-21 10:55:57 +01:00
parent f1139494d1
commit 4c722cea4e

@ -9153,14 +9153,15 @@ static inline int add_fast_array_element(JSContext *ctx, JSObject *p,
return TRUE;
}
/* Allocate a new fast array. Its 'length' property is set to zero. It
maximum size is 2^31-1 elements. For convenience, 'len' is a 64 bit
integer. WARNING: the content of the array is not initialized. */
/* Allocate a new fast array initialized to JS_UNDEFINED. Its maximum
size is 2^31-1 elements. For convenience, 'len' is a 64 bit
integer. */
static JSValue js_allocate_fast_array(JSContext *ctx, int64_t len)
{
JSValue arr;
JSObject *p;
int i;
if (len > INT32_MAX)
return JS_ThrowRangeError(ctx, "invalid array length");
arr = JS_NewArray(ctx);
@ -9173,6 +9174,10 @@ static JSValue js_allocate_fast_array(JSContext *ctx, int64_t len)
return JS_EXCEPTION;
}
p->u.array.count = len;
for(i = 0; i < len; i++)
p->u.array.u.values[i] = JS_UNDEFINED;
/* update the 'length' field */
set_value(ctx, &p->prop[0].u.value, JS_NewInt32(ctx, len));
}
return arr;
}
@ -41395,21 +41400,14 @@ static JSValue js_array_with(JSContext *ctx, JSValueConst this_val,
} else {
for (; i < idx; i++, pval++)
if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval))
goto fill_and_fail;
goto exception;
*pval = JS_DupValue(ctx, argv[1]);
for (i++, pval++; i < len; i++, pval++) {
if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) {
fill_and_fail:
for (; i < len; i++, pval++)
*pval = JS_UNDEFINED;
if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval))
goto exception;
}
}
}
if (JS_SetProperty(ctx, arr, JS_ATOM_length, JS_NewInt64(ctx, len)) < 0)
goto exception;
ret = arr;
arr = JS_UNDEFINED;
@ -42293,17 +42291,10 @@ static JSValue js_array_toReversed(JSContext *ctx, JSValueConst this_val,
} else {
// Query order is observable; test262 expects descending order.
for (; i >= 0; i--, pval++) {
if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) {
// Exception; initialize remaining elements.
for (; i >= 0; i--, pval++)
*pval = JS_UNDEFINED;
if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval))
goto exception;
}
}
}
if (JS_SetProperty(ctx, arr, JS_ATOM_length, JS_NewInt64(ctx, len)) < 0)
goto exception;
}
ret = arr;
@ -42492,17 +42483,11 @@ static JSValue js_array_toSpliced(JSContext *ctx, JSValueConst this_val,
assert(pval == last);
if (JS_SetProperty(ctx, arr, JS_ATOM_length, JS_NewInt64(ctx, newlen)) < 0)
goto exception;
done:
ret = arr;
arr = JS_UNDEFINED;
exception:
while (pval != last)
*pval++ = JS_UNDEFINED;
JS_FreeValue(ctx, arr);
JS_FreeValue(ctx, obj);
return ret;
@ -42847,16 +42832,10 @@ static JSValue js_array_toSorted(JSContext *ctx, JSValueConst this_val,
*pval = JS_DupValue(ctx, arrp[i]);
} else {
for (; i < len; i++, pval++) {
if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) {
for (; i < len; i++, pval++)
*pval = JS_UNDEFINED;
if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval))
goto exception;
}
}
}
if (JS_SetProperty(ctx, arr, JS_ATOM_length, JS_NewInt64(ctx, len)) < 0)
goto exception;
}
ret = js_array_sort(ctx, arr, argc, argv);