diff --git a/Jint.Tests.Test262/Test262Harness.settings.json b/Jint.Tests.Test262/Test262Harness.settings.json index 406010a5b..37bc78d5b 100644 --- a/Jint.Tests.Test262/Test262Harness.settings.json +++ b/Jint.Tests.Test262/Test262Harness.settings.json @@ -1,5 +1,5 @@ { - "SuiteGitSha": "5dc04b733275cf64e3022867359e27bc99d9262c", + "SuiteGitSha": "941813e1f0e64ae9a5c4c5c8075f49ff89b0c642", //"SuiteDirectory": "//mnt/c/work/test262", "TargetPath": "./Generated", "Namespace": "Jint.Tests.Test262", diff --git a/Jint/Native/Array/ArrayPrototype.cs b/Jint/Native/Array/ArrayPrototype.cs index 4ce625ddb..0765b9ac9 100644 --- a/Jint/Native/Array/ArrayPrototype.cs +++ b/Jint/Native/Array/ArrayPrototype.cs @@ -1300,42 +1300,35 @@ static string StringFromJsValue(JsValue value) return sb.ToString(); } + /// + /// https://tc39.es/ecma262/#sec-array.prototype.tolocalestring + /// private JsValue ToLocaleString(JsValue thisObject, JsValue[] arguments) { + const string Separator = ","; + var array = ArrayOperations.For(_realm, thisObject, forWrite: false); var len = array.GetLength(); - const string Separator = ","; if (len == 0) { return JsString.Empty; } - JsValue r; - if (!array.TryGetValue(0, out var firstElement) || firstElement.IsNull() || firstElement.IsUndefined()) - { - r = JsString.Empty; - } - else - { - r = Invoke(firstElement, "toLocaleString", System.Array.Empty()); - } - - for (uint k = 1; k < len; k++) + using var r = new ValueStringBuilder(); + for (uint k = 0; k < len; k++) { - var s = r + Separator; - if (!array.TryGetValue(k, out var nextElement) || nextElement.IsNull()) + if (k > 0) { - r = JsString.Empty; + r.Append(Separator); } - else + if (array.TryGetValue(k, out var nextElement) && !nextElement.IsNullOrUndefined()) { - r = Invoke(nextElement, "toLocaleString", System.Array.Empty()); + var s = TypeConverter.ToString(Invoke(nextElement, "toLocaleString", [])); + r.Append(s); } - - r = s + r; } - return r; + return r.ToString(); } /// diff --git a/Jint/Native/JsTypedArray.cs b/Jint/Native/JsTypedArray.cs index 847a7cefc..34ca77fbe 100644 --- a/Jint/Native/JsTypedArray.cs +++ b/Jint/Native/JsTypedArray.cs @@ -142,8 +142,16 @@ public override bool Set(JsValue property, JsValue value, JsValue receiver) var numericIndex = TypeConverter.CanonicalNumericIndexString(property); if (numericIndex is not null) { - IntegerIndexedElementSet(numericIndex.Value, value); - return true; + if (ReferenceEquals(this, receiver)) + { + IntegerIndexedElementSet(numericIndex.Value, value); + return true; + } + + if (!IsValidIntegerIndex(numericIndex.Value)) + { + return true; + } } return base.Set(property, value, receiver); diff --git a/Jint/Native/Number/NumberPrototype.cs b/Jint/Native/Number/NumberPrototype.cs index 03513bc52..8697b60c6 100644 --- a/Jint/Native/Number/NumberPrototype.cs +++ b/Jint/Native/Number/NumberPrototype.cs @@ -48,9 +48,12 @@ protected override void Initialize() SetProperties(properties); } + /// + /// https://tc39.es/ecma262/#sec-number.prototype.tolocalestring + /// private JsValue ToLocaleString(JsValue thisObject, JsValue[] arguments) { - if (!thisObject.IsNumber() && ReferenceEquals(thisObject.TryCast(), null)) + if (!thisObject.IsNumber() && thisObject is not NumberInstance) { ExceptionHelper.ThrowTypeError(_realm); } diff --git a/Jint/Native/TypedArray/IntrinsicTypedArrayPrototype.cs b/Jint/Native/TypedArray/IntrinsicTypedArrayPrototype.cs index 8096f5162..79217b4ce 100644 --- a/Jint/Native/TypedArray/IntrinsicTypedArrayPrototype.cs +++ b/Jint/Native/TypedArray/IntrinsicTypedArrayPrototype.cs @@ -1198,54 +1198,61 @@ private JsValue Slice(JsValue thisObject, JsValue[] arguments) var len = taRecord.TypedArrayLength; var relativeStart = TypeConverter.ToIntegerOrInfinity(start); - int k; + int startIndex; if (double.IsNegativeInfinity(relativeStart)) { - k = 0; + startIndex = 0; } else if (relativeStart < 0) { - k = (int) System.Math.Max(len + relativeStart, 0); + startIndex = (int) System.Math.Max(len + relativeStart, 0); } else { - k = (int) System.Math.Min(relativeStart, len); + startIndex = (int) System.Math.Min(relativeStart, len); } var relativeEnd = end.IsUndefined() ? len : TypeConverter.ToIntegerOrInfinity(end); - long final; + long endIndex; if (double.IsNegativeInfinity(relativeEnd)) { - final = 0; + endIndex = 0; } else if (relativeEnd < 0) { - final = (long) System.Math.Max(len + relativeEnd, 0); + endIndex = (long) System.Math.Max(len + relativeEnd, 0); } else { - final = (long) System.Math.Min(relativeEnd, len); + endIndex = (long) System.Math.Min(relativeEnd, len); } - var count = System.Math.Max(final - k, 0); - var a = _realm.Intrinsics.TypedArray.TypedArraySpeciesCreate(o, new JsValue[] { count }); + var countBytes = System.Math.Max(endIndex - startIndex, 0); + var a = _realm.Intrinsics.TypedArray.TypedArraySpeciesCreate(o, new JsValue[] { countBytes }); - if (count > 0) + if (countBytes > 0) { - o._viewedArrayBuffer.AssertNotDetached(); + taRecord = MakeTypedArrayWithBufferWitnessRecord(o, ArrayBufferOrder.SeqCst); + if (taRecord.IsTypedArrayOutOfBounds) + { + ExceptionHelper.ThrowTypeError(_realm, "TypedArray is out of bounds"); + } + + endIndex = System.Math.Min(endIndex, taRecord.TypedArrayLength); + countBytes = System.Math.Max(endIndex - startIndex, 0); var srcType = o._arrayElementType; var targetType = a._arrayElementType; if (srcType != targetType) { var n = 0; - while (k < final) + while (startIndex < endIndex) { - var kValue = o[k]; + var kValue = o[startIndex]; a[n] = kValue; - k++; + startIndex++; n++; } } @@ -1256,8 +1263,8 @@ private JsValue Slice(JsValue thisObject, JsValue[] arguments) var elementSize = srcType.GetElementSize(); var srcByteOffset = o._byteOffset; var targetByteIndex = a._byteOffset; - var srcByteIndex = (int) k * elementSize + srcByteOffset; - var limit = targetByteIndex + count * elementSize; + var srcByteIndex = (int) startIndex * elementSize + srcByteOffset; + var limit = targetByteIndex + countBytes * elementSize; while (targetByteIndex < limit) { var value = srcBuffer.GetValueFromBuffer(srcByteIndex, TypedArrayElementType.Uint8, true, ArrayBufferOrder.Unordered); @@ -1428,49 +1435,32 @@ private JsValue ToLocaleString(JsValue thisObject, JsValue[] arguments) * any observable changes in the specified behaviour of the algorithm. */ + const string Separator = ","; + var taRecord = thisObject.ValidateTypedArray(_realm, ArrayBufferOrder.SeqCst); var array = taRecord.Object; var len = taRecord.TypedArrayLength; - const string separator = ","; if (len == 0) { return JsString.Empty; } - JsValue r; - if (!array.TryGetValue(0, out var firstElement) || firstElement.IsNull() || firstElement.IsUndefined()) - { - r = JsString.Empty; - } - else + using var r = new ValueStringBuilder(); + for (uint k = 0; k < len; k++) { - var elementObj = TypeConverter.ToObject(_realm, firstElement); - var func = elementObj.Get("toLocaleString") as ICallable; - if (func is null) + if (k > 0) { - ExceptionHelper.ThrowTypeError(_realm); + r.Append(Separator); } - - r = func.Call(elementObj, Arguments.Empty); - } - - for (var k = 1; k < len; k++) - { - var s = r + separator; - var elementObj = TypeConverter.ToObject(_realm, array[k]); - var func = elementObj.Get("toLocaleString") as ICallable; - if (func is null) + if (array.TryGetValue(k, out var nextElement) && !nextElement.IsNullOrUndefined()) { - ExceptionHelper.ThrowTypeError(_realm); + var s = TypeConverter.ToString(Invoke(nextElement, "toLocaleString", [])); + r.Append(s); } - - r = func.Call(elementObj, Arguments.Empty); - - r = s + r; } - return r; + return r.ToString(); } ///