Skip to content

Commit c5ce362

Browse files
committed
Do not throw for detached ArrayBuffer from jitted code on typeof detachedView[i & 1].
In TypeofElem_Int32 & TypeofElem_UInt32, which are called only from the jit, call IsNumberFromNativeArray which can throw if the TypedArray is detached. This behavior differs from what we do in the interpreter.
1 parent 0a33794 commit c5ce362

File tree

4 files changed

+34
-5
lines changed

4 files changed

+34
-5
lines changed

lib/Runtime/Language/JavascriptOperators.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2608,8 +2608,15 @@ namespace Js
26082608
#endif
26092609
Js::TypeId instanceType = JavascriptOperators::GetTypeId(instance);
26102610
// Fast path for native and typed arrays.
2611-
if ( (instanceType == TypeIds_NativeIntArray || instanceType == TypeIds_NativeFloatArray) || (instanceType >= TypeIds_Int8Array && instanceType <= TypeIds_Uint64Array) )
2611+
bool isNativeArray = instanceType == TypeIds_NativeIntArray || instanceType == TypeIds_NativeFloatArray;
2612+
bool isTypedArray = instanceType >= TypeIds_Int8Array && instanceType <= TypeIds_Uint64Array;
2613+
if (isNativeArray || isTypedArray)
26122614
{
2615+
// Check if the typed array is detached to prevent an exception in GetOwnItem
2616+
if (isTypedArray && TypedArrayBase::IsDetachedTypedArray(instance))
2617+
{
2618+
return FALSE;
2619+
}
26132620
RecyclableObject* object = RecyclableObject::FromVar(instance);
26142621
Var member = nullptr;
26152622

@@ -4504,7 +4511,7 @@ namespace Js
45044511
ScriptContext* scriptContext,
45054512
PropertyOperationFlags flags)
45064513
{
4507-
4514+
45084515
INT_PTR vt = (INT_PTR)nullptr;
45094516
vt = VirtualTableInfoBase::GetVirtualTable(instance);
45104517

@@ -4565,7 +4572,7 @@ namespace Js
45654572
PropertyOperationFlags flags,
45664573
double dValue)
45674574
{
4568-
4575+
45694576
INT_PTR vt = (INT_PTR)nullptr;
45704577
vt = VirtualTableInfoBase::GetVirtualTable(instance);
45714578

lib/Runtime/Library/TypedArray.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,7 +1131,8 @@ namespace Js
11311131

11321132
BOOL TypedArrayBase::IsDetachedTypedArray(Var aValue)
11331133
{
1134-
return Is(aValue) && FromVar(aValue)->IsDetachedBuffer();
1134+
TypedArrayBase* arr = JavascriptOperators::TryFromVar<TypedArrayBase>(aValue);
1135+
return arr && arr->IsDetachedBuffer();
11351136
}
11361137

11371138
void TypedArrayBase::Set(TypedArrayBase* source, uint32 offset)
@@ -1158,7 +1159,7 @@ namespace Js
11581159
if (GetTypeId() == source->GetTypeId() ||
11591160
(GetBytesPerElement() == source->GetBytesPerElement()
11601161
&& !((Uint8ClampedArray::Is(this) || Uint8ClampedVirtualArray::Is(this)) && (Int8Array::Is(source) || Int8VirtualArray::Is(source)))
1161-
&& !Float32Array::Is(this) && !Float32Array::Is(source)
1162+
&& !Float32Array::Is(this) && !Float32Array::Is(source)
11621163
&& !Float32VirtualArray::Is(this) && !Float32VirtualArray::Is(source)
11631164
&& !Float64Array::Is(this) && !Float64Array::Is(source)
11641165
&& !Float64VirtualArray::Is(this) && !Float64VirtualArray::Is(source)))

test/typedarray/rlexe.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,4 +407,9 @@ Below test fails with difference in space. Investigate the cause and re-enable t
407407
<tags>typedarray</tags>
408408
</default>
409409
</test>
410+
<test>
411+
<default>
412+
<files>typeofDetached.js</files>
413+
</default>
414+
</test>
410415
</regress-exe>

test/typedarray/typeofDetached.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
const obj = {};
7+
const f32 = new Float32Array();
8+
function foo() {
9+
return typeof f32[obj.missingprop & 1];
10+
}
11+
ArrayBuffer.detach(f32.buffer);
12+
for (let i = 0; i < 1000; ++i) {
13+
foo();
14+
}
15+
foo();
16+
console.log("pass");

0 commit comments

Comments
 (0)