better array allocation

This commit is contained in:
2026-02-14 14:44:00 -06:00
parent 89421e11a4
commit 356c51bde3
12 changed files with 719589 additions and 134691 deletions

View File

@@ -7911,8 +7911,8 @@ static JSValue js_cell_array (JSContext *ctx, JSValue this_val, int argc, JSValu
JSValue exit_val = argc > 3 ? argv[3] : JS_NULL;
JSGCRef result_ref;
JS_PushGCRef (ctx, &result_ref); /* Push first - sets val to JS_NULL */
result_ref.val = JS_NewArray (ctx); /* Then assign */
JS_PushGCRef (ctx, &result_ref);
result_ref.val = JS_NewArrayLen (ctx, len);
if (JS_IsException (result_ref.val)) {
JS_PopGCRef (ctx, &result_ref);
JS_PopGCRef (ctx, &arg1_ref);
@@ -7920,17 +7920,23 @@ static JSValue js_cell_array (JSContext *ctx, JSValue this_val, int argc, JSValu
return result_ref.val;
}
int out_idx = 0;
#define MAP_STORE(val) do { \
JSArray *out = JS_VALUE_GET_ARRAY (result_ref.val); \
out->values[out_idx++] = (val); \
} while(0)
#define MAP_ERR() do { JS_PopGCRef (ctx, &result_ref); JS_PopGCRef (ctx, &arg1_ref); JS_PopGCRef (ctx, &arg0_ref); return JS_EXCEPTION; } while(0)
if (arity >= 2) {
if (reverse) {
for (int i = len - 1; i >= 0; i--) {
/* Re-chase input array each iteration */
arr = JS_VALUE_GET_ARRAY (arg0_ref.val);
if (i >= (int)arr->len) continue; /* array may have shrunk */
if (i >= (int)arr->len) continue;
JSValue args[2] = { arr->values[i], JS_NewInt32 (ctx, i) };
JSValue val = JS_CallInternal (ctx, arg1_ref.val, JS_NULL, 2, args, 0);
if (JS_IsException (val)) { JS_PopGCRef (ctx, &result_ref); JS_PopGCRef (ctx, &arg1_ref); JS_PopGCRef (ctx, &arg0_ref); return JS_EXCEPTION; }
if (JS_IsException (val)) { MAP_ERR (); }
if (!JS_IsNull (exit_val) && js_strict_eq (ctx, val, exit_val)) break;
if (js_intrinsic_array_push (ctx, &result_ref.val, val) < 0) { JS_PopGCRef (ctx, &result_ref); JS_PopGCRef (ctx, &arg1_ref); JS_PopGCRef (ctx, &arg0_ref); return JS_EXCEPTION; }
MAP_STORE (val);
}
} else {
for (int i = 0; i < len; i++) {
@@ -7938,9 +7944,9 @@ static JSValue js_cell_array (JSContext *ctx, JSValue this_val, int argc, JSValu
if (i >= (int)arr->len) break;
JSValue args[2] = { arr->values[i], JS_NewInt32 (ctx, i) };
JSValue val = JS_CallInternal (ctx, arg1_ref.val, JS_NULL, 2, args, 0);
if (JS_IsException (val)) { JS_PopGCRef (ctx, &result_ref); JS_PopGCRef (ctx, &arg1_ref); JS_PopGCRef (ctx, &arg0_ref); return JS_EXCEPTION; }
if (JS_IsException (val)) { MAP_ERR (); }
if (!JS_IsNull (exit_val) && js_strict_eq (ctx, val, exit_val)) break;
if (js_intrinsic_array_push (ctx, &result_ref.val, val) < 0) { JS_PopGCRef (ctx, &result_ref); JS_PopGCRef (ctx, &arg1_ref); JS_PopGCRef (ctx, &arg0_ref); return JS_EXCEPTION; }
MAP_STORE (val);
}
}
} else {
@@ -7950,9 +7956,9 @@ static JSValue js_cell_array (JSContext *ctx, JSValue this_val, int argc, JSValu
if (i >= (int)arr->len) continue;
JSValue item = arr->values[i];
JSValue val = JS_CallInternal (ctx, arg1_ref.val, JS_NULL, 1, &item, 0);
if (JS_IsException (val)) { JS_PopGCRef (ctx, &result_ref); JS_PopGCRef (ctx, &arg1_ref); JS_PopGCRef (ctx, &arg0_ref); return JS_EXCEPTION; }
if (JS_IsException (val)) { MAP_ERR (); }
if (!JS_IsNull (exit_val) && js_strict_eq (ctx, val, exit_val)) break;
if (js_intrinsic_array_push (ctx, &result_ref.val, val) < 0) { JS_PopGCRef (ctx, &result_ref); JS_PopGCRef (ctx, &arg1_ref); JS_PopGCRef (ctx, &arg0_ref); return JS_EXCEPTION; }
MAP_STORE (val);
}
} else {
for (int i = 0; i < len; i++) {
@@ -7960,12 +7966,17 @@ static JSValue js_cell_array (JSContext *ctx, JSValue this_val, int argc, JSValu
if (i >= (int)arr->len) break;
JSValue item = arr->values[i];
JSValue val = JS_CallInternal (ctx, arg1_ref.val, JS_NULL, 1, &item, 0);
if (JS_IsException (val)) { JS_PopGCRef (ctx, &result_ref); JS_PopGCRef (ctx, &arg1_ref); JS_PopGCRef (ctx, &arg0_ref); return JS_EXCEPTION; }
if (JS_IsException (val)) { MAP_ERR (); }
if (!JS_IsNull (exit_val) && js_strict_eq (ctx, val, exit_val)) break;
if (js_intrinsic_array_push (ctx, &result_ref.val, val) < 0) { JS_PopGCRef (ctx, &result_ref); JS_PopGCRef (ctx, &arg1_ref); JS_PopGCRef (ctx, &arg0_ref); return JS_EXCEPTION; }
MAP_STORE (val);
}
}
}
#undef MAP_STORE
#undef MAP_ERR
/* Truncate if early exit produced fewer elements */
JSArray *out = JS_VALUE_GET_ARRAY (result_ref.val);
out->len = out_idx;
JSValue result = result_ref.val;
JS_PopGCRef (ctx, &result_ref);
JS_PopGCRef (ctx, &arg1_ref);
@@ -8072,7 +8083,7 @@ static JSValue js_cell_array (JSContext *ctx, JSValue this_val, int argc, JSValu
JS_PushGCRef (ctx, &arr_ref);
JS_PushGCRef (ctx, &str_ref);
str_ref.val = arg;
arr_ref.val = JS_NewArray (ctx);
arr_ref.val = JS_NewArrayLen (ctx, len);
if (JS_IsException (arr_ref.val)) {
JS_PopGCRef (ctx, &str_ref);
JS_PopGCRef (ctx, &arr_ref);
@@ -8085,7 +8096,7 @@ static JSValue js_cell_array (JSContext *ctx, JSValue this_val, int argc, JSValu
JS_PopGCRef (ctx, &arr_ref);
return JS_EXCEPTION;
}
JS_ArrayPush (ctx, &arr_ref.val, ch);
JS_SetPropertyNumber (ctx, arr_ref.val, i, ch);
}
JSValue result = arr_ref.val;
JS_PopGCRef (ctx, &str_ref);
@@ -10182,16 +10193,13 @@ JSValue JS_CellFormat (JSContext *ctx, JSValue text, JSValue collection, JSValue
JSValue JS_NewArrayFrom (JSContext *ctx, int count, JSValue *values) {
JSGCRef arr_ref;
JS_PushGCRef (ctx, &arr_ref);
arr_ref.val = JS_NewArray (ctx);
arr_ref.val = JS_NewArrayLen (ctx, count);
if (JS_IsException (arr_ref.val)) {
JS_PopGCRef (ctx, &arr_ref);
return JS_EXCEPTION;
}
for (int i = 0; i < count; i++) {
if (JS_ArrayPush (ctx, &arr_ref.val, values[i]) < 0) {
JS_PopGCRef (ctx, &arr_ref);
return JS_EXCEPTION;
}
JS_SetPropertyNumber (ctx, arr_ref.val, i, values[i]);
}
JSValue result = arr_ref.val;
JS_PopGCRef (ctx, &arr_ref);
@@ -11063,7 +11071,7 @@ static char *js_do_nota_decode (JSContext *js, JSValue *tmp, char *nota, JSValue
break;
case NOTA_ARR:
nota = nota_read_array (&n, nota);
*tmp = JS_NewArray (js);
*tmp = JS_NewArrayLen (js, n);
for (int i = 0; i < n; i++) {
nota = js_do_nota_decode (js, &ret2, nota, *tmp, JS_NewInt32 (js, i), reviver);
JS_SetPropertyNumber (js, *tmp, i, ret2);