Compare commits

..

3 Commits

4 changed files with 601 additions and 24 deletions

2
TODO
View File

@ -62,5 +62,5 @@ Optimization ideas:
Test262o: 0/11262 errors, 463 excluded Test262o: 0/11262 errors, 463 excluded
Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch) Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch)
Result: 54/79414 errors, 1637 excluded, 6821 skipped Result: 54/79801 errors, 1630 excluded, 6631 skipped
Test262 commit: e7e136756cd67c1ffcf7c09d03aeb8ad5a6cec0c Test262 commit: e7e136756cd67c1ffcf7c09d03aeb8ad5a6cec0c

View File

@ -78,6 +78,8 @@ DEF(await, "await")
/* empty string */ /* empty string */
DEF(empty_string, "") DEF(empty_string, "")
/* identifiers */ /* identifiers */
DEF(keys, "keys")
DEF(size, "size")
DEF(length, "length") DEF(length, "length")
DEF(fileName, "fileName") DEF(fileName, "fileName")
DEF(lineNumber, "lineNumber") DEF(lineNumber, "lineNumber")

612
quickjs.c
View File

@ -48549,7 +48549,7 @@ static JSValue js_map_constructor(JSContext *ctx, JSValueConst new_target,
} }
/* XXX: could normalize strings to speed up comparison */ /* XXX: could normalize strings to speed up comparison */
static JSValueConst map_normalize_key(JSContext *ctx, JSValueConst key) static JSValue map_normalize_key(JSContext *ctx, JSValue key)
{ {
uint32_t tag = JS_VALUE_GET_TAG(key); uint32_t tag = JS_VALUE_GET_TAG(key);
/* convert -0.0 to +0.0 */ /* convert -0.0 to +0.0 */
@ -48559,6 +48559,11 @@ static JSValueConst map_normalize_key(JSContext *ctx, JSValueConst key)
return key; return key;
} }
static JSValueConst map_normalize_key_const(JSContext *ctx, JSValueConst key)
{
return (JSValueConst)map_normalize_key(ctx, (JSValue)key);
}
/* hash multipliers, same as the Linux kernel (see Knuth vol 3, /* hash multipliers, same as the Linux kernel (see Knuth vol 3,
section 6.4, exercise 9) */ section 6.4, exercise 9) */
#define HASH_MUL32 0x61C88647 #define HASH_MUL32 0x61C88647
@ -48718,8 +48723,19 @@ static JSMapRecord *map_add_record(JSContext *ctx, JSMapState *s,
return mr; return mr;
} }
static JSMapRecord *set_add_record(JSContext *ctx, JSMapState *s,
JSValueConst key)
{
JSMapRecord *mr;
mr = map_add_record(ctx, s, key);
if (!mr)
return NULL;
mr->value = JS_UNDEFINED;
return mr;
}
/* warning: the record must be removed from the hash table before */ /* warning: the record must be removed from the hash table before */
static void map_delete_record(JSRuntime *rt, JSMapState *s, JSMapRecord *mr) static void map_delete_record_internal(JSRuntime *rt, JSMapState *s, JSMapRecord *mr)
{ {
if (mr->empty) if (mr->empty)
return; return;
@ -48779,7 +48795,7 @@ static void map_delete_weakrefs(JSRuntime *rt, JSWeakRefHeader *wh)
/* remove from the hash table */ /* remove from the hash table */
*pmr = mr1->hash_next; *pmr = mr1->hash_next;
done: done:
map_delete_record(rt, s, mr); map_delete_record_internal(rt, s, mr);
} }
} }
} }
@ -48793,7 +48809,7 @@ static JSValue js_map_set(JSContext *ctx, JSValueConst this_val,
if (!s) if (!s)
return JS_EXCEPTION; return JS_EXCEPTION;
key = map_normalize_key(ctx, argv[0]); key = map_normalize_key_const(ctx, argv[0]);
if (s->is_weak && !js_weakref_is_target(key)) if (s->is_weak && !js_weakref_is_target(key))
return JS_ThrowTypeError(ctx, "invalid value used as %s key", (magic & MAGIC_SET) ? "WeakSet" : "WeakMap"); return JS_ThrowTypeError(ctx, "invalid value used as %s key", (magic & MAGIC_SET) ? "WeakSet" : "WeakMap");
if (magic & MAGIC_SET) if (magic & MAGIC_SET)
@ -48821,7 +48837,7 @@ static JSValue js_map_get(JSContext *ctx, JSValueConst this_val,
if (!s) if (!s)
return JS_EXCEPTION; return JS_EXCEPTION;
key = map_normalize_key(ctx, argv[0]); key = map_normalize_key_const(ctx, argv[0]);
mr = map_find_record(ctx, s, key); mr = map_find_record(ctx, s, key);
if (!mr) if (!mr)
return JS_UNDEFINED; return JS_UNDEFINED;
@ -48838,22 +48854,18 @@ static JSValue js_map_has(JSContext *ctx, JSValueConst this_val,
if (!s) if (!s)
return JS_EXCEPTION; return JS_EXCEPTION;
key = map_normalize_key(ctx, argv[0]); key = map_normalize_key_const(ctx, argv[0]);
mr = map_find_record(ctx, s, key); mr = map_find_record(ctx, s, key);
return JS_NewBool(ctx, mr != NULL); return JS_NewBool(ctx, mr != NULL);
} }
static JSValue js_map_delete(JSContext *ctx, JSValueConst this_val, /* return JS_TRUE or JS_FALSE */
int argc, JSValueConst *argv, int magic) static JSValue map_delete_record(JSContext *ctx, JSMapState *s, JSValueConst key)
{ {
JSMapState *s = JS_GetOpaque2(ctx, this_val, JS_CLASS_MAP + magic);
JSMapRecord *mr, **pmr; JSMapRecord *mr, **pmr;
JSValueConst key;
uint32_t h; uint32_t h;
if (!s) key = map_normalize_key_const(ctx, key);
return JS_EXCEPTION;
key = map_normalize_key(ctx, argv[0]);
h = map_hash_key(key, s->hash_bits); h = map_hash_key(key, s->hash_bits);
pmr = &s->hash_table[h]; pmr = &s->hash_table[h];
@ -48873,10 +48885,19 @@ static JSValue js_map_delete(JSContext *ctx, JSValueConst this_val,
/* remove from the hash table */ /* remove from the hash table */
*pmr = mr->hash_next; *pmr = mr->hash_next;
map_delete_record(ctx->rt, s, mr); map_delete_record_internal(ctx->rt, s, mr);
return JS_TRUE; return JS_TRUE;
} }
static JSValue js_map_delete(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv, int magic)
{
JSMapState *s = JS_GetOpaque2(ctx, this_val, JS_CLASS_MAP + magic);
if (!s)
return JS_EXCEPTION;
return map_delete_record(ctx, s, argv[0]);
}
static JSValue js_map_clear(JSContext *ctx, JSValueConst this_val, static JSValue js_map_clear(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv, int magic) int argc, JSValueConst *argv, int magic)
{ {
@ -48892,7 +48913,7 @@ static JSValue js_map_clear(JSContext *ctx, JSValueConst this_val,
list_for_each_safe(el, el1, &s->records) { list_for_each_safe(el, el1, &s->records) {
mr = list_entry(el, JSMapRecord, link); mr = list_entry(el, JSMapRecord, link);
map_delete_record(ctx->rt, s, mr); map_delete_record_internal(ctx->rt, s, mr);
} }
return JS_UNDEFINED; return JS_UNDEFINED;
} }
@ -49252,6 +49273,560 @@ static JSValue js_map_iterator_next(JSContext *ctx, JSValueConst this_val,
} }
} }
static int get_set_record(JSContext *ctx, JSValueConst obj,
int64_t *psize, JSValue *phas, JSValue *pkeys)
{
JSMapState *s;
int64_t size;
JSValue has = JS_UNDEFINED, keys = JS_UNDEFINED;
s = JS_GetOpaque(obj, JS_CLASS_SET);
if (s) {
size = s->record_count;
} else {
JSValue v;
double d;
v = JS_GetProperty(ctx, obj, JS_ATOM_size);
if (JS_IsException(v))
goto exception;
if (JS_ToFloat64Free(ctx, &d, v) < 0)
goto exception;
if (isnan(d)) {
JS_ThrowTypeError(ctx, ".size is not a number");
goto exception;
}
if (d < INT64_MIN)
size = INT64_MIN;
else if (d >= 0x1p63) /* must use INT64_MAX + 1 because INT64_MAX cannot be exactly represented as a double */
size = INT64_MAX;
else
size = (int64_t)d;
if (size < 0) {
JS_ThrowRangeError(ctx, ".size must be positive");
goto exception;
}
}
has = JS_GetProperty(ctx, obj, JS_ATOM_has);
if (JS_IsException(has))
goto exception;
if (JS_IsUndefined(has)) {
JS_ThrowTypeError(ctx, ".has is undefined");
goto exception;
}
if (!JS_IsFunction(ctx, has)) {
JS_ThrowTypeError(ctx, ".has is not a function");
goto exception;
}
keys = JS_GetProperty(ctx, obj, JS_ATOM_keys);
if (JS_IsException(keys))
goto exception;
if (JS_IsUndefined(keys)) {
JS_ThrowTypeError(ctx, ".keys is undefined");
goto exception;
}
if (!JS_IsFunction(ctx, keys)) {
JS_ThrowTypeError(ctx, ".keys is not a function");
goto exception;
}
*psize = size;
*phas = has;
*pkeys = keys;
return 0;
exception:
JS_FreeValue(ctx, has);
JS_FreeValue(ctx, keys);
*psize = 0;
*phas = JS_UNDEFINED;
*pkeys = JS_UNDEFINED;
return -1;
}
/* copy 'this_val' in a new set without side effects */
static JSValue js_copy_set(JSContext *ctx, JSValueConst this_val)
{
JSValue newset;
JSMapState *s, *t;
struct list_head *el;
JSMapRecord *mr;
s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET);
if (!s)
return JS_EXCEPTION;
newset = js_map_constructor(ctx, JS_UNDEFINED, 0, NULL, MAGIC_SET);
if (JS_IsException(newset))
return JS_EXCEPTION;
t = JS_GetOpaque(newset, JS_CLASS_SET);
// can't clone this_val using js_map_constructor(),
// test262 mandates we don't call the .add method
list_for_each(el, &s->records) {
mr = list_entry(el, JSMapRecord, link);
if (mr->empty)
continue;
if (!set_add_record(ctx, t, mr->key))
goto exception;
}
return newset;
exception:
JS_FreeValue(ctx, newset);
return JS_EXCEPTION;
}
static JSValue js_set_isDisjointFrom(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
JSValue item, iter, keys, has, next, rv, rval;
int done;
BOOL found;
JSMapState *s;
int64_t size;
int ok;
iter = JS_UNDEFINED;
next = JS_UNDEFINED;
rval = JS_EXCEPTION;
s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET);
if (!s)
return JS_EXCEPTION;
if (get_set_record(ctx, argv[0], &size, &has, &keys) < 0)
goto exception;
if (s->record_count <= size) {
iter = js_create_map_iterator(ctx, this_val, 0, NULL, MAGIC_SET);
if (JS_IsException(iter))
goto exception;
found = FALSE;
do {
item = js_map_iterator_next(ctx, iter, 0, NULL, &done, MAGIC_SET);
if (JS_IsException(item))
goto exception;
if (done) // item is JS_UNDEFINED
break;
rv = JS_Call(ctx, has, argv[0], 1, (JSValueConst *)&item);
JS_FreeValue(ctx, item);
ok = JS_ToBoolFree(ctx, rv); // returns -1 if rv is JS_EXCEPTION
if (ok < 0)
goto exception;
found = (ok > 0);
} while (!found);
} else {
iter = JS_Call(ctx, keys, argv[0], 0, NULL);
if (JS_IsException(iter))
goto exception;
next = JS_GetProperty(ctx, iter, JS_ATOM_next);
if (JS_IsException(next))
goto exception;
found = FALSE;
for(;;) {
item = JS_IteratorNext(ctx, iter, next, 0, NULL, &done);
if (JS_IsException(item))
goto exception;
if (done) // item is JS_UNDEFINED
break;
item = map_normalize_key(ctx, item);
found = (NULL != map_find_record(ctx, s, item));
JS_FreeValue(ctx, item);
if (found) {
JS_IteratorClose(ctx, iter, FALSE);
break;
}
}
}
rval = !found ? JS_TRUE : JS_FALSE;
exception:
JS_FreeValue(ctx, has);
JS_FreeValue(ctx, keys);
JS_FreeValue(ctx, iter);
JS_FreeValue(ctx, next);
return rval;
}
static JSValue js_set_isSubsetOf(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
JSValue item, iter, keys, has, next, rv, rval;
BOOL found;
JSMapState *s;
int64_t size;
int done, ok;
iter = JS_UNDEFINED;
next = JS_UNDEFINED;
rval = JS_EXCEPTION;
s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET);
if (!s)
return JS_EXCEPTION;
if (get_set_record(ctx, argv[0], &size, &has, &keys) < 0)
goto exception;
found = FALSE;
if (s->record_count > size)
goto fini;
iter = js_create_map_iterator(ctx, this_val, 0, NULL, MAGIC_SET);
if (JS_IsException(iter))
goto exception;
found = TRUE;
do {
item = js_map_iterator_next(ctx, iter, 0, NULL, &done, MAGIC_SET);
if (JS_IsException(item))
goto exception;
if (done) // item is JS_UNDEFINED
break;
rv = JS_Call(ctx, has, argv[0], 1, (JSValueConst *)&item);
JS_FreeValue(ctx, item);
ok = JS_ToBoolFree(ctx, rv); // returns -1 if rv is JS_EXCEPTION
if (ok < 0)
goto exception;
found = (ok > 0);
} while (found);
fini:
rval = found ? JS_TRUE : JS_FALSE;
exception:
JS_FreeValue(ctx, has);
JS_FreeValue(ctx, keys);
JS_FreeValue(ctx, iter);
JS_FreeValue(ctx, next);
return rval;
}
static JSValue js_set_isSupersetOf(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
JSValue item, iter, keys, has, next, rval;
int done;
BOOL found;
JSMapState *s;
int64_t size;
iter = JS_UNDEFINED;
next = JS_UNDEFINED;
rval = JS_EXCEPTION;
s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET);
if (!s)
return JS_EXCEPTION;
if (get_set_record(ctx, argv[0], &size, &has, &keys) < 0)
goto exception;
found = FALSE;
if (s->record_count < size)
goto fini;
iter = JS_Call(ctx, keys, argv[0], 0, NULL);
if (JS_IsException(iter))
goto exception;
next = JS_GetProperty(ctx, iter, JS_ATOM_next);
if (JS_IsException(next))
goto exception;
found = TRUE;
for(;;) {
item = JS_IteratorNext(ctx, iter, next, 0, NULL, &done);
if (JS_IsException(item))
goto exception;
if (done) // item is JS_UNDEFINED
break;
item = map_normalize_key(ctx, item);
found = (NULL != map_find_record(ctx, s, item));
JS_FreeValue(ctx, item);
if (!found) {
JS_IteratorClose(ctx, iter, FALSE);
break;
}
}
fini:
rval = found ? JS_TRUE : JS_FALSE;
exception:
JS_FreeValue(ctx, has);
JS_FreeValue(ctx, keys);
JS_FreeValue(ctx, iter);
JS_FreeValue(ctx, next);
return rval;
}
static JSValue js_set_intersection(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
JSValue newset, item, iter, keys, has, next, rv;
JSMapState *s, *t;
JSMapRecord *mr;
int64_t size;
int done, ok;
iter = JS_UNDEFINED;
next = JS_UNDEFINED;
newset = JS_UNDEFINED;
s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET);
if (!s)
return JS_EXCEPTION;
if (get_set_record(ctx, argv[0], &size, &has, &keys) < 0)
goto exception;
if (s->record_count > size) {
iter = JS_Call(ctx, keys, argv[0], 0, NULL);
if (JS_IsException(iter))
goto exception;
next = JS_GetProperty(ctx, iter, JS_ATOM_next);
if (JS_IsException(next))
goto exception;
newset = js_map_constructor(ctx, JS_UNDEFINED, 0, NULL, MAGIC_SET);
if (JS_IsException(newset))
goto exception;
t = JS_GetOpaque(newset, JS_CLASS_SET);
for (;;) {
item = JS_IteratorNext(ctx, iter, next, 0, NULL, &done);
if (JS_IsException(item))
goto exception;
if (done) // item is JS_UNDEFINED
break;
item = map_normalize_key(ctx, item);
if (!map_find_record(ctx, s, item)) {
JS_FreeValue(ctx, item);
} else if (map_find_record(ctx, t, item)) {
JS_FreeValue(ctx, item); // no duplicates
} else {
mr = set_add_record(ctx, t, item);
JS_FreeValue(ctx, item);
if (!mr)
goto exception;
}
}
} else {
iter = js_create_map_iterator(ctx, this_val, 0, NULL, MAGIC_SET);
if (JS_IsException(iter))
goto exception;
newset = js_map_constructor(ctx, JS_UNDEFINED, 0, NULL, MAGIC_SET);
if (JS_IsException(newset))
goto exception;
t = JS_GetOpaque(newset, JS_CLASS_SET);
for (;;) {
item = js_map_iterator_next(ctx, iter, 0, NULL, &done, MAGIC_SET);
if (JS_IsException(item))
goto exception;
if (done) // item is JS_UNDEFINED
break;
rv = JS_Call(ctx, has, argv[0], 1, (JSValueConst *)&item);
ok = JS_ToBoolFree(ctx, rv); // returns -1 if rv is JS_EXCEPTION
if (ok > 0) {
item = map_normalize_key(ctx, item);
if (map_find_record(ctx, t, item)) {
JS_FreeValue(ctx, item); // no duplicates
} else {
mr = set_add_record(ctx, t, item);
JS_FreeValue(ctx, item);
if (!mr)
goto exception;
}
} else {
JS_FreeValue(ctx, item);
if (ok < 0)
goto exception;
}
}
}
goto fini;
exception:
JS_FreeValue(ctx, newset);
newset = JS_EXCEPTION;
fini:
JS_FreeValue(ctx, has);
JS_FreeValue(ctx, keys);
JS_FreeValue(ctx, iter);
JS_FreeValue(ctx, next);
return newset;
}
static JSValue js_set_difference(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
JSValue newset, item, iter, keys, has, next, rv;
JSMapState *s, *t;
int64_t size;
int done;
int ok;
iter = JS_UNDEFINED;
next = JS_UNDEFINED;
newset = JS_UNDEFINED;
s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET);
if (!s)
return JS_EXCEPTION;
if (get_set_record(ctx, argv[0], &size, &has, &keys) < 0)
goto exception;
newset = js_copy_set(ctx, this_val);
if (JS_IsException(newset))
goto exception;
t = JS_GetOpaque(newset, JS_CLASS_SET);
if (s->record_count <= size) {
iter = js_create_map_iterator(ctx, newset, 0, NULL, MAGIC_SET);
if (JS_IsException(iter))
goto exception;
for (;;) {
item = js_map_iterator_next(ctx, iter, 0, NULL, &done, MAGIC_SET);
if (JS_IsException(item))
goto exception;
if (done) // item is JS_UNDEFINED
break;
rv = JS_Call(ctx, has, argv[0], 1, (JSValueConst *)&item);
ok = JS_ToBoolFree(ctx, rv); // returns -1 if rv is JS_EXCEPTION
if (ok < 0) {
JS_FreeValue(ctx, item);
goto exception;
}
if (ok) {
map_delete_record(ctx, t, item);
}
JS_FreeValue(ctx, item);
}
} else {
iter = JS_Call(ctx, keys, argv[0], 0, NULL);
if (JS_IsException(iter))
goto exception;
next = JS_GetProperty(ctx, iter, JS_ATOM_next);
if (JS_IsException(next))
goto exception;
for (;;) {
item = JS_IteratorNext(ctx, iter, next, 0, NULL, &done);
if (JS_IsException(item))
goto exception;
if (done) // item is JS_UNDEFINED
break;
map_delete_record(ctx, t, item);
JS_FreeValue(ctx, item);
}
}
goto fini;
exception:
JS_FreeValue(ctx, newset);
newset = JS_EXCEPTION;
fini:
JS_FreeValue(ctx, has);
JS_FreeValue(ctx, keys);
JS_FreeValue(ctx, iter);
JS_FreeValue(ctx, next);
return newset;
}
static JSValue js_set_symmetricDifference(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
JSValue newset, item, iter, next, has, keys;
JSMapState *s, *t;
JSMapRecord *mr;
int64_t size;
int done;
BOOL present;
s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET);
if (!s)
return JS_EXCEPTION;
if (get_set_record(ctx, argv[0], &size, &has, &keys) < 0)
return JS_EXCEPTION;
JS_FreeValue(ctx, has);
next = JS_UNDEFINED;
newset = JS_UNDEFINED;
iter = JS_Call(ctx, keys, argv[0], 0, NULL);
if (JS_IsException(iter))
goto exception;
next = JS_GetProperty(ctx, iter, JS_ATOM_next);
if (JS_IsException(next))
goto exception;
newset = js_copy_set(ctx, this_val);
if (JS_IsException(newset))
goto exception;
t = JS_GetOpaque(newset, JS_CLASS_SET);
for (;;) {
item = JS_IteratorNext(ctx, iter, next, 0, NULL, &done);
if (JS_IsException(item))
goto exception;
if (done) // item is JS_UNDEFINED
break;
// note the subtlety here: due to mutating iterators, it's
// possible for keys to disappear during iteration; test262
// still expects us to maintain insertion order though, so
// we first check |this|, then |new|; |new| is a copy of |this|
// - if item exists in |this|, delete (if it exists) from |new|
// - if item misses in |this| and |new|, add to |new|
// - if item exists in |new| but misses in |this|, *don't* add it,
// mutating iterator erased it
item = map_normalize_key(ctx, item);
present = (NULL != map_find_record(ctx, s, item));
mr = map_find_record(ctx, t, item);
if (present) {
map_delete_record(ctx, t, item);
JS_FreeValue(ctx, item);
} else if (mr) {
JS_FreeValue(ctx, item);
} else {
mr = set_add_record(ctx, t, item);
JS_FreeValue(ctx, item);
if (!mr)
goto exception;
}
}
goto fini;
exception:
JS_FreeValue(ctx, newset);
newset = JS_EXCEPTION;
fini:
JS_FreeValue(ctx, next);
JS_FreeValue(ctx, iter);
JS_FreeValue(ctx, keys);
return newset;
}
static JSValue js_set_union(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
JSValue newset, item, iter, next, has, keys, rv;
JSMapState *s;
int64_t size;
int done;
s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET);
if (!s)
return JS_EXCEPTION;
if (get_set_record(ctx, argv[0], &size, &has, &keys) < 0)
return JS_EXCEPTION;
JS_FreeValue(ctx, has);
next = JS_UNDEFINED;
newset = JS_UNDEFINED;
iter = JS_Call(ctx, keys, argv[0], 0, NULL);
if (JS_IsException(iter))
goto exception;
next = JS_GetProperty(ctx, iter, JS_ATOM_next);
if (JS_IsException(next))
goto exception;
newset = js_copy_set(ctx, this_val);
if (JS_IsException(newset))
goto exception;
for (;;) {
item = JS_IteratorNext(ctx, iter, next, 0, NULL, &done);
if (JS_IsException(item))
goto exception;
if (done) // item is JS_UNDEFINED
break;
rv = js_map_set(ctx, newset, 1, (JSValueConst *)&item, MAGIC_SET);
JS_FreeValue(ctx, item);
if (JS_IsException(rv))
goto exception;
JS_FreeValue(ctx, rv);
}
goto fini;
exception:
JS_FreeValue(ctx, newset);
newset = JS_EXCEPTION;
fini:
JS_FreeValue(ctx, next);
JS_FreeValue(ctx, iter);
JS_FreeValue(ctx, keys);
return newset;
}
static const JSCFunctionListEntry js_map_funcs[] = { static const JSCFunctionListEntry js_map_funcs[] = {
JS_CFUNC_MAGIC_DEF("groupBy", 2, js_object_groupBy, 1 ), JS_CFUNC_MAGIC_DEF("groupBy", 2, js_object_groupBy, 1 ),
JS_CGETSET_DEF("[Symbol.species]", js_get_this, NULL ), JS_CGETSET_DEF("[Symbol.species]", js_get_this, NULL ),
@ -49284,6 +49859,13 @@ static const JSCFunctionListEntry js_set_proto_funcs[] = {
JS_CFUNC_MAGIC_DEF("clear", 0, js_map_clear, MAGIC_SET ), JS_CFUNC_MAGIC_DEF("clear", 0, js_map_clear, MAGIC_SET ),
JS_CGETSET_MAGIC_DEF("size", js_map_get_size, NULL, MAGIC_SET ), JS_CGETSET_MAGIC_DEF("size", js_map_get_size, NULL, MAGIC_SET ),
JS_CFUNC_MAGIC_DEF("forEach", 1, js_map_forEach, MAGIC_SET ), JS_CFUNC_MAGIC_DEF("forEach", 1, js_map_forEach, MAGIC_SET ),
JS_CFUNC_DEF("isDisjointFrom", 1, js_set_isDisjointFrom ),
JS_CFUNC_DEF("isSubsetOf", 1, js_set_isSubsetOf ),
JS_CFUNC_DEF("isSupersetOf", 1, js_set_isSupersetOf ),
JS_CFUNC_DEF("intersection", 1, js_set_intersection ),
JS_CFUNC_DEF("difference", 1, js_set_difference ),
JS_CFUNC_DEF("symmetricDifference", 1, js_set_symmetricDifference ),
JS_CFUNC_DEF("union", 1, js_set_union ),
JS_CFUNC_MAGIC_DEF("values", 0, js_create_map_iterator, (JS_ITERATOR_KIND_KEY << 2) | MAGIC_SET ), JS_CFUNC_MAGIC_DEF("values", 0, js_create_map_iterator, (JS_ITERATOR_KIND_KEY << 2) | MAGIC_SET ),
JS_ALIAS_DEF("keys", "values" ), JS_ALIAS_DEF("keys", "values" ),
JS_ALIAS_DEF("[Symbol.iterator]", "values" ), JS_ALIAS_DEF("[Symbol.iterator]", "values" ),

View File

@ -183,7 +183,7 @@ RegExp.escape
resizable-arraybuffer=skip resizable-arraybuffer=skip
rest-parameters rest-parameters
Set Set
set-methods=skip set-methods
ShadowRealm=skip ShadowRealm=skip
SharedArrayBuffer SharedArrayBuffer
source-phase-imports-module-source=skip source-phase-imports-module-source=skip
@ -305,13 +305,6 @@ test262/test/built-ins/String/prototype/split/cstm-split-on-string-primitive.js
test262/test/staging/sm/Array/frozen-dense-array.js test262/test/staging/sm/Array/frozen-dense-array.js
# not supported # not supported
test262/test/staging/sm/Set/difference.js
test262/test/staging/sm/Set/intersection.js
test262/test/staging/sm/Set/is-disjoint-from.js
test262/test/staging/sm/Set/is-subset-of.js
test262/test/staging/sm/Set/is-superset-of.js
test262/test/staging/sm/Set/symmetric-difference.js
test262/test/staging/sm/Set/union.js
test262/test/staging/sm/extensions/censor-strict-caller.js test262/test/staging/sm/extensions/censor-strict-caller.js
test262/test/staging/sm/JSON/parse-with-source.js test262/test/staging/sm/JSON/parse-with-source.js