visaljs 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/THIRD_PARTY_LICENSES +1 -1
- package/cli.js +2782 -770
- package/node/include/js_node.h +1 -0
- package/node/prelude/_http_agent.js +5 -0
- package/node/prelude/_http_server.js +7 -0
- package/node/prelude/dns.js +7 -1
- package/node/prelude/events.js +7 -3
- package/node/prelude/http.js +693 -285
- package/node/prelude/https.js +14 -3
- package/node/prelude/internal/events_extras.js +2 -5
- package/node/prelude/internal/features.js +17 -0
- package/node/prelude/internal/http_agent.js +88 -2
- package/node/prelude/internal/http_chars.ts +22 -0
- package/node/prelude/internal/http_symbols.js +3 -0
- package/node/prelude/internal/net_bound.js +123 -0
- package/node/prelude/internal/net_onread.js +73 -0
- package/node/prelude/internal/net_tos.js +54 -0
- package/node/prelude/internal/perf_observe.js +7 -1
- package/node/prelude/internal/tls/wrap.js +2 -1
- package/node/prelude/module.js +42 -18
- package/node/prelude/net.js +212 -61
- package/node/prelude/perf_hooks.js +4 -0
- package/node/src/host_http.c +151 -21
- package/node/src/host_net.c +75 -9
- package/node/src/host_sys.c +9 -0
- package/package.json +1 -1
- package/prebuilt/win32-x64/boringssl-ce573858472b7fc9.a +0 -0
- package/prebuilt/win32-x64/brotli-20d86a61f30baeb3.a +0 -0
- package/prebuilt/win32-x64/uv-b11bae65d7fced82.a +0 -0
- package/prebuilt/win32-x64/zlib-4ce2317a4c3f5fb5.a +0 -0
- package/prebuilt/win32-x64/zstd-015315ac7c784c73.a +0 -0
- package/runtime/include/js_atoms.h +4 -0
- package/runtime/include/js_buffer.h +185 -0
- package/runtime/include/js_builtins.h +53 -0
- package/runtime/include/js_exception.h +3 -0
- package/runtime/include/js_function.h +1 -1
- package/runtime/include/js_object.h +21 -3
- package/runtime/include/js_ops.h +27 -0
- package/runtime/include/js_runtime.h +1 -0
- package/runtime/include/js_web.h +3 -3
- package/runtime/include/jscontext.h +15 -0
- package/runtime/src/atoms.c +37 -3
- package/runtime/src/builtins.c +17 -4
- package/runtime/src/events.c +19 -0
- package/runtime/src/function.c +37 -10
- package/runtime/src/gc.c +7 -5
- package/runtime/src/internal.h +4 -4
- package/runtime/src/iterator.c +5 -1
- package/runtime/src/object.c +42 -6
- package/runtime/src/regexp.c +569 -12
- package/runtime/src/shape.c +68 -1
- package/runtime/src/typedarray.c +23 -0
- package/runtime/src/weak.c +95 -24
package/runtime/src/function.c
CHANGED
|
@@ -222,10 +222,38 @@ JSValue js_get_prototype_from_constructor(JSContext *ctx, JSValue new_target, JS
|
|
|
222
222
|
return realm ? realm->intrinsics[fallback] : JS_EXCEPTION;
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
+
/* The root shape of the objects `new f` makes, with at least `slots` inline slots: kept on f, and
|
|
226
|
+
* grown by learn_instance_slots to what its instances end up holding. */
|
|
227
|
+
static JSShape *instance_root(JSContext *ctx, JSFunction *f, JSValue proto, uint16_t slots) {
|
|
228
|
+
JSShape *s = f->instance_shape;
|
|
229
|
+
if (JS_UNLIKELY(!s || !js_same_bits(s->proto, proto) || s->inline_cap < slots)) {
|
|
230
|
+
s = js_shape_root(ctx, &js_class_object, proto, slots);
|
|
231
|
+
js_store_ptr(ctx, &f->obj.cell, &f->instance_shape, s);
|
|
232
|
+
}
|
|
233
|
+
return s;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/* Slack tracking: when the constructors (a class's and its bases') left `v` with more properties
|
|
237
|
+
* than its root shape has inline slots, the next instances get room for them all. A derived
|
|
238
|
+
* class's `this` is made by its base, which can't count its subclasses' properties; the rest
|
|
239
|
+
* would sit out of line, where an inline cache's hit isn't inlined. */
|
|
240
|
+
static void learn_instance_slots(JSContext *ctx, JSFunction *f, JSValue v) {
|
|
241
|
+
JSShape *root = f->instance_shape;
|
|
242
|
+
if (!root || !js_is_object(v)) return;
|
|
243
|
+
JSShape *s = js_as_object(v)->shape;
|
|
244
|
+
if (JS_LIKELY(s->prop_count <= root->inline_cap || root->inline_cap >= JS_MAX_INLINE_SLOTS)) return;
|
|
245
|
+
JSShape *r = s;
|
|
246
|
+
while (r->parent) r = r->parent;
|
|
247
|
+
if (r != root) return; /* not made from it: an object the constructor returned, or a dictionary */
|
|
248
|
+
JSShape *grown = js_shape_root(ctx, &js_class_object, root->proto, (uint16_t)(s->prop_count < JS_MAX_INLINE_SLOTS ? s->prop_count : JS_MAX_INLINE_SLOTS));
|
|
249
|
+
js_store_ptr(ctx, &f->obj.cell, &f->instance_shape, grown);
|
|
250
|
+
}
|
|
251
|
+
|
|
225
252
|
JSValue js_create_from_constructor(JSContext *ctx, JSValue new_target, JSIntrinsic fallback) {
|
|
226
253
|
JSValue proto = js_get_prototype_from_constructor(ctx, new_target, fallback);
|
|
227
254
|
if (js_is_exception(proto)) return JS_EXCEPTION;
|
|
228
|
-
return js_new_object_proto(ctx, proto, JS_DEFAULT_INLINE_SLOTS);
|
|
255
|
+
if (!js_is_function(new_target)) return js_new_object_proto(ctx, proto, JS_DEFAULT_INLINE_SLOTS);
|
|
256
|
+
return js_object_value(js_alloc_object(ctx, JS_CELL_OBJECT, instance_root(ctx, js_as_function(new_target), proto, JS_DEFAULT_INLINE_SLOTS)));
|
|
229
257
|
}
|
|
230
258
|
|
|
231
259
|
JSValue js_new_instance(JSContext *ctx, JSValue fv, uint16_t slots, JSPropCache *ic) {
|
|
@@ -234,26 +262,25 @@ JSValue js_new_instance(JSContext *ctx, JSValue fv, uint16_t slots, JSPropCache
|
|
|
234
262
|
: js_get_prop(ctx, fv, JS_ATOM(prototype), ic);
|
|
235
263
|
if (js_is_exception(proto)) return JS_EXCEPTION;
|
|
236
264
|
if (!js_is_object(proto)) proto = ctx->intrinsics[JS_INTRINSIC_OBJECT_PROTOTYPE]; /* OrdinaryCreateFromConstructor's fallback */
|
|
237
|
-
|
|
238
|
-
JSShape *s = f->instance_shape;
|
|
239
|
-
if (JS_UNLIKELY(!s || !js_same_bits(s->proto, proto) || s->inline_cap != slots)) {
|
|
240
|
-
s = js_shape_root(ctx, &js_class_object, proto, slots);
|
|
241
|
-
js_store_ptr(ctx, &f->obj.cell, &f->instance_shape, s);
|
|
242
|
-
}
|
|
243
|
-
return js_object_value(js_alloc_object(ctx, JS_CELL_OBJECT, s));
|
|
265
|
+
return js_object_value(js_alloc_object(ctx, JS_CELL_OBJECT, instance_root(ctx, js_as_function(fv), proto, slots)));
|
|
244
266
|
}
|
|
245
267
|
|
|
246
268
|
JSValue js_construct(JSContext *ctx, JSValue f, uint32_t argc, const JSValue *argv, JSValue new_target, const char *callee_text) {
|
|
247
269
|
if (JS_UNLIKELY(!js_is_constructor(f))) return not_callable(ctx, f, callee_text, "constructor");
|
|
248
270
|
JSFunction *fn = js_as_function(f);
|
|
271
|
+
bool outermost = js_is_undefined(new_target) || js_same_bits(new_target, f); /* not a super() */
|
|
249
272
|
if (js_is_undefined(new_target)) new_target = f;
|
|
250
|
-
if (!(fn->flags & JS_FN_ORDINARY)) /* builtins create their own object; a derived constructor gets it from super() */
|
|
251
|
-
|
|
273
|
+
if (!(fn->flags & JS_FN_ORDINARY)) { /* builtins create their own object; a derived constructor gets it from super() */
|
|
274
|
+
JSValue r = fn->entry(fn->flags & JS_FN_PROXY ? ctx : fn->realm, f, JS_UNDEFINED, argc, argv, new_target);
|
|
275
|
+
if (outermost && (fn->flags & JS_FN_DERIVED) && !js_is_exception(r)) learn_instance_slots(ctx, fn, r);
|
|
276
|
+
return r;
|
|
277
|
+
}
|
|
252
278
|
/* [[Construct]] of an ordinary function (§10.2.2): this = a new object; an object result wins */
|
|
253
279
|
JSValue this_val = js_create_from_constructor(fn->realm, new_target, JS_INTRINSIC_OBJECT_PROTOTYPE);
|
|
254
280
|
if (js_is_exception(this_val)) return JS_EXCEPTION;
|
|
255
281
|
JSValue r = fn->entry(fn->realm, f, this_val, argc, argv, new_target);
|
|
256
282
|
if (js_is_exception(r)) return JS_EXCEPTION;
|
|
283
|
+
if (outermost) learn_instance_slots(ctx, fn, this_val);
|
|
257
284
|
return js_is_object(r) ? r : this_val;
|
|
258
285
|
}
|
|
259
286
|
|
package/runtime/src/gc.c
CHANGED
|
@@ -1646,8 +1646,10 @@ static void mark_roots(JSRuntime *rt, JSTracer *trc) {
|
|
|
1646
1646
|
js_trace_value(trc, rt->async_context);
|
|
1647
1647
|
js_jobs_trace(rt, trc); /* queued jobs, unhandled rejections */
|
|
1648
1648
|
js_weak_trace_roots(rt, trc); /* the WeakRef kept-alive set */
|
|
1649
|
-
for (JSContext *realm = rt->realms; realm; realm = realm->next_realm)
|
|
1649
|
+
for (JSContext *realm = rt->realms; realm; realm = realm->next_realm) {
|
|
1650
1650
|
for (unsigned i = 0; i < JS_INTRINSIC_COUNT; i++) js_trace_value(trc, realm->intrinsics[i]);
|
|
1651
|
+
if (realm->array_shape) js_trace_cell(trc, &realm->array_shape->cell);
|
|
1652
|
+
}
|
|
1651
1653
|
for (size_t t = 0; t < h->root_table_count; t++)
|
|
1652
1654
|
for (size_t i = 0; i < h->root_tables[t].n; i++) js_trace_value(trc, h->root_tables[t].slots[i]);
|
|
1653
1655
|
for (size_t i = 0; i < h->root_count; i++) js_trace_value(trc, *h->roots[i]);
|
|
@@ -1910,14 +1912,14 @@ static JS_NOINLINE void collect(JSContext *ctx, const void *stack_low, bool full
|
|
|
1910
1912
|
mark_roots(rt, trc);
|
|
1911
1913
|
mark_stack(trc);
|
|
1912
1914
|
drain(trc);
|
|
1913
|
-
while (js_weak_ephemerons(rt, trc)) drain(trc); /* a WeakMap value lives if its key does */
|
|
1915
|
+
while (js_weak_ephemerons(rt, trc, full)) drain(trc); /* a WeakMap value lives if its key does */
|
|
1914
1916
|
h->mark_stack = trc->stack; /* kept for the next collection */
|
|
1915
1917
|
h->mark_stack_cap = trc->cap;
|
|
1916
1918
|
double marked = js_os_now_ms_precise();
|
|
1917
1919
|
|
|
1918
|
-
js_weak_sweep(rt);
|
|
1919
|
-
js_atoms_sweep(rt); /* weak references, before anything is freed */
|
|
1920
|
-
js_shapes_sweep(rt);
|
|
1920
|
+
js_weak_sweep(rt, full);
|
|
1921
|
+
js_atoms_sweep(rt, full); /* weak references, before anything is freed */
|
|
1922
|
+
js_shapes_sweep(rt, full);
|
|
1921
1923
|
js_prop_caches_sweep(rt);
|
|
1922
1924
|
double weak = js_os_now_ms_precise();
|
|
1923
1925
|
|
package/runtime/src/internal.h
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
bool js_gc_is_marked(const JSCell *c);
|
|
13
13
|
|
|
14
14
|
/* Shapes (shape.c): weak processing after marking, and teardown. */
|
|
15
|
-
void js_shapes_sweep(JSRuntime *rt);
|
|
15
|
+
void js_shapes_sweep(JSRuntime *rt, bool full);
|
|
16
16
|
void js_shapes_free(JSRuntime *rt);
|
|
17
17
|
/* Inline caches (object.c): weak processing after marking, and teardown. */
|
|
18
18
|
void js_prop_caches_sweep(JSRuntime *rt);
|
|
@@ -55,8 +55,8 @@ void js_promise_then_internal(JSContext *ctx, JSValue promise, JSValue on_fulfil
|
|
|
55
55
|
* marked anything), weak processing after marking, the kept-alive roots, teardown;
|
|
56
56
|
* ClearKeptObjects; the FinalizationRegistry cleanup tasks (0, or -1 after an uncaught
|
|
57
57
|
* error); the realm's WeakMap, WeakSet, WeakRef, FinalizationRegistry. */
|
|
58
|
-
bool js_weak_ephemerons(JSRuntime *rt, JSTracer *trc);
|
|
59
|
-
void js_weak_sweep(JSRuntime *rt);
|
|
58
|
+
bool js_weak_ephemerons(JSRuntime *rt, JSTracer *trc, bool full);
|
|
59
|
+
void js_weak_sweep(JSRuntime *rt, bool full);
|
|
60
60
|
void js_weak_trace_roots(JSRuntime *rt, JSTracer *trc);
|
|
61
61
|
void js_weak_free(JSRuntime *rt);
|
|
62
62
|
void js_clear_kept_objects(JSRuntime *rt);
|
|
@@ -64,7 +64,7 @@ int js_run_finalization_cleanups(JSContext *ctx);
|
|
|
64
64
|
|
|
65
65
|
/* Atom table lifecycle (atoms.c). */
|
|
66
66
|
void js_atoms_init(JSRuntime *rt);
|
|
67
|
-
void js_atoms_sweep(JSRuntime *rt); /* weak processing: drop unmarked atoms */
|
|
67
|
+
void js_atoms_sweep(JSRuntime *rt, bool full); /* weak processing: drop unmarked atoms */
|
|
68
68
|
void js_atoms_free(JSRuntime *rt);
|
|
69
69
|
|
|
70
70
|
/* Cell classes defined outside gc.c: each kind's name and finalizer. The marker visits these kinds
|
package/runtime/src/iterator.c
CHANGED
|
@@ -236,7 +236,11 @@ JSValue js_iter_next(JSContext *ctx, JSValue rec) {
|
|
|
236
236
|
if (r->done) return JS_EMPTY;
|
|
237
237
|
JSValue value;
|
|
238
238
|
if (r->mode == MODE_ARRAY) {
|
|
239
|
-
|
|
239
|
+
/* a dense array's present element: what array_step's [[Get]] would read */
|
|
240
|
+
const JSElements *d = js_as_object(r->iterator)->elements;
|
|
241
|
+
uint32_t i = (uint32_t)r->index;
|
|
242
|
+
if (JS_LIKELY(d->kind == JS_ELEMENTS_DENSE && r->index < d->length && !js_is_empty(d->data[i]))) value = d->data[i];
|
|
243
|
+
else value = array_step(ctx, r->iterator, r->index, KIND_VALUES);
|
|
240
244
|
r->index++;
|
|
241
245
|
} else if (r->mode == MODE_STRING) {
|
|
242
246
|
uint32_t i = (uint32_t)r->index;
|
package/runtime/src/object.c
CHANGED
|
@@ -697,8 +697,7 @@ const JSClass js_class_array = {
|
|
|
697
697
|
"Array", sizeof(JSObject), array_get_own, array_define, array_delete, array_extra_keys, NULL, NULL, NULL,
|
|
698
698
|
};
|
|
699
699
|
|
|
700
|
-
static JSValue
|
|
701
|
-
JSShape *shape = js_shape_root(ctx, &js_class_array, proto, 0); /* named properties on arrays are rare */
|
|
700
|
+
static JSValue array_of_shape(JSContext *ctx, JSShape *shape, uint32_t capacity) {
|
|
702
701
|
JSObject *a = js_alloc_object(ctx, JS_CELL_ARRAY, shape);
|
|
703
702
|
if (capacity) {
|
|
704
703
|
JSElements *e = (JSElements *)js_alloc_cell(ctx, JS_CELL_ELEMENTS, sizeof(JSElements) + (size_t)capacity * sizeof(JSValue));
|
|
@@ -709,8 +708,13 @@ static JSValue array_with_proto(JSContext *ctx, JSValue proto, uint32_t capacity
|
|
|
709
708
|
return js_object_value(a);
|
|
710
709
|
}
|
|
711
710
|
|
|
711
|
+
static JSValue array_with_proto(JSContext *ctx, JSValue proto, uint32_t capacity) {
|
|
712
|
+
return array_of_shape(ctx, js_shape_root(ctx, &js_class_array, proto, 0), capacity); /* named properties on arrays are rare */
|
|
713
|
+
}
|
|
714
|
+
|
|
712
715
|
JSValue js_new_array(JSContext *ctx, uint32_t capacity) {
|
|
713
|
-
|
|
716
|
+
if (JS_UNLIKELY(!ctx->array_shape)) ctx->array_shape = js_shape_root(ctx, &js_class_array, ctx->intrinsics[JS_INTRINSIC_ARRAY_PROTOTYPE], 0);
|
|
717
|
+
return array_of_shape(ctx, ctx->array_shape, capacity);
|
|
714
718
|
}
|
|
715
719
|
|
|
716
720
|
JSValue js_new_array_from(JSContext *ctx, const JSValue *values, uint32_t n) {
|
|
@@ -821,7 +825,7 @@ JSValue js_get_value(JSContext *ctx, JSValue obj, JSValue key) {
|
|
|
821
825
|
}
|
|
822
826
|
|
|
823
827
|
int js_set_value(JSContext *ctx, JSValue obj, JSValue key, JSValue v, bool strict) {
|
|
824
|
-
if (js_is_object(obj)) return js_set(ctx, js_as_object(obj), key, v, obj, strict);
|
|
828
|
+
if (js_is_object(obj)) return js_key_is_index(key) ? js_set(ctx, js_as_object(obj), key, v, obj, strict) : js_set_prop_slow(ctx, obj, key, v, strict, NULL);
|
|
825
829
|
if (js_is_nullish(obj)) {
|
|
826
830
|
js_discard(nullish_error(ctx, obj, key, "set"));
|
|
827
831
|
return -1;
|
|
@@ -1045,6 +1049,11 @@ int js_set_prop_slow(JSContext *ctx, JSValue obj, JSValue key, JSValue v, bool s
|
|
|
1045
1049
|
JS_ASSERT_NOT_EXC(obj);
|
|
1046
1050
|
JS_ASSERT_NOT_EXC(v);
|
|
1047
1051
|
if (!js_is_object(obj) || js_key_is_index(key)) return js_set_value(ctx, obj, key, v, strict);
|
|
1052
|
+
JSPropCache none; /* no site (a computed key): only the shared cache */
|
|
1053
|
+
if (!ic) {
|
|
1054
|
+
none.kind = JS_IC_EMPTY;
|
|
1055
|
+
ic = &none;
|
|
1056
|
+
}
|
|
1048
1057
|
JSObject *o = js_as_object(obj);
|
|
1049
1058
|
if (ic->kind == JS_IC_ADD && o->shape == ic->shape && chain_holds(ctx, ic)) {
|
|
1050
1059
|
JSShape *next = ic->next; /* on the stack: kept alive if ensure_slot collects */
|
|
@@ -1083,8 +1092,10 @@ int js_set_prop_slow(JSContext *ctx, JSValue obj, JSValue key, JSValue v, bool s
|
|
|
1083
1092
|
return 1;
|
|
1084
1093
|
}
|
|
1085
1094
|
int r = js_set(ctx, o, key, v, obj, strict);
|
|
1086
|
-
/* a plain add (no setter or read-only property on the chain
|
|
1087
|
-
|
|
1095
|
+
/* a plain add (no setter or read-only property on the chain, or a prototype's writable data
|
|
1096
|
+
* property it shadows, as EventEmitter.prototype._events): remember the transition */
|
|
1097
|
+
bool shadows = l.holder && l.holder != o && (l.attrs & (JS_PROP_WRITABLE | JS_PROP_ACCESSOR)) == JS_PROP_WRITABLE;
|
|
1098
|
+
if (r == 1 && cacheable && (!l.holder || shadows) && !before->cls->define_own_property && !is_dictionary(o) &&
|
|
1088
1099
|
o->shape->parent == before && js_same_bits(o->shape->key, key)) {
|
|
1089
1100
|
JSPropCache c = { .kind = JS_IC_ADD, .depth = l.depth, .shape = before, .next = o->shape, .epoch = epoch };
|
|
1090
1101
|
memcpy(c.chain, l.chain, sizeof c.chain);
|
|
@@ -1098,9 +1109,32 @@ int js_set_prop_slow(JSContext *ctx, JSValue obj, JSValue key, JSValue v, bool s
|
|
|
1098
1109
|
|
|
1099
1110
|
/* ---- Generated code: computed keys, delete, literals --------------------------------- */
|
|
1100
1111
|
|
|
1112
|
+
/* Whether `key` can be a keyed site's: a property key as it is (a symbol, an interned string
|
|
1113
|
+
* that isn't an index), so that the same bits mean the same key. Makes the site its. */
|
|
1114
|
+
static bool take_site_key(JSContext *ctx, JSValue key, JSValue *site, JSPropCache *ic) {
|
|
1115
|
+
if (!js_is_symbol(key) && !(js_is_string(key) && js_is_atom(key))) return false;
|
|
1116
|
+
JSValue k = js_to_property_key(ctx, key); /* a primitive: no user code */
|
|
1117
|
+
if (!js_same_bits(k, key) || js_key_is_index(k)) return false;
|
|
1118
|
+
memset(ic, 0, sizeof *ic); /* its entries were for the old key */
|
|
1119
|
+
*site = key;
|
|
1120
|
+
return true;
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
JSValue js_get_keyed_slow(JSContext *ctx, JSValue obj, JSValue key, JSValue *site, JSPropCache *ic) {
|
|
1124
|
+
if (take_site_key(ctx, key, site, ic)) return js_get_prop(ctx, obj, key, ic);
|
|
1125
|
+
return js_get_elem(ctx, obj, key);
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
int js_set_keyed_slow(JSContext *ctx, JSValue obj, JSValue key, JSValue v, bool strict, JSValue *site, JSPropCache *ic) {
|
|
1129
|
+
if (take_site_key(ctx, key, site, ic)) return js_set_prop(ctx, obj, key, v, strict, ic);
|
|
1130
|
+
return js_set_elem(ctx, obj, key, v, strict);
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1101
1133
|
JSValue js_get_elem(JSContext *ctx, JSValue obj, JSValue key) {
|
|
1102
1134
|
JS_ASSERT_NOT_EXC(obj);
|
|
1103
1135
|
JS_ASSERT_NOT_EXC(key);
|
|
1136
|
+
JSValue elem; /* a typed array's element: the component reads it inline */
|
|
1137
|
+
if (js_is_int32(key) && ctx->rt->typed_array_get && ctx->rt->typed_array_get(obj, js_as_int32(key), &elem)) return elem;
|
|
1104
1138
|
if (js_is_nullish(obj)) {
|
|
1105
1139
|
JSValue k = js_is_object(key) ? key : js_to_property_key(ctx, key); /* primitives only: no user code */
|
|
1106
1140
|
if (js_is_exception(k)) return JS_EXCEPTION;
|
|
@@ -1113,6 +1147,8 @@ JSValue js_get_elem(JSContext *ctx, JSValue obj, JSValue key) {
|
|
|
1113
1147
|
|
|
1114
1148
|
int js_set_elem(JSContext *ctx, JSValue obj, JSValue key, JSValue v, bool strict) {
|
|
1115
1149
|
JS_ASSERT_NOT_EXC(v);
|
|
1150
|
+
/* a Number into a typed array's element: no ToNumber code to run, the component stores it inline */
|
|
1151
|
+
if (js_is_int32(key) && js_is_number(v) && ctx->rt->typed_array_set && ctx->rt->typed_array_set(obj, js_as_int32(key), js_as_number(v))) return 1;
|
|
1116
1152
|
if (js_is_nullish(obj)) {
|
|
1117
1153
|
JSValue k = js_is_object(key) ? js_empty_string() : js_to_property_key(ctx, key);
|
|
1118
1154
|
if (js_is_exception(k)) return -1;
|