diff --git a/meson/ant.version b/meson/ant.version index 56e9df1..142464b 100644 --- a/meson/ant.version +++ b/meson/ant.version @@ -1 +1 @@ -0.10.3 \ No newline at end of file +0.11.0 \ No newline at end of file diff --git a/src/ant.c b/src/ant.c index 690c201..00a87a6 100644 --- a/src/ant.c +++ b/src/ant.c @@ -4968,7 +4968,7 @@ static ant_value_t try_exotic_to_primitive(ant_t *js, ant_value_t value, int hin ant_value_t tp_fn = js_get_sym(js, value, tp_sym); uint8_t ft = vtype(tp_fn); - if (ft == T_UNDEF) return mkval(T_UNDEF, 0); + if (ft == T_UNDEF || ft == T_NULL) return mkval(T_UNDEF, 0); if (ft != T_FUNC && ft != T_CFUNC) { return js_mkerr_typed(js, JS_ERR_TYPE, "Symbol.toPrimitive is not a function"); } @@ -5004,7 +5004,7 @@ ant_value_t js_to_primitive(ant_t *js, ant_value_t value, int hint) { ant_value_t tp_sym = get_toPrimitive_sym(); ant_value_t tp_fn = js_get_sym(js, value, tp_sym); if (is_err(tp_fn)) return tp_fn; - if (vtype(tp_fn) == T_UNDEF) + if (vtype(tp_fn) == T_UNDEF || vtype(tp_fn) == T_NULL) return try_ordinary_to_primitive(js, value, hint); if (vtype(tp_fn) != T_FUNC && vtype(tp_fn) != T_CFUNC) return js_mkerr_typed(js, JS_ERR_TYPE, "Symbol.toPrimitive is not a function"); diff --git a/tests/test_toprimitive_null.cjs b/tests/test_toprimitive_null.cjs new file mode 100644 index 0000000..fd46ce8 --- /dev/null +++ b/tests/test_toprimitive_null.cjs @@ -0,0 +1,40 @@ +function assert(condition, message) { + if (!condition) { + console.log("FAIL: " + message); + throw new Error(message); + } +} + +const ordinary = { + [Symbol.toPrimitive]: null, + valueOf() { + return 7; + }, +}; + +const proxied = new Proxy({ + [Symbol.toPrimitive]: null, + valueOf() { + return 9; + }, +}, {}); + +const bad = { + [Symbol.toPrimitive]: 1, + valueOf() { + return 11; + }, +}; + +assert(+ordinary === 7, "ordinary null @@toPrimitive should fall back"); +assert(+proxied === 9, "proxy null @@toPrimitive should fall back"); + +let threw = false; +try { + +bad; +} catch (e) { + threw = e instanceof TypeError; +} + +assert(threw, "non-null non-callable @@toPrimitive should throw"); +console.log("OK");