respsect array and object length requests

This commit is contained in:
2026-02-14 15:42:19 -06:00
parent 356c51bde3
commit e75596ce30
18 changed files with 54250 additions and 62692 deletions

View File

@@ -2136,8 +2136,24 @@ static JSValue js_sub_string_val (JSContext *ctx, JSValue src, int start, int en
return js_new_string8_len (ctx, buf, len);
}
/* Heap string — fast path for short ASCII substrings (avoids heap alloc) */
JSText *p = JS_VALUE_GET_STRING (src);
if (len <= MIST_ASCII_MAX_LEN) {
char buf[MIST_ASCII_MAX_LEN];
int all_ascii = 1;
for (int i = 0; i < len; i++) {
uint32_t c = string_get (p, start + i);
if (c >= 0x80) { all_ascii = 0; break; }
buf[i] = (char)c;
}
if (all_ascii) {
JSValue imm = MIST_TryNewImmediateASCII (buf, len);
if (!JS_IsNull (imm)) return imm;
}
}
/* Heap string — delegate to existing js_sub_string */
return js_sub_string (ctx, JS_VALUE_GET_STRING (src), start, end);
return js_sub_string (ctx, p, start, end);
}
/* Allocate a new pretext (mutable JSText) with initial capacity */
@@ -2646,11 +2662,51 @@ JSValue JS_NewArrayLen (JSContext *ctx, uint32_t len) {
JSValue JS_NewArray (JSContext *ctx) { return JS_NewArrayLen (ctx, 0); }
/* Create array with pre-allocated capacity but len=0 (for push-fill patterns) */
JSValue JS_NewArrayCap (JSContext *ctx, uint32_t cap) {
if (cap == 0) cap = JS_ARRAY_INITIAL_SIZE;
size_t values_size = sizeof (JSValue) * cap;
size_t total_size = sizeof (JSArray) + values_size;
JSArray *arr = js_malloc (ctx, total_size);
if (!arr) return JS_EXCEPTION;
arr->mist_hdr = objhdr_make (cap, OBJ_ARRAY, false, false, false, false);
arr->len = 0;
for (uint32_t i = 0; i < cap; i++)
arr->values[i] = JS_NULL;
return JS_MKPTR (arr);
}
JSValue JS_NewObject (JSContext *ctx) {
/* inline JS_NewObjectClass(ctx, JS_CLASS_OBJECT); */
return JS_NewObjectProtoClass (ctx, ctx->class_proto[JS_CLASS_OBJECT], JS_CLASS_OBJECT);
}
/* Create object with pre-allocated hash table for n properties */
JSValue JS_NewObjectCap (JSContext *ctx, uint32_t n) {
/* slot 0 is reserved, so need n+1 slots minimum.
Hash table needs ~2x entries for good load factor.
mask must be power-of-2 minus 1. */
uint32_t need = (n + 1) * 2;
uint32_t mask = JS_RECORD_INITIAL_MASK;
while (mask + 1 < need) mask = (mask << 1) | 1;
JSGCRef proto_ref;
JS_PushGCRef (ctx, &proto_ref);
proto_ref.val = ctx->class_proto[JS_CLASS_OBJECT];
JSRecord *rec = js_new_record_class (ctx, mask, JS_CLASS_OBJECT);
JSValue proto_val = proto_ref.val;
JS_PopGCRef (ctx, &proto_ref);
if (!rec) return JS_EXCEPTION;
if (JS_IsRecord (proto_val))
rec->proto = proto_val;
return JS_MKPTR (rec);
}
/* Note: at least 'length' arguments will be readable in 'argv' */
static JSValue JS_NewCFunction3 (JSContext *ctx, JSCFunction *func, const char *name, int length, JSCFunctionEnum cproto, int magic) {