Paul Leathers 6 лет назад
Родитель
Сommit
cd58e8e679

+ 37 - 15
lib/Runtime/ByteCode/ByteCodeEmitter.cpp

@@ -4262,21 +4262,33 @@ void ByteCodeGenerator::EmitLoadInstance(Symbol *sym, IdentPtr pid, Js::RegSlot
                 funcInfo->FindOrAddReferencedPropertyId(propertyId),
                 envIndex + Js::FrameDisplay::GetOffsetOfScopes() / sizeof(Js::Var));
 
-            Js::RegSlot tmpReg = funcInfo->AcquireTmpRegister();
-
             AssertOrFailFast(scope->GetIsObject());
-            this->m_writer.SlotI1(Js::OpCode::LdEnvObj, tmpReg,
-                envIndex + Js::FrameDisplay::GetOffsetOfScopes() / sizeof(Js::Var));
-
-            Js::OpCode op = unwrapWithObj ? Js::OpCode::UnwrapWithObj : Js::OpCode::Ld_A;
 
-            this->m_writer.Reg2(op, instLocation, tmpReg);
-            if (thisLocation != Js::Constants::NoRegister)
+            if (unwrapWithObj)
             {
-                this->m_writer.Reg2(op, thisLocation, tmpReg);
+                Js::RegSlot tmpReg = funcInfo->AcquireTmpRegister();
+
+                this->m_writer.SlotI1(Js::OpCode::LdEnvObj, tmpReg,
+                    envIndex + Js::FrameDisplay::GetOffsetOfScopes() / sizeof(Js::Var));
+
+                this->m_writer.Reg2(Js::OpCode::UnwrapWithObj, instLocation, tmpReg);
+                if (thisLocation != Js::Constants::NoRegister)
+                {
+                    this->m_writer.Reg2(Js::OpCode::UnwrapWithObj, thisLocation, tmpReg);
+                }
+
+                funcInfo->ReleaseTmpRegister(tmpReg);
             }
+            else
+            {
+                this->m_writer.SlotI1(Js::OpCode::LdEnvObj, instLocation,
+                    envIndex + Js::FrameDisplay::GetOffsetOfScopes() / sizeof(Js::Var));
 
-            funcInfo->ReleaseTmpRegister(tmpReg);
+                if (thisLocation != Js::Constants::NoRegister)
+                {
+                    this->m_writer.Reg2(Js::OpCode::Ld_A, thisLocation, funcInfo->undefinedConstantRegister);
+                }
+            }
         }
         else if (scopeLocation != Js::Constants::NoRegister && scopeLocation == funcInfo->frameObjRegister)
         {
@@ -4288,7 +4300,7 @@ void ByteCodeGenerator::EmitLoadInstance(Symbol *sym, IdentPtr pid, Js::RegSlot
             this->m_writer.Reg1(Js::OpCode::LdLocalObj, instLocation);
             if (thisLocation != Js::Constants::NoRegister)
             {
-                this->m_writer.Reg1(Js::OpCode::LdLocalObj, thisLocation);
+                this->m_writer.Reg2(Js::OpCode::Ld_A, thisLocation, funcInfo->undefinedConstantRegister);
             }
         }
         else
@@ -4296,11 +4308,21 @@ void ByteCodeGenerator::EmitLoadInstance(Symbol *sym, IdentPtr pid, Js::RegSlot
             this->m_writer.BrProperty(Js::OpCode::BrOnNoProperty, nextLabel, scopeLocation,
                 funcInfo->FindOrAddReferencedPropertyId(propertyId));
 
-            Js::OpCode op = unwrapWithObj ? Js::OpCode::UnwrapWithObj : Js::OpCode::Ld_A;
-            this->m_writer.Reg2(op, instLocation, scopeLocation);
-            if (thisLocation != Js::Constants::NoRegister)
+            if (unwrapWithObj)
             {
-                this->m_writer.Reg2(op, thisLocation, scopeLocation);
+                this->m_writer.Reg2(Js::OpCode::UnwrapWithObj, instLocation, scopeLocation);
+                if (thisLocation != Js::Constants::NoRegister)
+                {
+                    this->m_writer.Reg2(Js::OpCode::UnwrapWithObj, thisLocation, scopeLocation);
+                }
+            }
+            else
+            {
+                this->m_writer.Reg2(Js::OpCode::Ld_A, instLocation, scopeLocation);
+                if (thisLocation != Js::Constants::NoRegister)
+                {
+                    this->m_writer.Reg2(Js::OpCode::Ld_A, thisLocation, funcInfo->undefinedConstantRegister);
+                }
             }
         }
 

+ 1 - 2
lib/Runtime/Language/JavascriptOperators.cpp

@@ -2072,8 +2072,7 @@ CommonNumber:
                 // HasProperty will call UnscopablesWrapperObject's HasProperty which will do the filtering
                 // All we have to do here is unwrap the object hence the api call
 
-                *thisVar = obj->GetThisObjectOrUnWrap();
-                return *thisVar;
+                return obj->GetThisAndUnwrappedInstance(thisVar);
             }
         }
 

+ 6 - 0
lib/Runtime/Types/RecyclableObject.cpp

@@ -331,6 +331,12 @@ namespace Js
         return this;
     }
 
+    RecyclableObject* RecyclableObject::GetThisAndUnwrappedInstance(Var* thisVar) const
+    {
+        *thisVar = this->GetLibrary()->GetUndefined();
+        return (RecyclableObject*)this;
+    }
+
     // In order to avoid a branch, every object has an entry point if it gets called like a
     // function - however, if it can't be called like a function, it's set to DefaultEntryPoint
     // which will emit an error.

+ 1 - 0
lib/Runtime/Types/RecyclableObject.h

@@ -353,6 +353,7 @@ namespace Js {
         virtual uint GetSpecialPropertyCount() const { return 0; }
         virtual PropertyId const * GetSpecialPropertyIds() const { return nullptr; }
         virtual RecyclableObject* GetThisObjectOrUnWrap(); // Due to the withScope object there are times we need to unwrap
+        virtual RecyclableObject* GetThisAndUnwrappedInstance(Var* thisVar) const;
 
         virtual BOOL HasInstance(Var instance, ScriptContext* scriptContext, IsInstInlineCache* inlineCache = NULL);
 

+ 6 - 0
lib/Runtime/Types/UnscopablesWrapperObject.cpp

@@ -23,6 +23,12 @@ namespace Js
         return static_cast<UnscopablesWrapperObject*>(aValue);
     }
 
+    RecyclableObject * UnscopablesWrapperObject::GetThisAndUnwrappedInstance(Var* thisVar) const
+    {
+        *thisVar = this->GetWrappedObject();
+        return this->GetWrappedObject();
+    }
+
     PropertyQueryFlags UnscopablesWrapperObject::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
     {
         return JavascriptConversion::BooleanToPropertyQueryFlags(JavascriptOperators::HasPropertyUnscopables(wrappedObject, propertyId));

+ 2 - 1
lib/Runtime/Types/UnscopablesWrapperObject.h

@@ -28,7 +28,8 @@ namespace Js
             static bool Is(Var aValue);
             static UnscopablesWrapperObject* FromVar(Var value);
             static UnscopablesWrapperObject* UnsafeFromVar(Var value);
-            RecyclableObject *GetWrappedObject() { return wrappedObject; }
+            RecyclableObject *GetWrappedObject() const { return wrappedObject; }
+            virtual RecyclableObject* GetThisAndUnwrappedInstance(Var* thisVar) const override;
             virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
             virtual BOOL HasOwnProperty(PropertyId propertyId) override;
             virtual BOOL SetProperty(PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info) override;