diff --git a/nova_vm/src/ecmascript/builtins/text_processing/string_objects/string_constructor.rs b/nova_vm/src/ecmascript/builtins/text_processing/string_objects/string_constructor.rs index 2ee1a7d0..d3b1b0bc 100644 --- a/nova_vm/src/ecmascript/builtins/text_processing/string_objects/string_constructor.rs +++ b/nova_vm/src/ecmascript/builtins/text_processing/string_objects/string_constructor.rs @@ -2,6 +2,8 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. +use crate::ecmascript::abstract_operations::testing_and_comparison::is_integral_number; +use crate::ecmascript::abstract_operations::type_conversion::to_number; use crate::ecmascript::abstract_operations::type_conversion::to_string; use crate::ecmascript::builders::builtin_function_builder::BuiltinFunctionBuilder; use crate::ecmascript::builtins::ordinary::get_prototype_from_constructor; @@ -170,9 +172,8 @@ impl StringConstructor { agent: &mut Agent, _this_value: Value, code_points: ArgumentsList, - gc: GcScope, + mut gc: GcScope, ) -> JsResult { - let gc = gc.nogc(); // 3. Assert: If codePoints is empty, then result is the empty String. if code_points.is_empty() { return Ok(String::EMPTY_STRING.into_value()); @@ -190,7 +191,7 @@ impl StringConstructor { return Err(agent.throw_exception( ExceptionType::RangeError, format!("{:?} is not a valid code point", next_cp), - gc, + gc.nogc(), )); } // d. Set result to the string-concatenation of result and UTF16EncodeCodePoint(ℝ(nextCP)). @@ -204,24 +205,29 @@ impl StringConstructor { // 2. For each element next of codePoints, do for next in code_points.iter() { // a. Let nextCP be ? ToNumber(next). + let next_cp = to_number(agent, next.into_value(), gc.reborrow())?.unbind(); // b. If IsIntegralNumber(nextCP) is false, throw a RangeError exception. + if !is_integral_number(agent, next_cp, gc.reborrow()) { + return Err(agent.throw_exception( + ExceptionType::RangeError, + format!("{:?} is not a valid code point", next_cp.to_real(agent)), + gc.nogc(), + )); + } // c. If ℝ(nextCP) < 0 or ℝ(nextCP) > 0x10FFFF, throw a RangeError exception. - let Value::Integer(next_cp) = next else { - unreachable!(); - }; - let next_cp = next_cp.into_i64(); + let next_cp = next_cp.into_i64(agent); if !(0..=0x10FFFF).contains(&next_cp) { return Err(agent.throw_exception( ExceptionType::RangeError, format!("{:?} is not a valid code point", next_cp), - gc, + gc.nogc(), )); } // d. Set result to the string-concatenation of result and UTF16EncodeCodePoint(ℝ(nextCP)). result.push(char::from_u32(next_cp as u32).unwrap()); } // 4. Return result. - Ok(String::from_string(agent, result, gc).into()) + Ok(String::from_string(agent, result, gc.nogc()).into()) } fn raw( diff --git a/tests/expectations.json b/tests/expectations.json index 2f30545c..68933066 100644 --- a/tests/expectations.json +++ b/tests/expectations.json @@ -5195,11 +5195,6 @@ "built-ins/SharedArrayBuffer/zero-length.js": "CRASH", "built-ins/String/S15.5.5.1_A4_T1.js": "CRASH", "built-ins/String/S9.8_A5_T1.js": "FAIL", - "built-ins/String/fromCodePoint/argument-is-Symbol.js": "CRASH", - "built-ins/String/fromCodePoint/argument-is-not-integer.js": "CRASH", - "built-ins/String/fromCodePoint/argument-not-coercible.js": "CRASH", - "built-ins/String/fromCodePoint/number-is-out-of-range.js": "CRASH", - "built-ins/String/fromCodePoint/to-number-conversions.js": "CRASH", "built-ins/String/proto-from-ctor-realm.js": "FAIL", "built-ins/String/prototype/Symbol.iterator/this-val-non-obj-coercible.js": "CRASH", "built-ins/String/prototype/Symbol.iterator/this-val-to-str-err.js": "CRASH", @@ -11361,7 +11356,12 @@ "built-ins/isFinite/tonumber-operations.js": "FAIL", "built-ins/isNaN/tonumber-operations.js": "FAIL", "built-ins/parseFloat/S15.1.2.3_A6.js": "TIMEOUT", + "harness/assert-notsamevalue-tostring.js": "CRASH", + "harness/assert-obj.js": "CRASH", + "harness/assert-samevalue-objects.js": "CRASH", + "harness/assert-samevalue-tostring.js": "CRASH", "harness/assert-throws-same-realm.js": "FAIL", + "harness/assert-tostring.js": "CRASH", "harness/assertRelativeDateMs.js": "CRASH", "harness/asyncHelpers-throwsAsync-custom-typeerror.js": "CRASH", "harness/asyncHelpers-throwsAsync-func-throws-sync.js": "CRASH", @@ -11375,11 +11375,15 @@ "harness/asyncHelpers-throwsAsync-same-realm.js": "CRASH", "harness/asyncHelpers-throwsAsync-single-arg.js": "CRASH", "harness/deepEqual-array.js": "CRASH", + "harness/deepEqual-deep.js": "CRASH", "harness/deepEqual-mapset.js": "CRASH", + "harness/deepEqual-object.js": "CRASH", "harness/deepEqual-primitives-bigint.js": "CRASH", "harness/deepEqual-primitives.js": "FAIL", "harness/nativeFunctionMatcher.js": "CRASH", "harness/testTypedArray-conversions.js": "CRASH", + "harness/verifyProperty-desc-is-not-object.js": "CRASH", + "harness/verifyProperty-undefined-desc.js": "CRASH", "language/arguments-object/10.6-10-c-ii-1.js": "FAIL", "language/arguments-object/10.6-10-c-ii-2.js": "FAIL", "language/arguments-object/10.6-12-1.js": "FAIL", diff --git a/tests/metrics.json b/tests/metrics.json index 7648a1e5..ea72b7b4 100644 --- a/tests/metrics.json +++ b/tests/metrics.json @@ -1,11 +1,11 @@ { "results": { - "crash": 14950, - "fail": 7662, - "pass": 24122, + "crash": 14931, + "fail": 7665, + "pass": 24138, "skip": 55, "timeout": 12, "unresolved": 0 }, - "total": 45299 + "total": 46801 } \ No newline at end of file