fix tests
This commit is contained in:
@@ -4885,6 +4885,54 @@ static void free_array(JSRuntime *rt, JSArray *arr)
|
||||
js_free_rt(rt, arr);
|
||||
}
|
||||
|
||||
static int js_intrinsic_array_ensure_capacity(JSContext *ctx, JSArray *arr, uint32_t min_cap)
|
||||
{
|
||||
if (min_cap <= arr->cap)
|
||||
return 0;
|
||||
|
||||
uint32_t new_cap = arr->cap ? arr->cap : JS_ARRAY_INITIAL_SIZE;
|
||||
while (new_cap < min_cap) {
|
||||
if (new_cap > UINT32_MAX / 2) {
|
||||
new_cap = min_cap;
|
||||
break;
|
||||
}
|
||||
new_cap *= 2;
|
||||
}
|
||||
|
||||
JSValue *new_values = js_realloc(ctx, arr->values, sizeof(JSValue) * new_cap);
|
||||
if (!new_values)
|
||||
return -1;
|
||||
|
||||
arr->values = new_values;
|
||||
arr->cap = new_cap;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int js_intrinsic_array_set(JSContext *ctx, JSArray *arr, uint32_t idx, JSValue val)
|
||||
{
|
||||
if (arr->stone) {
|
||||
JS_FreeValue(ctx, val);
|
||||
JS_ThrowInternalError(ctx, "cannot set on a stoned array");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (js_intrinsic_array_ensure_capacity(ctx, arr, idx + 1) < 0) {
|
||||
JS_FreeValue(ctx, val);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (idx >= arr->len) {
|
||||
for (uint32_t i = arr->len; i < idx; i++) {
|
||||
arr->values[i] = JS_NULL;
|
||||
}
|
||||
arr->len = idx + 1;
|
||||
arr->values[idx] = val;
|
||||
} else {
|
||||
set_value(ctx, &arr->values[idx], val);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Push element to intrinsic array, growing if needed. Returns -1 on error, 0 on success. */
|
||||
static int js_intrinsic_array_push(JSContext *ctx, JSArray *arr, JSValue val)
|
||||
{
|
||||
@@ -6612,24 +6660,19 @@ static JSValue JS_GetPropertyValue(JSContext *ctx, JSValueConst this_obj,
|
||||
int JS_SetPropertyNumber(JSContext *js, JSValueConst obj, int idx, JSValue val)
|
||||
{
|
||||
if (JS_VALUE_GET_TAG(obj) != JS_TAG_ARRAY) {
|
||||
JS_FreeValue(js, val);
|
||||
JS_ThrowInternalError(js, "cannot set with a number on a non array");
|
||||
return -1;
|
||||
}
|
||||
|
||||
JSArray *a = JS_VALUE_GET_ARRAY(obj);
|
||||
int len = a->len;
|
||||
if (idx < 0 || idx >= len) {
|
||||
JS_ThrowInternalError(js, "index out of bounds");
|
||||
if (idx < 0) {
|
||||
JS_FreeValue(js, val);
|
||||
JS_ThrowRangeError(js, "array index out of bounds");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (a->stone) {
|
||||
JS_ThrowInternalError(js, "cannot set on a stoned array");
|
||||
return -1;
|
||||
}
|
||||
|
||||
a->values[idx] = JS_DupValue(js, val);
|
||||
return TRUE;
|
||||
return js_intrinsic_array_set(js, a, (uint32_t)idx, val);
|
||||
}
|
||||
|
||||
JSValue JS_GetPropertyNumber(JSContext *js, JSValueConst obj, int idx)
|
||||
@@ -6868,15 +6911,13 @@ static int JS_SetPropertyValue(JSContext *ctx, JSValueConst this_obj, JSValue pr
|
||||
if (likely(this_tag == JS_TAG_ARRAY && prop_tag == JS_TAG_INT)) {
|
||||
JSArray *arr = JS_VALUE_GET_ARRAY(this_obj);
|
||||
int32_t signed_idx = JS_VALUE_GET_INT(prop);
|
||||
/* Throw for negative index or out of bounds */
|
||||
if (signed_idx < 0 || (uint32_t)signed_idx >= arr->len) {
|
||||
if (signed_idx < 0) {
|
||||
JS_FreeValue(ctx, val);
|
||||
JS_ThrowRangeError(ctx, "array index %d out of bounds (length %u)",
|
||||
signed_idx, arr->len);
|
||||
return -1;
|
||||
}
|
||||
set_value(ctx, &arr->values[signed_idx], val);
|
||||
return TRUE;
|
||||
return js_intrinsic_array_set(ctx, arr, (uint32_t)signed_idx, val);
|
||||
}
|
||||
|
||||
/* Intrinsic array slow path - handle non-int index */
|
||||
@@ -6894,13 +6935,12 @@ static int JS_SetPropertyValue(JSContext *ctx, JSValueConst this_obj, JSValue pr
|
||||
JSArray *arr = JS_VALUE_GET_ARRAY(this_obj);
|
||||
JS_FreeValue(ctx, prop);
|
||||
uint32_t idx = (uint32_t)d;
|
||||
if (d < 0 || d != (double)idx || idx >= arr->len) {
|
||||
if (d < 0 || d != (double)idx) {
|
||||
JS_FreeValue(ctx, val);
|
||||
JS_ThrowRangeError(ctx, "array index out of bounds");
|
||||
return -1;
|
||||
}
|
||||
set_value(ctx, &arr->values[idx], val);
|
||||
return TRUE;
|
||||
return js_intrinsic_array_set(ctx, arr, idx, val);
|
||||
}
|
||||
JS_FreeValue(ctx, prop);
|
||||
JS_FreeValue(ctx, val);
|
||||
|
||||
Reference in New Issue
Block a user