Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 19 additions & 14 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -49502,11 +49502,11 @@ static int JS_WriteSet(BCWriterState *s, struct JSMapState *map_state)
}

static int js_setlike_get_props(JSContext *ctx, JSValueConst setlike,
int64_t *psize, JSValue *phas, JSValue *pkeys)
uint64_t *psize, JSValue *phas, JSValue *pkeys)
{
JSValue has, keys, v;
JSMapState *s;
int64_t size;
uint64_t size;
double d;

keys = JS_UNDEFINED;
Expand All @@ -49524,14 +49524,19 @@ static int js_setlike_get_props(JSContext *ctx, JSValueConst setlike,
}
if (JS_ToFloat64Free(ctx, &d, v) < 0)
return -1;
if (d < 0) {
JS_ThrowRangeError(ctx, ".size is not a legal size");
return -1;
}
if (isnan(d)) {
JS_ThrowTypeError(ctx, ".size is not a number");
JS_ThrowTypeError(ctx, ".size is not a legal size");
return -1;
}
// TODO(bnoordhuis) add precision check, can be double
// that cannot be accurately represented as an int64,
// like Infinity and numbers outside MAX_SAFE_INTEGER
size = d;
if (isinf(d) || d > (double)MAX_SAFE_INTEGER) {
size = UINT64_MAX;
} else {
size = (uint64_t)d; // cast for expository reasons
}
}
has = JS_GetProperty(ctx, setlike, JS_ATOM_has);
if (JS_IsException(has))
Expand Down Expand Up @@ -49565,7 +49570,7 @@ static JSValue js_set_isDisjointFrom(JSContext *ctx, JSValueConst this_val,
int done;
bool found;
JSMapState *s;
int64_t size;
uint64_t size;
int ok;

s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET);
Expand Down Expand Up @@ -49635,7 +49640,7 @@ static JSValue js_set_isSubsetOf(JSContext *ctx, JSValueConst this_val,
JSValueConst setlike;
bool found;
JSMapState *s;
int64_t size;
uint64_t size;
int done, ok;

s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET);
Expand Down Expand Up @@ -49685,7 +49690,7 @@ static JSValue js_set_isSupersetOf(JSContext *ctx, JSValueConst this_val,
int done;
bool found;
JSMapState *s;
int64_t size;
uint64_t size;

s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET);
if (!s)
Expand Down Expand Up @@ -49738,7 +49743,7 @@ static JSValue js_set_intersection(JSContext *ctx, JSValueConst this_val,
JSValueConst setlike;
JSMapState *s, *t;
JSMapRecord *mr;
int64_t size;
uint64_t size;
int done, ok;

s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET);
Expand Down Expand Up @@ -49831,7 +49836,7 @@ static JSValue js_set_difference(JSContext *ctx, JSValueConst this_val,
JSValueConst setlike;
JSMapState *s, *t;
JSMapRecord *mr;
int64_t size;
uint64_t size;
int done;
int ok;

Expand Down Expand Up @@ -49920,7 +49925,7 @@ static JSValue js_set_symmetricDifference(JSContext *ctx, JSValueConst this_val,
struct list_head *el;
JSMapState *s, *t;
JSMapRecord *mr;
int64_t size;
uint64_t size;
int done;
bool present;

Expand Down Expand Up @@ -50005,7 +50010,7 @@ static JSValue js_set_union(JSContext *ctx, JSValueConst this_val,
struct list_head *el;
JSMapState *s, *t;
JSMapRecord *mr;
int64_t size;
uint64_t size;
int done;

iter = JS_UNDEFINED;
Expand Down
45 changes: 37 additions & 8 deletions tests/test_builtin.js
Original file line number Diff line number Diff line change
Expand Up @@ -933,22 +933,51 @@ function test_set()
}
// set must be bigger than iter.a to hit iter.next and iter.return
assert(new Set([4,5,6,7]).isSupersetOf(setlike), true)
assert(iter.nextCalls, 4);
assert(iter.returnCalls, 0);
assert(iter.nextCalls, 4)
assert(iter.returnCalls, 0)
iter.nextCalls = iter.returnCalls = 0
assert(new Set([0,1,2,3]).isSupersetOf(setlike), false)
assert(iter.nextCalls, 1);
assert(iter.returnCalls, 1);
assert(iter.nextCalls, 1)
assert(iter.returnCalls, 1)
iter.nextCalls = iter.returnCalls = 0
// set must be bigger than iter.a to hit iter.next and iter.return
assert(new Set([4,5,6,7]).isDisjointFrom(setlike), false)
assert(iter.nextCalls, 1);
assert(iter.returnCalls, 1);
assert(iter.nextCalls, 1)
assert(iter.returnCalls, 1)
iter.nextCalls = iter.returnCalls = 0
assert(new Set([0,1,2,3]).isDisjointFrom(setlike), true)
assert(iter.nextCalls, 4);
assert(iter.returnCalls, 0);
assert(iter.nextCalls, 4)
assert(iter.returnCalls, 0)
iter.nextCalls = iter.returnCalls = 0
function expectException(klass, sizes) {
for (const size of sizes) {
let ex
try {
new Set([]).union({size})
} catch (e) {
ex = e
}
assert(ex instanceof klass)
assert(typeof ex.message, "string")
assert(ex.message.includes(".size"))
}
}
expectException(RangeError, [-1, -(Number.MAX_SAFE_INTEGER+1), -Infinity])
expectException(TypeError, [NaN])
const legal = [
0, -0, 1, 2,
Number.MAX_SAFE_INTEGER + 1,
Number.MAX_SAFE_INTEGER + 2,
Number.MAX_SAFE_INTEGER + 3,
Infinity
]
for (const size of legal) {
new Set([]).union({
size,
has() { return false },
keys() { return [].values() },
})
}
}

function test_weak_set()
Expand Down
Loading