Explorar el Código

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.
Michael Ferris hace 7 años
padre
commit
c5ce362139

+ 10 - 3
lib/Runtime/Language/JavascriptOperators.cpp

@@ -2608,8 +2608,15 @@ CommonNumber:
 #endif
         Js::TypeId instanceType = JavascriptOperators::GetTypeId(instance);
         // Fast path for native and typed arrays.
-        if ( (instanceType == TypeIds_NativeIntArray || instanceType == TypeIds_NativeFloatArray) || (instanceType >= TypeIds_Int8Array && instanceType <= TypeIds_Uint64Array) )
+        bool isNativeArray = instanceType == TypeIds_NativeIntArray || instanceType == TypeIds_NativeFloatArray;
+        bool isTypedArray = instanceType >= TypeIds_Int8Array && instanceType <= TypeIds_Uint64Array;
+        if (isNativeArray || isTypedArray)
         {
+            // Check if the typed array is detached to prevent an exception in GetOwnItem
+            if (isTypedArray && TypedArrayBase::IsDetachedTypedArray(instance))
+            {
+                return FALSE;
+            }
             RecyclableObject* object = RecyclableObject::FromVar(instance);
             Var member = nullptr;
 
@@ -4504,7 +4511,7 @@ SetElementIHelper_INDEX_TYPE_IS_NUMBER:
         ScriptContext* scriptContext,
         PropertyOperationFlags flags)
     {
-        
+
         INT_PTR vt = (INT_PTR)nullptr;
         vt = VirtualTableInfoBase::GetVirtualTable(instance);
 
@@ -4565,7 +4572,7 @@ SetElementIHelper_INDEX_TYPE_IS_NUMBER:
         PropertyOperationFlags flags,
         double dValue)
     {
-        
+
         INT_PTR vt = (INT_PTR)nullptr;
         vt = VirtualTableInfoBase::GetVirtualTable(instance);
 

+ 3 - 2
lib/Runtime/Library/TypedArray.cpp

@@ -1131,7 +1131,8 @@ namespace Js
 
     BOOL TypedArrayBase::IsDetachedTypedArray(Var aValue)
     {
-        return Is(aValue) && FromVar(aValue)->IsDetachedBuffer();
+        TypedArrayBase* arr = JavascriptOperators::TryFromVar<TypedArrayBase>(aValue);
+        return arr && arr->IsDetachedBuffer();
     }
 
     void TypedArrayBase::Set(TypedArrayBase* source, uint32 offset)
@@ -1158,7 +1159,7 @@ namespace Js
         if (GetTypeId() == source->GetTypeId() ||
             (GetBytesPerElement() == source->GetBytesPerElement()
              && !((Uint8ClampedArray::Is(this) || Uint8ClampedVirtualArray::Is(this)) && (Int8Array::Is(source) || Int8VirtualArray::Is(source)))
-             && !Float32Array::Is(this) && !Float32Array::Is(source) 
+             && !Float32Array::Is(this) && !Float32Array::Is(source)
              && !Float32VirtualArray::Is(this) && !Float32VirtualArray::Is(source)
              && !Float64Array::Is(this) && !Float64Array::Is(source)
              && !Float64VirtualArray::Is(this) && !Float64VirtualArray::Is(source)))

+ 5 - 0
test/typedarray/rlexe.xml

@@ -407,4 +407,9 @@ Below test fails with difference in space. Investigate the cause and re-enable t
       <tags>typedarray</tags>
     </default>
   </test>
+  <test>
+    <default>
+      <files>typeofDetached.js</files>
+    </default>
+  </test>
 </regress-exe>

+ 16 - 0
test/typedarray/typeofDetached.js

@@ -0,0 +1,16 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+const obj = {};
+const f32 = new Float32Array();
+function foo() {
+  return typeof f32[obj.missingprop & 1];
+}
+ArrayBuffer.detach(f32.buffer);
+for (let i = 0; i < 1000; ++i) {
+  foo();
+}
+foo();
+console.log("pass");