diff --git a/crates/js/src/builtins.rs b/crates/js/src/builtins.rs index b16aa9c9e1..3eda7b6a62 100644 --- a/crates/js/src/builtins.rs +++ b/crates/js/src/builtins.rs @@ -113,12 +113,11 @@ fn install_errors(interp: &mut Interp, object_proto: ObjId) -> JsResult<()> { ]; let mut error_proto = object_proto; for (i, (name, f)) in kinds.into_iter().enumerate() { - let proto = alloc(interp, Class::Ordinary, Some(if i == 0 { object_proto } else { error_proto })); + // Error.prototype and each NativeError prototype are Error objects (sections 15.11.4 and + // 15.11.7.7). + let proto = alloc(interp, Class::Error, Some(if i == 0 { object_proto } else { error_proto })); if i == 0 { error_proto = proto; - if let Some(p) = interp.heap.object_mut(proto) { - p.class = Class::Error; - } method(interp, proto, "toString", error_to_string, 0)?; } if let Some(slot) = interp.intrinsics.error_protos.get_mut(i) { diff --git a/crates/js/src/interp_tests.rs b/crates/js/src/interp_tests.rs index 6c2608f2b1..8dff13050a 100644 --- a/crates/js/src/interp_tests.rs +++ b/crates/js/src/interp_tests.rs @@ -118,6 +118,11 @@ fn objects_arrays_and_accessors() { truth("'abc'.length === 3 && 'abc'[1] === 'b' && 'abc'.x === undefined"); truth("var o = {}; o.hasOwnProperty('x') === false && ({x: 1}).hasOwnProperty('x')"); truth("Object.prototype.toString.call([]) === '[object Array]' && Object.prototype.toString.call(null) === '[object Null]'"); + // Error.prototype and each NativeError prototype are Error objects (sections 15.11.4 and 15.11.7.7). + truth( + "var s = Object.prototype.toString, all = [Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError], ok = true;\ + for (var i = 0; i < all.length; i++) ok = ok && s.call(all[i].prototype) === '[object Error]'; ok", + ); let e = fail("var a = []; a.length = -1"); assert!(e.message.starts_with("RangeError"), "{}", e.message); let e = fail("'use strict'; var o = { get x() { return 1; } }; o.x = 2;");