From aaa208ac8f8e707a6896de2c7d9a767ae31a41fd Mon Sep 17 00:00:00 2001 From: Charlie Gordon Date: Sun, 10 Mar 2024 17:04:06 +0100 Subject: [PATCH] Improve error handling (#297) * Improve error handling - throw RangeError for invalid string length - throw RangeError for stack overflow with updated message - fix case for `BigInt` error messages - refine stack check for `next_token` and `json_next_token` - throw SyntaxError for too many variables, arguments, parameters... - v8.js: disable v8 specific tests - v8.js: disable Realm object tests - v8.js: disable MODULE tests - v8.js: disable RegExp static properties tests - use more precise error messages - reorder property lookup in `js_obj_to_desc()` according to ECMA - set global object's [Symbol.toStringTag] to "global" - fix error message for duplicate parameter name in strict mode --- quickjs.c | 137 ++++++++++-------- tests/test_builtin.js | 6 +- v8.js | 7 + v8.txt | 319 +----------------------------------------- 4 files changed, 88 insertions(+), 381 deletions(-) diff --git a/quickjs.c b/quickjs.c index 969a7f8..3cc8175 100644 --- a/quickjs.c +++ b/quickjs.c @@ -3589,7 +3589,7 @@ static no_inline int string_buffer_realloc(StringBuffer *s, int new_len, int c) return -1; if (new_len > JS_STRING_LEN_MAX) { - JS_ThrowInternalError(s->ctx, "string too long"); + JS_ThrowRangeError(s->ctx, "invalid string length"); return string_buffer_set_error(s); } new_size = min_int(max_int(new_len, s->size * 3 / 2), JS_STRING_LEN_MAX); @@ -3859,7 +3859,7 @@ JSValue JS_NewStringLen(JSContext *ctx, const char *buf, size_t buf_len) p++; len1 = p - p_start; if (len1 > JS_STRING_LEN_MAX) - return JS_ThrowInternalError(ctx, "string too long"); + return JS_ThrowRangeError(ctx, "invalid string length"); if (p == p_end) { /* ASCII string */ return js_new_string8(ctx, (const uint8_t *)buf, buf_len); @@ -4154,7 +4154,7 @@ static JSValue JS_ConcatString1(JSContext *ctx, len = p1->len + p2->len; if (len > JS_STRING_LEN_MAX) - return JS_ThrowInternalError(ctx, "string too long"); + return JS_ThrowRangeError(ctx, "invalid string length"); is_wide_char = p1->is_wide_char | p2->is_wide_char; p = js_alloc_string(ctx, len, is_wide_char); if (!p) @@ -6758,7 +6758,7 @@ JSValue JS_ThrowOutOfMemory(JSContext *ctx) static JSValue JS_ThrowStackOverflow(JSContext *ctx) { - return JS_ThrowInternalError(ctx, "stack overflow"); + return JS_ThrowRangeError(ctx, "Maximum call stack size exceeded"); } static JSValue JS_ThrowTypeErrorNotAnObject(JSContext *ctx) @@ -6774,7 +6774,7 @@ static JSValue JS_ThrowTypeErrorNotASymbol(JSContext *ctx) static JSValue JS_ThrowReferenceErrorNotDefined(JSContext *ctx, JSAtom name) { char buf[ATOM_GET_STR_BUF_SIZE]; - return JS_ThrowReferenceError(ctx, "'%s' is not defined", + return JS_ThrowReferenceError(ctx, "%s is not defined", JS_AtomGetStr(ctx, buf, sizeof(buf), name)); } @@ -10332,7 +10332,7 @@ static JSValue JS_ToNumberHintFree(JSContext *ctx, JSValue val, case JS_TAG_BIG_INT: if (flag != TON_FLAG_NUMERIC) { JS_FreeValue(ctx, val); - return JS_ThrowTypeError(ctx, "cannot convert bigint to number"); + return JS_ThrowTypeError(ctx, "cannot convert BigInt to number"); } ret = val; break; @@ -11870,7 +11870,7 @@ static JSValue JS_StringToBigIntErr(JSContext *ctx, JSValue val) { val = JS_StringToBigInt(ctx, val); if (JS_VALUE_IS_NAN(val)) - return JS_ThrowSyntaxError(ctx, "invalid bigint literal"); + return JS_ThrowSyntaxError(ctx, "invalid BigInt literal"); return val; } @@ -11912,7 +11912,7 @@ static bf_t *JS_ToBigIntFree(JSContext *ctx, bf_t *buf, JSValue val) default: fail: JS_FreeValue(ctx, val); - JS_ThrowTypeError(ctx, "cannot convert to bigint"); + JS_ThrowTypeError(ctx, "cannot convert to BigInt"); return NULL; } return r; @@ -12037,7 +12037,7 @@ static int js_unary_arith_bigint(JSContext *ctx, JSValue res; if (op == OP_plus) { - JS_ThrowTypeError(ctx, "bigint argument with unary +"); + JS_ThrowTypeError(ctx, "BigInt argument with unary +"); JS_FreeValue(ctx, op1); return -1; } @@ -12515,7 +12515,7 @@ static no_inline __exception int js_binary_logic_slow(JSContext *ctx, if (tag1 != tag2) { JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); - JS_ThrowTypeError(ctx, "both operands must be bigint"); + JS_ThrowTypeError(ctx, "both operands must be BigInt"); goto exception; } else if (js_binary_arith_bigint(ctx, op, sp - 2, op1, op2)) { goto exception; @@ -12873,7 +12873,7 @@ static no_inline int js_shr_slow(JSContext *ctx, JSValue *sp) if ((JS_VALUE_GET_TAG(op1) == JS_TAG_BIG_INT || JS_VALUE_GET_TAG(op2) == JS_TAG_BIG_INT)) { - JS_ThrowTypeError(ctx, "bigint operands are forbidden for >>>"); + JS_ThrowTypeError(ctx, "BigInt operands are forbidden for >>>"); JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); goto exception; @@ -18968,8 +18968,9 @@ static __exception int next_token(JSParseState *s) BOOL ident_has_escape; JSAtom atom; - if (js_check_stack_overflow(s->ctx->rt, 0)) { - return js_parse_error(s, "stack overflow"); + if (js_check_stack_overflow(s->ctx->rt, 1000)) { + JS_ThrowStackOverflow(s->ctx); + return -1; } free_token(s, &s->token); @@ -19488,8 +19489,9 @@ static __exception int json_next_token(JSParseState *s) int c; JSAtom atom; - if (js_check_stack_overflow(s->ctx->rt, 0)) { - return js_parse_error(s, "stack overflow"); + if (js_check_stack_overflow(s->ctx->rt, 1000)) { + JS_ThrowStackOverflow(s->ctx); + return -1; } free_token(s, &s->token); @@ -20068,7 +20070,9 @@ static int add_var(JSContext *ctx, JSFunctionDef *fd, JSAtom name) /* the local variable indexes are currently stored on 16 bits */ if (fd->var_count >= JS_MAX_LOCAL_VARS) { - JS_ThrowInternalError(ctx, "too many local variables"); + // XXX: add_var() should take JSParseState *s and use js_parse_error + JS_ThrowSyntaxError(ctx, "too many variables declared (only %d allowed)", + JS_MAX_LOCAL_VARS - 1); return -1; } if (js_resize_array(ctx, (void **)&fd->vars, sizeof(fd->vars[0]), @@ -20148,7 +20152,9 @@ static int add_arg(JSContext *ctx, JSFunctionDef *fd, JSAtom name) /* the local variable indexes are currently stored on 16 bits */ if (fd->arg_count >= JS_MAX_LOCAL_VARS) { - JS_ThrowInternalError(ctx, "too many arguments"); + // XXX: add_arg() should take JSParseState *s and use js_parse_error + JS_ThrowSyntaxError(ctx, "too many parameters in function definition (only %d allowed)", + JS_MAX_LOCAL_VARS - 1); return -1; } if (js_resize_array(ctx, (void **)&fd->args, sizeof(fd->args[0]), @@ -22171,7 +22177,7 @@ static int js_parse_check_duplicate_parameter(JSParseState *s, JSAtom name) return 0; duplicate: - return js_parse_error(s, "duplicate parameter names not allowed in this context"); + return js_parse_error(s, "Duplicate parameter name not allowed in this context"); } static JSAtom js_parse_destructuring_var(JSParseState *s, int tok, int is_arg) @@ -23049,7 +23055,8 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) arg_count = 0; while (s->token.val != ')') { if (arg_count >= 65535) { - return js_parse_error(s, "Too many call arguments"); + return js_parse_error(s, "Too many arguments in function call (only %d allowed)", + 65535 - 1); } if (s->token.val == TOK_ELLIPSIS) break; @@ -23421,10 +23428,8 @@ static __exception int js_parse_unary(JSParseState *s, int parse_flags) regarding the precedence of prefix operators and the postifx exponential, ES7 specifies that -2**2 is a syntax error. */ - if (parse_flags & PF_POW_FORBIDDEN) { - JS_ThrowSyntaxError(s->ctx, "unparenthesized unary expression can't appear on the left-hand side of '**'"); - return -1; - } + if (parse_flags & PF_POW_FORBIDDEN) + return js_parse_error(s, "unparenthesized unary expression can't appear on the left-hand side of '**'"); if (next_token(s)) return -1; if (js_parse_unary(s, PF_POW_ALLOWED)) @@ -27683,7 +27688,9 @@ static int add_closure_var(JSContext *ctx, JSFunctionDef *s, /* the closure variable indexes are currently stored on 16 bits */ if (s->closure_var_count >= JS_MAX_LOCAL_VARS) { - JS_ThrowInternalError(ctx, "too many closure variables"); + // XXX: add_closure_var() should take JSParseState *s and use js_parse_error + JS_ThrowSyntaxError(ctx, "too many closure variables used (only %d allowed)", + JS_MAX_LOCAL_VARS - 1); return -1; } @@ -28468,6 +28475,7 @@ static int resolve_scope_private_field1(JSContext *ctx, } } /* XXX: no line number info */ + // XXX: resolve_scope_private_field1() should take JSParseState *s and use js_parse_error_atom JS_ThrowSyntaxErrorAtom(ctx, "undefined private field '%s'", var_name); return -1; @@ -30886,6 +30894,7 @@ static int add_module_variables(JSContext *ctx, JSFunctionDef *fd) if (me->export_type == JS_EXPORT_TYPE_LOCAL) { idx = find_closure_var(ctx, fd, me->local_name); if (idx < 0) { + // XXX: add_module_variables() should take JSParseState *s and use js_parse_error_atom JS_ThrowSyntaxErrorAtom(ctx, "exported variable '%s' does not exist", me->local_name); return -1; @@ -31269,7 +31278,7 @@ static int js_parse_function_check_names(JSParseState *s, JSFunctionDef *fd, return 0; duplicate: - return js_parse_error(s, "duplicate argument names not allowed in this context"); + return js_parse_error(s, "Duplicate parameter name not allowed in this context"); } /* create a function to initialize class fields */ @@ -31553,6 +31562,8 @@ static __exception int js_parse_function_decl2(JSParseState *s, goto fail; } if (fd->has_parameter_expressions) { + if (js_parse_check_duplicate_parameter(s, name)) + goto fail; if (define_var(s, fd, name, JS_VAR_DEF_LET) < 0) goto fail; } @@ -32330,7 +32341,7 @@ static const char * const bc_tag_str[] = { "string", "object", "array", - "bigint", + "BigInt", "template", "function", "module", @@ -32591,7 +32602,7 @@ static int JS_WriteBigInt(BCWriterState *s, JSValue obj) e = a->expn; e = (e * 2) | a->sign; if (e < INT32_MIN || e > INT32_MAX) { - JS_ThrowInternalError(s->ctx, "bigint exponent is too large"); + JS_ThrowRangeError(s->ctx, "maximum BigInt size exceeded"); return -1; } bc_put_sleb128(s, e); @@ -32611,7 +32622,7 @@ static int JS_WriteBigInt(BCWriterState *s, JSValue obj) i++; len = (a->len - i) * sizeof(limb_t) + n1; if (len > INT32_MAX) { - JS_ThrowInternalError(s->ctx, "bigint is too large"); + JS_ThrowRangeError(s->ctx, "maximum BigInt size exceeded"); return -1; } bc_put_leb128(s, len); @@ -33469,7 +33480,7 @@ static JSValue JS_ReadBigInt(BCReaderState *s) goto fail; bc_read_trace(s, "len=%" PRId64 "\n", (int64_t)len); if (len == 0) { - JS_ThrowInternalError(s->ctx, "invalid bigint length"); + JS_ThrowRangeError(s->ctx, "maximum BigInt size exceeded"); goto fail; } l = (len + sizeof(limb_t) - 1) / sizeof(limb_t); @@ -34620,7 +34631,7 @@ static JSValue JS_ToObject(JSContext *ctx, JSValue val) default: case JS_TAG_NULL: case JS_TAG_UNDEFINED: - return JS_ThrowTypeError(ctx, "cannot convert to object"); + return JS_ThrowTypeError(ctx, "Cannot convert undefined or null to object"); case JS_TAG_OBJECT: case JS_TAG_EXCEPTION: return js_dup(val); @@ -34665,13 +34676,21 @@ static int js_obj_to_desc(JSContext *ctx, JSPropertyDescriptor *d, int flags; if (!JS_IsObject(desc)) { - JS_ThrowTypeErrorNotAnObject(ctx); + JS_ThrowTypeError(ctx, "Property description must be an object"); return -1; } flags = 0; val = JS_UNDEFINED; getter = JS_UNDEFINED; setter = JS_UNDEFINED; + if (JS_HasProperty(ctx, desc, JS_ATOM_enumerable)) { + JSValue prop = JS_GetProperty(ctx, desc, JS_ATOM_enumerable); + if (JS_IsException(prop)) + goto fail; + flags |= JS_PROP_HAS_ENUMERABLE; + if (JS_ToBoolFree(ctx, prop)) + flags |= JS_PROP_ENUMERABLE; + } if (JS_HasProperty(ctx, desc, JS_ATOM_configurable)) { JSValue prop = JS_GetProperty(ctx, desc, JS_ATOM_configurable); if (JS_IsException(prop)) @@ -34680,6 +34699,12 @@ static int js_obj_to_desc(JSContext *ctx, JSPropertyDescriptor *d, if (JS_ToBoolFree(ctx, prop)) flags |= JS_PROP_CONFIGURABLE; } + if (JS_HasProperty(ctx, desc, JS_ATOM_value)) { + flags |= JS_PROP_HAS_VALUE; + val = JS_GetProperty(ctx, desc, JS_ATOM_value); + if (JS_IsException(val)) + goto fail; + } if (JS_HasProperty(ctx, desc, JS_ATOM_writable)) { JSValue prop = JS_GetProperty(ctx, desc, JS_ATOM_writable); if (JS_IsException(prop)) @@ -34688,26 +34713,12 @@ static int js_obj_to_desc(JSContext *ctx, JSPropertyDescriptor *d, if (JS_ToBoolFree(ctx, prop)) flags |= JS_PROP_WRITABLE; } - if (JS_HasProperty(ctx, desc, JS_ATOM_enumerable)) { - JSValue prop = JS_GetProperty(ctx, desc, JS_ATOM_enumerable); - if (JS_IsException(prop)) - goto fail; - flags |= JS_PROP_HAS_ENUMERABLE; - if (JS_ToBoolFree(ctx, prop)) - flags |= JS_PROP_ENUMERABLE; - } - if (JS_HasProperty(ctx, desc, JS_ATOM_value)) { - flags |= JS_PROP_HAS_VALUE; - val = JS_GetProperty(ctx, desc, JS_ATOM_value); - if (JS_IsException(val)) - goto fail; - } if (JS_HasProperty(ctx, desc, JS_ATOM_get)) { flags |= JS_PROP_HAS_GET; getter = JS_GetProperty(ctx, desc, JS_ATOM_get); if (JS_IsException(getter) || !(JS_IsUndefined(getter) || JS_IsFunction(ctx, getter))) { - JS_ThrowTypeError(ctx, "invalid getter"); + JS_ThrowTypeError(ctx, "Getter must be a function"); goto fail; } } @@ -34716,7 +34727,7 @@ static int js_obj_to_desc(JSContext *ctx, JSPropertyDescriptor *d, setter = JS_GetProperty(ctx, desc, JS_ATOM_set); if (JS_IsException(setter) || !(JS_IsUndefined(setter) || JS_IsFunction(ctx, setter))) { - JS_ThrowTypeError(ctx, "invalid setter"); + JS_ThrowTypeError(ctx, "Setter must be a function"); goto fail; } } @@ -34764,7 +34775,7 @@ static __exception int JS_ObjectDefineProperties(JSContext *ctx, int ret = -1; if (!JS_IsObject(obj)) { - JS_ThrowTypeErrorNotAnObject(ctx); + JS_ThrowTypeError(ctx, "Object.defineProperties called on non-object"); return -1; } desc = JS_UNDEFINED; @@ -34774,6 +34785,9 @@ static __exception int JS_ObjectDefineProperties(JSContext *ctx, p = JS_VALUE_GET_OBJ(props); if (JS_GetOwnPropertyNamesInternal(ctx, &atoms, &len, p, JS_GPN_ENUM_ONLY | JS_GPN_STRING_MASK | JS_GPN_SYMBOL_MASK) < 0) goto exception; + // XXX: ECMA specifies that all descriptions should be validated before + // modifying the object. This would require allocating an array + // JSPropertyDescriptor and use 2 separate loops. for(i = 0; i < len; i++) { JS_FreeValue(ctx, desc); desc = JS_GetProperty(ctx, props, atoms[i].atom); @@ -34823,7 +34837,7 @@ static JSValue js_object_create(JSContext *ctx, JSValue this_val, proto = argv[0]; if (!JS_IsObject(proto) && !JS_IsNull(proto)) - return JS_ThrowTypeError(ctx, "not a prototype"); + return JS_ThrowTypeError(ctx, "object prototype may only be an Object or null"); obj = JS_NewObjectProto(ctx, proto); if (JS_IsException(obj)) return JS_EXCEPTION; @@ -35966,7 +35980,9 @@ static JSValue *build_arg_list(JSContext *ctx, uint32_t *plen, if (js_get_length32(ctx, &len, array_arg)) return NULL; if (len > JS_MAX_LOCAL_VARS) { - JS_ThrowInternalError(ctx, "too many arguments"); + // XXX: check for stack overflow? + JS_ThrowRangeError(ctx, "too many arguments in function call (only %d allowed)", + JS_MAX_LOCAL_VARS); return NULL; } /* avoid allocating 0 bytes */ @@ -39420,7 +39436,7 @@ static JSValue js_string_includes(JSContext *ctx, JSValue this_val, ret = js_is_regexp(ctx, argv[0]); if (ret) { if (ret > 0) - JS_ThrowTypeError(ctx, "regex not supported"); + JS_ThrowTypeError(ctx, "regexp not supported"); goto fail; } v = JS_ToString(ctx, argv[0]); @@ -39982,7 +39998,7 @@ static JSValue js_string_pad(JSContext *ctx, JSValue this_val, } } if (n > JS_STRING_LEN_MAX) { - JS_ThrowInternalError(ctx, "string too long"); + JS_ThrowRangeError(ctx, "invalid string length"); goto fail2; } if (string_buffer_init(ctx, b, n)) @@ -40045,7 +40061,7 @@ static JSValue js_string_repeat(JSContext *ctx, JSValue this_val, if (len == 0 || n == 1) return str; if (val * len > JS_STRING_LEN_MAX) { - JS_ThrowInternalError(ctx, "string too long"); + JS_ThrowRangeError(ctx, "invalid string length"); goto fail; } if (string_buffer_init2(ctx, b, n * len, p->is_wide_char)) @@ -42490,7 +42506,7 @@ static JSValue json_parse_value(JSParseState *s) default: def_token: if (s->token.val == TOK_EOF) { - js_parse_error(s, "unexpected end of input"); + js_parse_error(s, "Unexpected end of JSON input"); } else { js_parse_error(s, "unexpected token: '%.*s'", (int)(s->buf_ptr - s->token.ptr), s->token.ptr); @@ -42735,7 +42751,7 @@ static int js_json_to_str(JSContext *ctx, JSONStringifyContext *jsc, JS_FreeValue(ctx, val); return ret; } else if (cl == JS_CLASS_BIG_INT) { - JS_ThrowTypeError(ctx, "bigint are forbidden in JSON.stringify"); + JS_ThrowTypeError(ctx, "BigInt are forbidden in JSON.stringify"); goto exception; } v = js_array_includes(ctx, jsc->stack, 1, &val); @@ -42865,7 +42881,7 @@ static int js_json_to_str(JSContext *ctx, JSONStringifyContext *jsc, concat_value: return string_buffer_concat_value_free(jsc->b, val); case JS_TAG_BIG_INT: - JS_ThrowTypeError(ctx, "bigint are forbidden in JSON.stringify"); + JS_ThrowTypeError(ctx, "BigInt are forbidden in JSON.stringify"); goto exception; default: JS_FreeValue(ctx, val); @@ -46765,6 +46781,7 @@ static const JSCFunctionListEntry js_global_funcs[] = { JS_PROP_DOUBLE_DEF("Infinity", 1.0 / 0.0, 0 ), JS_PROP_DOUBLE_DEF("NaN", NAN, 0 ), JS_PROP_UNDEFINED_DEF("undefined", 0 ), + JS_PROP_STRING_DEF("[Symbol.toStringTag]", "global", JS_PROP_CONFIGURABLE ), }; /* Date */ @@ -47922,7 +47939,7 @@ static JSValue JS_ToBigIntCtorFree(JSContext *ctx, JSValue val) a = JS_ToBigInt1(ctx, &a_s, val); if (!bf_is_finite(a)) { JS_FreeValue(ctx, val); - val = JS_ThrowRangeError(ctx, "cannot convert NaN or Infinity to bigint"); + val = JS_ThrowRangeError(ctx, "cannot convert NaN or Infinity to BigInt"); } else { JSValue val1 = JS_NewBigInt(ctx); bf_t *r; @@ -47940,7 +47957,7 @@ static JSValue JS_ToBigIntCtorFree(JSContext *ctx, JSValue val) val = JS_ThrowOutOfMemory(ctx); } else if (ret & BF_ST_INEXACT) { JS_FreeValue(ctx, val1); - val = JS_ThrowRangeError(ctx, "cannot convert to bigint: not an integer"); + val = JS_ThrowRangeError(ctx, "cannot convert to BigInt: not an integer"); } else { val = JS_CompactBigInt(ctx, val1); } @@ -47961,7 +47978,7 @@ static JSValue JS_ToBigIntCtorFree(JSContext *ctx, JSValue val) case JS_TAG_UNDEFINED: default: JS_FreeValue(ctx, val); - return JS_ThrowTypeError(ctx, "cannot convert to bigint"); + return JS_ThrowTypeError(ctx, "cannot convert to BigInt"); } return val; } @@ -47987,7 +48004,7 @@ static JSValue js_thisBigIntValue(JSContext *ctx, JSValue this_val) return js_dup(p->u.object_data); } } - return JS_ThrowTypeError(ctx, "not a bigint"); + return JS_ThrowTypeError(ctx, "not a BigInt"); } static JSValue js_bigint_toString(JSContext *ctx, JSValue this_val, diff --git a/tests/test_builtin.js b/tests/test_builtin.js index 0d6c86e..98faa74 100644 --- a/tests/test_builtin.js +++ b/tests/test_builtin.js @@ -955,9 +955,9 @@ function test_proxy_is_array() /* Without ASAN */ assert(Array.isArray(r)); } catch(e) { - /* With ASAN expect InternalError "stack overflow" to be raised */ - if (e instanceof InternalError) { - assert(e.message, "stack overflow", "Stack overflow error was not raised") + /* With ASAN expect RangeError "Maximum call stack size exceeded" to be raised */ + if (e instanceof RangeError) { + assert(e.message, "Maximum call stack size exceeded", "Stack overflow error was not raised") } else { throw e; } diff --git a/v8.js b/v8.js index 6999e43..66190b4 100644 --- a/v8.js +++ b/v8.js @@ -6,13 +6,18 @@ const tweak = realpath("v8-tweak.js") const dir = "test262/implementation-contributed/v8/mjsunit" const exclude = [ + "arguments-indirect.js", // implementation-defined "array-concat.js", // slow "array-isarray.js", // unstable output due to stack overflow "ascii-regexp-subject.js", // slow + "asm-directive.js", // v8 specific + "disallow-codegen-from-strings.js", // --disallow-code-generation-from-strings "cyclic-array-to-string.js", // unstable output due to stack overflow "error-tostring.js", // unstable output due to stack overflow "regexp.js", // invalid, legitimate early SyntaxError "regexp-capture-3.js", // slow + "regexp-indexof.js", // deprecated RegExp.lastMatch etc. + "regexp-static.js", // deprecated RegExp static properties. "string-replace.js", // unstable output "mjsunit-assertion-error.js", @@ -31,6 +36,8 @@ for (const file of files) { if (exclude.includes(file)) continue const source = std.loadFile(dir + "/" + file) if (/^(im|ex)port/m.test(source)) continue // TODO support modules + if (source.includes('Realm.create()')) continue // TODO support Realm object + if (source.includes('// MODULE')) continue // TODO support modules if (source.includes('// Files:')) continue // TODO support includes // exclude tests that use V8 intrinsics like %OptimizeFunctionOnNextCall if (source.includes ("--allow-natives-syntax")) continue diff --git a/v8.txt b/v8.txt index 9f4e747..8ee3db4 100644 --- a/v8.txt +++ b/v8.txt @@ -8,21 +8,9 @@ === arguments-call-apply.js === arguments-enum.js === arguments-escape.js -=== arguments-indirect.js -Failure: expected <"object"> found <"undefined"> -Failure: expected found -TypeError: cannot read property 'length' of undefined - at g (arguments-indirect.js:47:19) - at f1 (arguments-indirect.js:29:3) - at (arguments-indirect.js:53:1) - === arguments-lazy.js === arguments-load-across-eval.js === arguments-read-and-assignment.js -=== array-constructor.js -ReferenceError: 'Realm' is not defined - at (array-constructor.js:98:9) - === array-elements-from-array-prototype-chain.js === array-elements-from-array-prototype.js === array-elements-from-object-prototype.js @@ -36,7 +24,7 @@ ReferenceError: 'Realm' is not defined === array-join-nesting.js === array-join-nonarray-length-getter-side-effects.js === array-join.js -InternalError: stack overflow +RangeError: Maximum call stack size exceeded at join (native) at toString (native) at join (native) @@ -80,10 +68,6 @@ Failure (Error message): expected <"7 is not a function"> found <"not a function === array-tostring.js === array-unshift.js === arrow-with.js -=== asm-directive.js -ReferenceError: 'Realm' is not defined - at (asm-directive.js:5:1) - === async-stack-traces-prepare-stacktrace-1.js === async-stack-traces-prepare-stacktrace-2.js Failure: @@ -99,15 +83,7 @@ async function two(x) { === async-stack-traces-prepare-stacktrace-3.js === async-stack-traces-prepare-stacktrace-4.js === big-array-literal.js -Object is not an instance of but of -Failure: expected found -Object is not an instance of but of -Failure: expected found === big-object-literal.js -Object is not an instance of but of -Failure: expected found -Object is not an instance of but of -Failure: expected found === binary-op-newspace.js === binary-operation-overwrite.js === bit-not.js @@ -118,10 +94,6 @@ Failure: expected found === bool-concat.js === boolean.js === break.js -=== call-cross-realm.js -ReferenceError: 'Realm' is not defined - at (call-cross-realm.js:5:1) - === call-non-function-call.js === call-non-function.js === call-stub.js @@ -147,15 +119,7 @@ TypeError: not a function === constant-folding.js === context-variable-assignments.js -=== contextual-calls.js -ReferenceError: 'Realm' is not defined - at (contextual-calls.js:28:14) - === copy-on-write-assert.js -=== cross-realm-filtering.js -ReferenceError: 'Realm' is not defined - at (cross-realm-filtering.js:5:14) - === cyrillic.js Failure (7): expected found Failure (8): expected found @@ -195,123 +159,17 @@ Failure (May 25 2008 1:30( )AM (PM) is not NaN.): expected found === delete-vars-from-eval.js === delete.js === deserialize-reference.js -=== disallow-codegen-from-strings.js -Did not throw exception -Did not throw exception -Did not throw exception === do-not-strip-fc.js === dont-enum-array-holes.js === dont-reinit-global-var.js === double-equals.js === dtoa.js === duplicate-parameters.js -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found - === eagerly-parsed-lazily-compiled-functions.js === elements-transition-and-store.js === empirical_max_arraybuffer.js === enumeration-order.js === error-accessors.js -Failure: expected <"x is not defined"> found <"'x' is not defined"> -Failure: expected <"x is not defined"> found <"'x' is not defined"> === error-constructors.js === error-tostring-omit.js Failure: expected found @@ -609,12 +467,10 @@ expected: found: "invalid character in a JSON string" === json-parser-recursive.js -Object is not an instance of but of === json-replacer-number-wrapper-tostring.js === json-replacer-order.js === json-stringify-holder.js === json-stringify-recursive.js -Object is not an instance of but of Did not throw exception Did not throw exception === json-stringify-stack.js @@ -639,10 +495,6 @@ found: === keyed-array-call.js === keyed-call-generic.js === keyed-call-ic.js -Failure: expected <"[object global]"> found <"[object Object]"> -Failure: expected <"[object global]"> found <"[object Object]"> -Failure: expected <"[object global]"> found <"[object Object]"> -Failure: expected <"[object global]"> found <"[object Object]"> === keyed-ic.js === keyed-storage-extend.js === keywords-and-reserved_words.js @@ -655,19 +507,11 @@ Failure: expected <"[object global]"> found <"[object Object]"> === load-callback-from-value-classic.js === local-load-from-eval.js === logical.js -=== lookup-behind-property.js -ReferenceError: 'Realm' is not defined - at (lookup-behind-property.js:5:9) - === math-exp-precision.js === math-sqrt.js === md5.js === megamorphic-callbacks.js === mod.js -=== modules-error-trace.js -=== modules-preparse.js -=== modules-this.js -Failure: expected found === mul-exhaustive-part1.js === mul-exhaustive-part10.js === mul-exhaustive-part2.js @@ -709,26 +553,10 @@ Failure: expected found === object-create.js Failure: expected found Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected <1> found <0> -Failure: expected <3> found <1> -Failure: expected <0> found <2> -Failure: expected <2> found <3> -Failure: expected found -Failure: expected found -Failure: expected found -Failure: expected found === object-define-properties.js -Failure: expected found -Failure: expected found Failure: expected found <1> === object-freeze-global.js === object-get-own-property-names.js -Failure: expected found -Failure: expected found === object-is.js === object-literal-conversions.js === object-literal-gc.js @@ -756,10 +584,6 @@ Failure (printErr should be defined): expected <"function"> found <"undefined"> === prototype.js === random-bit-correlations.js === readonly-accessor.js -=== realm-property-access.js -ReferenceError: 'Realm' is not defined - at (realm-property-access.js:5:9) - === receiver-in-with-calls.js === regexp-UC16.js === regexp-cache-replace.js @@ -778,43 +602,6 @@ SyntaxError: too many captures at RegExp (native) at (regexp-global.js:169:36) -=== regexp-indexof.js -Failure (lastMatch): expected <"abc"> found -Failure (leftContext): expected <"xxx"> found -Failure (rightContext): expected <"xxxabcxxx"> found -Failure (lastMatch): expected <"abc"> found -Failure (leftContext): expected <"xxxabcxxx"> found -Failure (rightContext): expected <"xxx"> found -Failure (lastMatch): expected <"abc"> found -Failure (leftContext): expected <"xxxabab"> found -Failure (rightContext): expected <"xxxabcxxx"> found -Failure (lastMatch): expected <"abc"> found -Failure (leftContext): expected <"abcabc"> found -Failure (rightContext): expected <""> found -Failure (lastMatch): expected <"aba"> found -Failure (leftContext): expected <"abab"> found -Failure (rightContext): expected <"ba"> found -Failure (lastMatch): expected <"foo"> found -Failure (leftContext): expected <"ofooofoooofo"> found -Failure (rightContext): expected <"ofo"> found -Failure (lastMatch): expected <""> found -Failure (leftContext): expected <""> found -Failure (rightContext): expected <"xxx"> found -Failure (lastMatch): expected <"ab"> found -Failure (leftContext): expected <"xyzzy"> found -Failure (rightContext): expected <"xyzzzyacxyzzy"> found -Failure (lastMatch): expected <"ac"> found -Failure (leftContext): expected <"xyzzyabxyzzy"> found -Failure (rightContext): expected <"xyzzy"> found -Failure (lastMatch): expected <""> found -Failure (leftContext): expected <"aba"> found -Failure (rightContext): expected <""> found -Failure (lastMatch): expected <""> found -Failure (leftContext): expected <"baba"> found -Failure (rightContext): expected <""> found -Failure (lastMatch): expected <""> found -Failure (leftContext): expected <"bab"> found -Failure (rightContext): expected <""> found === regexp-lastIndex.js === regexp-lookahead.js === regexp-loop-capture.js @@ -858,107 +645,6 @@ TypeError: regexp must have the 'g' flag === regexp-sort.js === regexp-stack-overflow.js === regexp-standalones.js -=== regexp-static.js -Failure: expected <"abc123.456def"> found -Failure: expected <"123.456"> found -Failure: expected <"456"> found -Failure: expected <"abc"> found -Failure: expected <"def"> found -Failure: expected <"abc123.456def"> found -Failure: expected <"123.456"> found -Failure: expected <"456"> found -Failure: expected <"abc"> found -Failure: expected <"def"> found -Failure: expected <"123.456"> found -Failure: expected <"123"> found -Failure: expected <"456"> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <"123.456"> found <"fisk"> -Failure: expected <"ghi789.012jkl"> found -Failure: expected <"789.012"> found -Failure: expected <"012"> found -Failure: expected <"ghi"> found -Failure: expected <"jkl"> found -Failure: expected <"ghi789.012jkl"> found -Failure: expected <"789.012"> found -Failure: expected <"012"> found -Failure: expected <"ghi"> found -Failure: expected <"jkl"> found -Failure: expected <"789.012"> found <"fisk"> -Failure: expected <"789"> found -Failure: expected <"012"> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <"abc123.456def"> found -Failure: expected <"123.456"> found -Failure: expected <"456"> found -Failure: expected <"abc"> found -Failure: expected <"def"> found -Failure: expected <"abc123.456def"> found -Failure: expected <"123.456"> found -Failure: expected <"456"> found -Failure: expected <"abc"> found -Failure: expected <"def"> found -Failure: expected <"123.456"> found <"fisk"> -Failure: expected <"123"> found -Failure: expected <"456"> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <"ghi789.012jkl"> found -Failure: expected <"789.012"> found -Failure: expected <"012"> found -Failure: expected <"ghi"> found -Failure: expected <"jkl"> found -Failure: expected <"ghi789.012jkl"> found -Failure: expected <"789.012"> found -Failure: expected <"012"> found -Failure: expected <"ghi"> found -Failure: expected <"jkl"> found -Failure: expected <"789.012"> found <"fisk"> -Failure: expected <"789"> found -Failure: expected <"012"> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <""> found -Failure: expected <"dddd"> found <"fiskfiskfiskfisk"> -Failure (lastParen): expected <""> found -Failure ($1): expected <""> found <"fisk"> -Failure ($2): expected <""> found -Failure ($1 in $3 setup): expected <"x"> found <"fisk"> -Failure ($3): expected <""> found -Failure ($1 in $4 setup): expected <"x"> found <"fisk"> -Failure ($2 in $4 setup): expected <"x"> found -Failure ($4): expected <""> found -Failure ($1 in $5 setup): expected <"x"> found <"fisk"> -Failure ($2 in $5 setup): expected <"x"> found -Failure ($3 in $5 setup): expected <"x"> found -Failure ($5): expected <""> found -Failure ($1 in $6 setup): expected <"x"> found <"fisk"> -Failure ($2 in $6 setup): expected <"x"> found -Failure ($3 in $6 setup): expected <"x"> found -Failure ($4 in $6 setup): expected <"x"> found -Failure ($6): expected <""> found -Failure ($1 in $7 setup): expected <"x"> found <"fisk"> -Failure ($2 in $7 setup): expected <"x"> found -Failure ($3 in $7 setup): expected <"x"> found -Failure ($4 in $7 setup): expected <"x"> found - === regexp-string-methods.js === regress-regexp-functional-replace-slow.js === result-table-max.js @@ -1029,7 +715,6 @@ TypeError: not a function at (stack-traces-custom.js:20:21) === stack-traces-overflow.js -Object is not an instance of but of Failure: expected found Failure: expected found Failure: expected found <""> @@ -1298,7 +983,6 @@ Failure (Capture-Global-nocapture-2): expected <""> found === string-normalize.js === string-oom-concat.js -Object is not an instance of but of === string-pad.js === string-replace-gc.js === string-replace-one-char.js @@ -1413,7 +1097,6 @@ Failure (RegExp.$1): expected <"regexp"> found === this-in-callbacks.js === this-property-assignment.js === this.js -Failure: expected <"[object global]"> found <"[object Object]"> === throw-and-catch-function.js === throw-exception-for-null-access.js === to-precision.js