Skip to content

Commit 15f798d

Browse files
authored
Implement Array.prototype.with (#45)
1 parent a19b07a commit 15f798d

File tree

2 files changed

+75
-36
lines changed

2 files changed

+75
-36
lines changed

quickjs.c

+75
Original file line numberDiff line numberDiff line change
@@ -35936,6 +35936,80 @@ static JSValue js_array_at(JSContext *ctx, JSValueConst this_val,
3593635936
return ret;
3593735937
}
3593835938

35939+
static JSValue js_array_with(JSContext *ctx, JSValueConst this_val,
35940+
int argc, JSValueConst *argv)
35941+
{
35942+
JSValue arr, obj, ret, *arrp, *pval;
35943+
JSObject *p;
35944+
int64_t i, len, idx;
35945+
uint32_t count32;
35946+
35947+
ret = JS_EXCEPTION;
35948+
arr = JS_UNDEFINED;
35949+
obj = JS_ToObject(ctx, this_val);
35950+
if (js_get_length64(ctx, &len, obj))
35951+
goto exception;
35952+
35953+
if (len > UINT32_MAX) {
35954+
JS_ThrowRangeError(ctx, "invalid array length");
35955+
goto exception;
35956+
}
35957+
35958+
if (JS_ToInt64Sat(ctx, &idx, argv[0]))
35959+
goto exception;
35960+
35961+
if (idx < 0)
35962+
idx = len + idx;
35963+
35964+
if (idx < 0 || idx >= len) {
35965+
JS_ThrowRangeError(ctx, "invalid array index: %" PRId64, idx);
35966+
goto exception;
35967+
}
35968+
35969+
arr = JS_NewArray(ctx);
35970+
if (JS_IsException(arr))
35971+
goto exception;
35972+
35973+
p = JS_VALUE_GET_OBJ(arr);
35974+
if (expand_fast_array(ctx, p, len) < 0)
35975+
goto exception;
35976+
p->u.array.count = len;
35977+
35978+
i = 0;
35979+
pval = p->u.array.u.values;
35980+
if (js_get_fast_array(ctx, obj, &arrp, &count32) && count32 == len) {
35981+
for (; i < idx; i++, pval++)
35982+
*pval = JS_DupValue(ctx, arrp[i]);
35983+
*pval = JS_DupValue(ctx, argv[1]);
35984+
for (i++, pval++; i < len; i++, pval++)
35985+
*pval = JS_DupValue(ctx, arrp[i]);
35986+
} else {
35987+
for (; i < idx; i++, pval++)
35988+
if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval))
35989+
goto fill_and_fail;
35990+
*pval = JS_DupValue(ctx, argv[1]);
35991+
for (i++, pval++; i < len; i++, pval++) {
35992+
if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) {
35993+
fill_and_fail:
35994+
for (; i < len; i++, pval++)
35995+
*pval = JS_UNDEFINED;
35996+
goto exception;
35997+
}
35998+
}
35999+
}
36000+
36001+
if (JS_SetProperty(ctx, arr, JS_ATOM_length, JS_NewInt64(ctx, len)) < 0)
36002+
goto exception;
36003+
36004+
ret = arr;
36005+
arr = JS_UNDEFINED;
36006+
36007+
exception:
36008+
JS_FreeValue(ctx, arr);
36009+
JS_FreeValue(ctx, obj);
36010+
return ret;
36011+
}
36012+
3593936013
static JSValue js_array_concat(JSContext *ctx, JSValueConst this_val,
3594036014
int argc, JSValueConst *argv)
3594136015
{
@@ -37432,6 +37506,7 @@ static const JSCFunctionListEntry js_iterator_proto_funcs[] = {
3743237506

3743337507
static const JSCFunctionListEntry js_array_proto_funcs[] = {
3743437508
JS_CFUNC_DEF("at", 1, js_array_at ),
37509+
JS_CFUNC_DEF("with", 2, js_array_with ),
3743537510
JS_CFUNC_DEF("concat", 1, js_array_concat ),
3743637511
JS_CFUNC_MAGIC_DEF("every", 1, js_array_every, special_every ),
3743737512
JS_CFUNC_MAGIC_DEF("some", 1, js_array_every, special_some ),

test262_errors.txt

-36
Original file line numberDiff line numberDiff line change
@@ -59,42 +59,6 @@ test262/test/built-ins/Array/prototype/toSpliced/this-value-boolean.js:18: TypeE
5959
test262/test/built-ins/Array/prototype/toSpliced/this-value-boolean.js:18: strict mode: TypeError: cannot read property 'call' of undefined
6060
test262/test/built-ins/Array/prototype/toSpliced/unmodified.js:13: TypeError: not a function
6161
test262/test/built-ins/Array/prototype/toSpliced/unmodified.js:13: strict mode: TypeError: not a function
62-
test262/test/built-ins/Array/prototype/with/frozen-this-value.js:13: TypeError: not a function
63-
test262/test/built-ins/Array/prototype/with/frozen-this-value.js:13: strict mode: TypeError: not a function
64-
test262/test/built-ins/Array/prototype/with/holes-not-preserved.js:27: TypeError: not a function
65-
test262/test/built-ins/Array/prototype/with/holes-not-preserved.js:27: strict mode: TypeError: not a function
66-
test262/test/built-ins/Array/prototype/with/ignores-species.js:21: TypeError: not a function
67-
test262/test/built-ins/Array/prototype/with/ignores-species.js:21: strict mode: TypeError: not a function
68-
test262/test/built-ins/Array/prototype/with/immutable.js:13: TypeError: not a function
69-
test262/test/built-ins/Array/prototype/with/immutable.js:13: strict mode: TypeError: not a function
70-
test262/test/built-ins/Array/prototype/with/index-bigger-or-eq-than-length.js:21: Test262Error: Expected a RangeError but got a TypeError
71-
test262/test/built-ins/Array/prototype/with/index-bigger-or-eq-than-length.js:21: strict mode: Test262Error: Expected a RangeError but got a TypeError
72-
test262/test/built-ins/Array/prototype/with/index-casted-to-number.js:23: TypeError: not a function
73-
test262/test/built-ins/Array/prototype/with/index-casted-to-number.js:23: strict mode: TypeError: not a function
74-
test262/test/built-ins/Array/prototype/with/index-negative.js:23: TypeError: not a function
75-
test262/test/built-ins/Array/prototype/with/index-negative.js:23: strict mode: TypeError: not a function
76-
test262/test/built-ins/Array/prototype/with/index-smaller-than-minus-length.js:21: TypeError: not a function
77-
test262/test/built-ins/Array/prototype/with/index-smaller-than-minus-length.js:21: strict mode: TypeError: not a function
78-
test262/test/built-ins/Array/prototype/with/length-decreased-while-iterating.js:32: TypeError: not a function
79-
test262/test/built-ins/Array/prototype/with/length-decreased-while-iterating.js:32: strict mode: TypeError: not a function
80-
test262/test/built-ins/Array/prototype/with/length-exceeding-array-length-limit.js:26: Test262Error: Expected a RangeError but got a TypeError
81-
test262/test/built-ins/Array/prototype/with/length-exceeding-array-length-limit.js:26: strict mode: Test262Error: Expected a RangeError but got a TypeError
82-
test262/test/built-ins/Array/prototype/with/length-increased-while-iterating.js:32: TypeError: not a function
83-
test262/test/built-ins/Array/prototype/with/length-increased-while-iterating.js:32: strict mode: TypeError: not a function
84-
test262/test/built-ins/Array/prototype/with/length-tolength.js:19: TypeError: cannot read property 'call' of undefined
85-
test262/test/built-ins/Array/prototype/with/length-tolength.js:19: strict mode: TypeError: cannot read property 'call' of undefined
86-
test262/test/built-ins/Array/prototype/with/metadata/length.js:30: TypeError: cannot convert to object
87-
test262/test/built-ins/Array/prototype/with/metadata/length.js:30: strict mode: TypeError: cannot convert to object
88-
test262/test/built-ins/Array/prototype/with/metadata/name.js:28: TypeError: cannot convert to object
89-
test262/test/built-ins/Array/prototype/with/metadata/name.js:28: strict mode: TypeError: cannot convert to object
90-
test262/test/built-ins/Array/prototype/with/metadata/property-descriptor.js:18: Test262Error: typeof Expected SameValue(«undefined», «function») to be true
91-
test262/test/built-ins/Array/prototype/with/metadata/property-descriptor.js:18: strict mode: Test262Error: typeof Expected SameValue(«undefined», «function») to be true
92-
test262/test/built-ins/Array/prototype/with/no-get-replaced-index.js:29: TypeError: not a function
93-
test262/test/built-ins/Array/prototype/with/no-get-replaced-index.js:29: strict mode: TypeError: not a function
94-
test262/test/built-ins/Array/prototype/with/not-a-constructor.js:30: Test262Error: isConstructor invoked with a non-function value
95-
test262/test/built-ins/Array/prototype/with/not-a-constructor.js:30: strict mode: Test262Error: isConstructor invoked with a non-function value
96-
test262/test/built-ins/Array/prototype/with/this-value-boolean.js:22: TypeError: cannot read property 'call' of undefined
97-
test262/test/built-ins/Array/prototype/with/this-value-boolean.js:22: strict mode: TypeError: cannot read property 'call' of undefined
9862
test262/test/built-ins/AsyncGeneratorPrototype/return/return-state-completed-broken-promise.js:53: TypeError: $DONE() not called
9963
test262/test/built-ins/AsyncGeneratorPrototype/return/return-state-completed-broken-promise.js:53: strict mode: TypeError: $DONE() not called
10064
test262/test/built-ins/AsyncGeneratorPrototype/return/return-suspendedStart-broken-promise.js:34: TypeError: $DONE() not called

0 commit comments

Comments
 (0)