2
0
Эх сурвалжийг харах

Do not CrossSite::MarshalVar if scriptContext == requestContext

Saves 3 compare + arithmetic ops per each change.
Oguz Bastemur 8 жил өмнө
parent
commit
2f572ce23c

+ 18 - 1
lib/Runtime/Base/CrossSite.cpp

@@ -122,7 +122,10 @@ namespace Js
             if (WithScopeObject::Is(value))
             if (WithScopeObject::Is(value))
             {
             {
                 // Here we are marshalling the wrappedObject and then ReWrapping th object in the new context.
                 // Here we are marshalling the wrappedObject and then ReWrapping th object in the new context.
-                value = JavascriptOperators::ToWithObject(CrossSite::MarshalVar(scriptContext, WithScopeObject::FromVar(value)->GetWrappedObject()), scriptContext);
+                RecyclableObject* wrappedObject = WithScopeObject::FromVar(value)->GetWrappedObject();
+                ScriptContext* wrappedObjectScriptContext = wrappedObject->GetScriptContext();
+                value = JavascriptOperators::ToWithObject(CrossSite::MarshalVar(scriptContext,
+                  wrappedObject, wrappedObjectScriptContext), scriptContext);
             }
             }
             else
             else
             {
             {
@@ -134,6 +137,20 @@ namespace Js
         return (Var)newDisplay;
         return (Var)newDisplay;
     }
     }
 
 
+    // static
+    Var CrossSite::MarshalVar(ScriptContext* scriptContext, Var value, ScriptContext* objectScriptContext)
+    {
+        if (scriptContext != objectScriptContext)
+        {
+            if (value == nullptr || Js::TaggedNumber::Is(value))
+            {
+                return value;
+            }
+            return MarshalVarInner(scriptContext, RecyclableObject::FromVar(value), false);
+        }
+        return value;
+    }
+
     // static
     // static
     Var CrossSite::MarshalVar(ScriptContext* scriptContext, Var value, bool fRequestWrapper)
     Var CrossSite::MarshalVar(ScriptContext* scriptContext, Var value, bool fRequestWrapper)
     {
     {

+ 1 - 1
lib/Runtime/Base/CrossSite.h

@@ -17,6 +17,7 @@ namespace Js
         static Var DefaultThunk(RecyclableObject* function, CallInfo callInfo, ...);
         static Var DefaultThunk(RecyclableObject* function, CallInfo callInfo, ...);
         static Var ProfileThunk(RecyclableObject* function, CallInfo callInfo, ...);
         static Var ProfileThunk(RecyclableObject* function, CallInfo callInfo, ...);
         static Var CrossSiteProxyCallTrap(RecyclableObject* function, CallInfo callInfo, ...);
         static Var CrossSiteProxyCallTrap(RecyclableObject* function, CallInfo callInfo, ...);
+        static Var MarshalVar(ScriptContext* scriptContext, Var value, ScriptContext* objectScriptContext);
         static Var MarshalVar(ScriptContext* scriptContext, Var value, bool fRequestWrapper = false);
         static Var MarshalVar(ScriptContext* scriptContext, Var value, bool fRequestWrapper = false);
         static void MarshalDynamicObjectAndPrototype(ScriptContext * scriptContext, DynamicObject * object);
         static void MarshalDynamicObjectAndPrototype(ScriptContext * scriptContext, DynamicObject * object);
         static void ForceCrossSiteThunkOnPrototypeChain(RecyclableObject* object);
         static void ForceCrossSiteThunkOnPrototypeChain(RecyclableObject* object);
@@ -46,4 +47,3 @@ namespace Js
         static bool DoRequestWrapper(Js::RecyclableObject* object, bool fRequestWrapper);
         static bool DoRequestWrapper(Js::RecyclableObject* object, bool fRequestWrapper);
     };
     };
 };
 };
-

+ 13 - 9
lib/Runtime/Language/JavascriptConversion.cpp

@@ -369,22 +369,22 @@ CommonNumber:
         case TypeIds_StringObject:
         case TypeIds_StringObject:
             {
             {
                 JavascriptStringObject * stringObject = JavascriptStringObject::FromVar(aValue);
                 JavascriptStringObject * stringObject = JavascriptStringObject::FromVar(aValue);
-
-                if (stringObject->GetScriptContext()->optimizationOverrides.GetSideEffects() & (hint == JavascriptHint::HintString ? SideEffects_ToString : SideEffects_ValueOf))
+                ScriptContext * objectScriptContext = stringObject->GetScriptContext();
+                if (objectScriptContext->optimizationOverrides.GetSideEffects() & (hint == JavascriptHint::HintString ? SideEffects_ToString : SideEffects_ValueOf))
                 {
                 {
                     return MethodCallToPrimitive(aValue, hint, requestContext);
                     return MethodCallToPrimitive(aValue, hint, requestContext);
                 }
                 }
 
 
-                return CrossSite::MarshalVar(requestContext, stringObject->Unwrap());
+                return CrossSite::MarshalVar(requestContext, stringObject->Unwrap(), objectScriptContext);
             }
             }
 
 
         case TypeIds_NumberObject:
         case TypeIds_NumberObject:
             {
             {
                 JavascriptNumberObject * numberObject = JavascriptNumberObject::FromVar(aValue);
                 JavascriptNumberObject * numberObject = JavascriptNumberObject::FromVar(aValue);
-
+                ScriptContext * objectScriptContext = numberObject->GetScriptContext();
                 if (hint == JavascriptHint::HintString)
                 if (hint == JavascriptHint::HintString)
                 {
                 {
-                    if (numberObject->GetScriptContext()->optimizationOverrides.GetSideEffects() & SideEffects_ToString)
+                    if (objectScriptContext->optimizationOverrides.GetSideEffects() & SideEffects_ToString)
                     {
                     {
                         return MethodCallToPrimitive(aValue, hint, requestContext);
                         return MethodCallToPrimitive(aValue, hint, requestContext);
                     }
                     }
@@ -392,11 +392,12 @@ CommonNumber:
                 }
                 }
                 else
                 else
                 {
                 {
-                    if (numberObject->GetScriptContext()->optimizationOverrides.GetSideEffects() & SideEffects_ValueOf)
+                    if (objectScriptContext->optimizationOverrides.GetSideEffects() & SideEffects_ValueOf)
                     {
                     {
                         return MethodCallToPrimitive(aValue, hint, requestContext);
                         return MethodCallToPrimitive(aValue, hint, requestContext);
                     }
                     }
-                    return CrossSite::MarshalVar(requestContext, numberObject->Unwrap());
+
+                    return CrossSite::MarshalVar(requestContext, numberObject->Unwrap(), objectScriptContext);
                 }
                 }
             }
             }
 
 
@@ -673,8 +674,11 @@ CommonNumber:
                 }
                 }
 
 
             case TypeIds_String:
             case TypeIds_String:
-                return JavascriptString::FromVar(CrossSite::MarshalVar(scriptContext, aValue));
-
+                {
+                    ScriptContext* aValueScriptContext = Js::RecyclableObject::FromVar(aValue)->GetScriptContext();
+                    return JavascriptString::FromVar(CrossSite::MarshalVar(scriptContext,
+                      aValue, aValueScriptContext));
+                }
             case TypeIds_VariantDate:
             case TypeIds_VariantDate:
                 return JavascriptVariantDate::FromVar(aValue)->GetValueString(scriptContext);
                 return JavascriptVariantDate::FromVar(aValue)->GetValueString(scriptContext);
 
 

+ 20 - 19
lib/Runtime/Language/JavascriptOperators.cpp

@@ -1178,13 +1178,11 @@ CommonNumber:
         return JavascriptObject::CreateOwnStringSymbolPropertiesHelper(object, scriptContext);
         return JavascriptObject::CreateOwnStringSymbolPropertiesHelper(object, scriptContext);
     }
     }
 
 
-    JavascriptArray* JavascriptOperators::GetOwnEnumerablePropertyNames(Var instance, ScriptContext* scriptContext)
+    JavascriptArray* JavascriptOperators::GetOwnEnumerablePropertyNames(RecyclableObject* object, ScriptContext* scriptContext)
     {
     {
-        RecyclableObject *object = RecyclableObject::FromVar(ToObject(instance, scriptContext));
-
-        if (JavascriptProxy::Is(instance))
+        if (JavascriptProxy::Is(object))
         {
         {
-            JavascriptProxy* proxy = JavascriptProxy::FromVar(instance);
+            JavascriptProxy* proxy = JavascriptProxy::FromVar(object);
             JavascriptArray* proxyResult = proxy->PropertyKeysTrap(JavascriptProxy::KeysTrapKind::GetOwnPropertyNamesKind, scriptContext);
             JavascriptArray* proxyResult = proxy->PropertyKeysTrap(JavascriptProxy::KeysTrapKind::GetOwnPropertyNamesKind, scriptContext);
             JavascriptArray* proxyResultToReturn = scriptContext->GetLibrary()->CreateArray(0);
             JavascriptArray* proxyResultToReturn = scriptContext->GetLibrary()->CreateArray(0);
 
 
@@ -1201,7 +1199,7 @@ CommonNumber:
 
 
                 PropertyDescriptor propertyDescriptor;
                 PropertyDescriptor propertyDescriptor;
                 JavascriptConversion::ToPropertyKey(element, scriptContext, &propertyRecord);
                 JavascriptConversion::ToPropertyKey(element, scriptContext, &propertyRecord);
-                if (JavascriptOperators::GetOwnPropertyDescriptor(RecyclableObject::FromVar(instance), propertyRecord->GetPropertyId(), scriptContext, &propertyDescriptor))
+                if (JavascriptOperators::GetOwnPropertyDescriptor(object, propertyRecord->GetPropertyId(), scriptContext, &propertyDescriptor))
                 {
                 {
                     if (propertyDescriptor.IsEnumerable())
                     if (propertyDescriptor.IsEnumerable())
                     {
                     {
@@ -1214,13 +1212,11 @@ CommonNumber:
         return JavascriptObject::CreateOwnEnumerableStringPropertiesHelper(object, scriptContext);
         return JavascriptObject::CreateOwnEnumerableStringPropertiesHelper(object, scriptContext);
     }
     }
 
 
-    JavascriptArray* JavascriptOperators::GetOwnEnumerablePropertyNamesSymbols(Var instance, ScriptContext* scriptContext)
+    JavascriptArray* JavascriptOperators::GetOwnEnumerablePropertyNamesSymbols(RecyclableObject* object, ScriptContext* scriptContext)
     {
     {
-        RecyclableObject *object = RecyclableObject::FromVar(ToObject(instance, scriptContext));
-
-        if (JavascriptProxy::Is(instance))
+        if (JavascriptProxy::Is(object))
         {
         {
-            JavascriptProxy* proxy = JavascriptProxy::FromVar(instance);
+            JavascriptProxy* proxy = JavascriptProxy::FromVar(object);
             return proxy->PropertyKeysTrap(JavascriptProxy::KeysTrapKind::KeysKind, scriptContext);
             return proxy->PropertyKeysTrap(JavascriptProxy::KeysTrapKind::KeysKind, scriptContext);
         }
         }
         return JavascriptObject::CreateOwnEnumerableStringSymbolPropertiesHelper(object, scriptContext);
         return JavascriptObject::CreateOwnEnumerableStringSymbolPropertiesHelper(object, scriptContext);
@@ -5902,9 +5898,9 @@ CommonNumber:
 #if ENABLE_DEBUG_CONFIG_OPTIONS
 #if ENABLE_DEBUG_CONFIG_OPTIONS
         if (Js::Configuration::Global.flags.IsEnabled(Js::autoProxyFlag))
         if (Js::Configuration::Global.flags.IsEnabled(Js::autoProxyFlag))
         {
         {
-            newObject = DynamicObject::FromVar(JavascriptProxy::AutoProxyWrapper(newObject));
+            DynamicObject* newDynamicObject = DynamicObject::FromVar(JavascriptProxy::AutoProxyWrapper(newObject));
             // this might come from a different scriptcontext.
             // this might come from a different scriptcontext.
-            newObject = CrossSite::MarshalVar(requestContext, newObject);
+            newObject = CrossSite::MarshalVar(requestContext, newDynamicObject, newDynamicObject->GetScriptContext());
         }
         }
 #endif
 #endif
 
 
@@ -5943,7 +5939,8 @@ CommonNumber:
         ScriptContext* functionScriptContext = function->GetScriptContext();
         ScriptContext* functionScriptContext = function->GetScriptContext();
 
 
         RecyclableObject * prototype = JavascriptOperators::GetPrototypeObject(function, functionScriptContext);
         RecyclableObject * prototype = JavascriptOperators::GetPrototypeObject(function, functionScriptContext);
-        prototype = RecyclableObject::FromVar(CrossSite::MarshalVar(requestContext, prototype));
+        prototype = RecyclableObject::FromVar(CrossSite::MarshalVar(requestContext, prototype, functionScriptContext));
+
         Var object = requestContext->GetLibrary()->CreateObject(prototype);
         Var object = requestContext->GetLibrary()->CreateObject(prototype);
         JS_ETW(EventWriteJSCRIPT_RECYCLER_ALLOCATE_OBJECT(object));
         JS_ETW(EventWriteJSCRIPT_RECYCLER_ALLOCATE_OBJECT(object));
 #if ENABLE_DEBUG_CONFIG_OPTIONS
 #if ENABLE_DEBUG_CONFIG_OPTIONS
@@ -6071,8 +6068,10 @@ CommonNumber:
         // after we fail the guard check.  When invalidating the cache for proto change, make sure we zap the prototype field of the cache in
         // after we fail the guard check.  When invalidating the cache for proto change, make sure we zap the prototype field of the cache in
         // addition to the guard value.
         // addition to the guard value.
         bool prototypeCanBeCached;
         bool prototypeCanBeCached;
-        RecyclableObject* prototype = JavascriptOperators::GetPrototypeObjectForConstructorCache(function, constructorScriptContext, prototypeCanBeCached);
-        prototype = RecyclableObject::FromVar(CrossSite::MarshalVar(requestContext, prototype));
+        RecyclableObject* prototype = JavascriptOperators::GetPrototypeObjectForConstructorCache(
+          function, constructorScriptContext, prototypeCanBeCached);
+        prototype = RecyclableObject::FromVar(CrossSite::MarshalVar(requestContext,
+          prototype, constructorScriptContext));
 
 
         DynamicObject* newObject = requestContext->GetLibrary()->CreateObject(prototype, 8);
         DynamicObject* newObject = requestContext->GetLibrary()->CreateObject(prototype, 8);
 
 
@@ -6484,9 +6483,9 @@ CommonNumber:
         Assert(i <= pDisplay->GetLength());
         Assert(i <= pDisplay->GetLength());
         pDisplay->SetLength(i);
         pDisplay->SetLength(i);
     }
     }
+
     FrameDisplay * JavascriptOperators::OP_LdHandlerScope(Var argThis, ScriptContext* scriptContext)
     FrameDisplay * JavascriptOperators::OP_LdHandlerScope(Var argThis, ScriptContext* scriptContext)
     {
     {
-
         // The idea here is to build a stack of nested scopes in the form of a JS array.
         // The idea here is to build a stack of nested scopes in the form of a JS array.
         //
         //
         // The scope stack for an event handler looks like this:
         // The scope stack for an event handler looks like this:
@@ -9367,7 +9366,9 @@ CommonNumber:
 
 
             Var thisVar = RootToThisObject(object, scriptContext);
             Var thisVar = RootToThisObject(object, scriptContext);
 
 
-            RecyclableObject* marshalledFunction = RecyclableObject::FromVar(CrossSite::MarshalVar(requestContext, function));
+            RecyclableObject* marshalledFunction = RecyclableObject::FromVar(
+              CrossSite::MarshalVar(requestContext, function, scriptContext));
+
             Var result = CALL_ENTRYPOINT(threadContext, marshalledFunction->GetEntryPoint(), function, CallInfo(flags, 1), thisVar);
             Var result = CALL_ENTRYPOINT(threadContext, marshalledFunction->GetEntryPoint(), function, CallInfo(flags, 1), thisVar);
             result = CrossSite::MarshalVar(requestContext, result);
             result = CrossSite::MarshalVar(requestContext, result);
 
 
@@ -9407,7 +9408,7 @@ CommonNumber:
             RecyclableObject* marshalledFunction = function;
             RecyclableObject* marshalledFunction = function;
             if (requestContext)
             if (requestContext)
             {
             {
-                marshalledFunction = RecyclableObject::FromVar(CrossSite::MarshalVar(requestContext, function));
+                marshalledFunction = RecyclableObject::FromVar(CrossSite::MarshalVar(requestContext, function, function->GetScriptContext()));
             }
             }
 
 
             Var result = CALL_ENTRYPOINT(threadContext, marshalledFunction->GetEntryPoint(), function, CallInfo(flags, 2), thisVar, putValue);
             Var result = CALL_ENTRYPOINT(threadContext, marshalledFunction->GetEntryPoint(), function, CallInfo(flags, 2), thisVar, putValue);

+ 2 - 2
lib/Runtime/Language/JavascriptOperators.h

@@ -159,8 +159,8 @@ namespace Js
         static JavascriptArray*  GetOwnPropertyKeys(Var instance, ScriptContext *scriptContext);
         static JavascriptArray*  GetOwnPropertyKeys(Var instance, ScriptContext *scriptContext);
 
 
 
 
-        static JavascriptArray*  GetOwnEnumerablePropertyNames(Var instance, ScriptContext *scriptContext);
-        static JavascriptArray*  GetOwnEnumerablePropertyNamesSymbols(Var instance, ScriptContext *scriptContext);
+        static JavascriptArray*  GetOwnEnumerablePropertyNames(RecyclableObject* instance, ScriptContext *scriptContext);
+        static JavascriptArray*  GetOwnEnumerablePropertyNamesSymbols(RecyclableObject* instance, ScriptContext *scriptContext);
 
 
         static BOOL GetOwnPropertyDescriptor(RecyclableObject* obj, PropertyId propertyId, ScriptContext* scriptContext, PropertyDescriptor* propertyDescriptor);
         static BOOL GetOwnPropertyDescriptor(RecyclableObject* obj, PropertyId propertyId, ScriptContext* scriptContext, PropertyDescriptor* propertyDescriptor);
         static BOOL GetOwnPropertyDescriptor(RecyclableObject* obj, JavascriptString* propertyKey, ScriptContext* scriptContext, PropertyDescriptor* propertyDescriptor);
         static BOOL GetOwnPropertyDescriptor(RecyclableObject* obj, JavascriptString* propertyKey, ScriptContext* scriptContext, PropertyDescriptor* propertyDescriptor);

+ 6 - 5
lib/Runtime/Language/ProfilingHelpers.cpp

@@ -278,7 +278,7 @@ namespace Js
             {
             {
                 length = headSegmentLength;
                 length = headSegmentLength;
                 bool isVirtual = (VirtualTableInfoBase::GetVirtualTable(base) == ValueType::GetVirtualTypedArrayVtable(arrayTypeId));
                 bool isVirtual = (VirtualTableInfoBase::GetVirtualTable(base) == ValueType::GetVirtualTypedArrayVtable(arrayTypeId));
-                stElemInfo.arrayType = ValueType::FromTypeId(arrayTypeId, isVirtual).ToLikely();        
+                stElemInfo.arrayType = ValueType::FromTypeId(arrayTypeId, isVirtual).ToLikely();
                 if (!TaggedNumber::Is(value) && !JavascriptNumber::Is_NoTaggedIntCheck(value))
                 if (!TaggedNumber::Is(value) && !JavascriptNumber::Is_NoTaggedIntCheck(value))
                 {
                 {
                     // Non-number stored to a typed array. A helper call will be needed to convert the value.
                     // Non-number stored to a typed array. A helper call will be needed to convert the value.
@@ -576,9 +576,10 @@ namespace Js
 
 
         args.Values[0] = nullptr;
         args.Values[0] = nullptr;
         Var array;
         Var array;
+        Js::RecyclableObject* calleeObject = RecyclableObject::FromVar(callee);
         if (arrayInfo->IsNativeIntArray())
         if (arrayInfo->IsNativeIntArray())
         {
         {
-            array = JavascriptNativeIntArray::NewInstance(RecyclableObject::FromVar(callee), args);
+            array = JavascriptNativeIntArray::NewInstance(calleeObject, args);
             if (VirtualTableInfo<JavascriptNativeIntArray>::HasVirtualTable(array))
             if (VirtualTableInfo<JavascriptNativeIntArray>::HasVirtualTable(array))
             {
             {
                 JavascriptNativeIntArray *const intArray = static_cast<JavascriptNativeIntArray *>(array);
                 JavascriptNativeIntArray *const intArray = static_cast<JavascriptNativeIntArray *>(array);
@@ -600,7 +601,7 @@ namespace Js
         }
         }
         else if (arrayInfo->IsNativeFloatArray())
         else if (arrayInfo->IsNativeFloatArray())
         {
         {
-            array = JavascriptNativeFloatArray::NewInstance(RecyclableObject::FromVar(callee), args);
+            array = JavascriptNativeFloatArray::NewInstance(calleeObject, args);
             if (VirtualTableInfo<JavascriptNativeFloatArray>::HasVirtualTable(array))
             if (VirtualTableInfo<JavascriptNativeFloatArray>::HasVirtualTable(array))
             {
             {
                 JavascriptNativeFloatArray *const floatArray = static_cast<JavascriptNativeFloatArray *>(array);
                 JavascriptNativeFloatArray *const floatArray = static_cast<JavascriptNativeFloatArray *>(array);
@@ -613,10 +614,10 @@ namespace Js
         }
         }
         else
         else
         {
         {
-            array = JavascriptArray::NewInstance(RecyclableObject::FromVar(callee), args);
+            array = JavascriptArray::NewInstance(calleeObject, args);
         }
         }
 
 
-        return CrossSite::MarshalVar(scriptContext, array);
+        return CrossSite::MarshalVar(scriptContext, array, calleeObject->GetScriptContext());
     }
     }
 
 
     Var ProfilingHelpers::ProfiledNewScObject(
     Var ProfilingHelpers::ProfiledNewScObject(

+ 2 - 2
lib/Runtime/Library/JavascriptArray.cpp

@@ -4884,7 +4884,7 @@ Case0:
         }
         }
         else
         else
         {
         {
-            element = CrossSite::MarshalVar(scriptContext, element);
+            element = CrossSite::MarshalVar(scriptContext, element, arr->GetScriptContext());
         }
         }
         arr->SetLength(index); // SetLength will clear element at index
         arr->SetLength(index); // SetLength will clear element at index
 
 
@@ -5339,7 +5339,7 @@ Case0:
             {
             {
                 RecyclableObject* protoObj = prototype;
                 RecyclableObject* protoObj = prototype;
 
 
-                if (!(DynamicObject::IsAnyArray(protoObj) || JavascriptOperators::IsObject(protoObj)) 
+                if (!(DynamicObject::IsAnyArray(protoObj) || JavascriptOperators::IsObject(protoObj))
                     || JavascriptProxy::Is(protoObj)
                     || JavascriptProxy::Is(protoObj)
                     || protoObj->IsExternal())
                     || protoObj->IsExternal())
                 {
                 {

+ 13 - 12
lib/Runtime/Library/JavascriptExternalFunction.cpp

@@ -285,20 +285,21 @@ namespace Js
         END_LEAVE_SCRIPT(scriptContext);
         END_LEAVE_SCRIPT(scriptContext);
 #endif
 #endif
 
 
-        if (result != nullptr && !Js::TaggedNumber::Is(result))
+        bool marshallingMayBeNeeded = false;
+        if (result != nullptr)
         {
         {
-            if (!Js::RecyclableObject::Is(result))
+            marshallingMayBeNeeded = Js::RecyclableObject::Is(result);
+            if (marshallingMayBeNeeded)
             {
             {
-                Js::Throw::InternalError();
-            }
-
-            Js::RecyclableObject * obj = Js::RecyclableObject::FromVar(result);
+                Js::RecyclableObject * obj = Js::RecyclableObject::FromVar(result);
 
 
-            // For JSRT, we could get result marshalled in different context.
-            bool isJSRT = scriptContext->GetThreadContext()->IsJSRT();
-            if (!isJSRT && obj->GetScriptContext() != scriptContext)
-            {
-                Js::Throw::InternalError();
+                // For JSRT, we could get result marshalled in different context.
+                bool isJSRT = scriptContext->GetThreadContext()->IsJSRT();
+                marshallingMayBeNeeded = obj->GetScriptContext() != scriptContext;
+                if (!isJSRT && marshallingMayBeNeeded)
+                {
+                    Js::Throw::InternalError();
+                }
             }
             }
         }
         }
 
 
@@ -324,7 +325,7 @@ namespace Js
         {
         {
             result = scriptContext->GetLibrary()->GetUndefined();
             result = scriptContext->GetLibrary()->GetUndefined();
         }
         }
-        else
+        else if (marshallingMayBeNeeded)
         {
         {
             result = CrossSite::MarshalVar(scriptContext, result);
             result = CrossSite::MarshalVar(scriptContext, result);
         }
         }

+ 5 - 3
lib/Runtime/Library/JavascriptFunction.cpp

@@ -653,8 +653,10 @@ namespace Js
         ScriptContext* scriptContext = func->GetScriptContext();
         ScriptContext* scriptContext = func->GetScriptContext();
         if (scriptContext->GetThreadContext()->HasPreviousHostScriptContext())
         if (scriptContext->GetThreadContext()->HasPreviousHostScriptContext())
         {
         {
-            ScriptContext* requestContext = scriptContext->GetThreadContext()->GetPreviousHostScriptContext()->GetScriptContext();
-            func = JavascriptFunction::FromVar(CrossSite::MarshalVar(requestContext, func));
+            ScriptContext* requestContext = scriptContext->GetThreadContext()->
+              GetPreviousHostScriptContext()->GetScriptContext();
+            func = JavascriptFunction::FromVar(CrossSite::MarshalVar(requestContext,
+              func, scriptContext));
         }
         }
         return func->CallRootFunction(args, scriptContext, true);
         return func->CallRootFunction(args, scriptContext, true);
     }
     }
@@ -2821,7 +2823,7 @@ LABEL1:
             }
             }
             else
             else
             {
             {
-                *value = CrossSite::MarshalVar(requestContext, funcCaller);
+                *value = CrossSite::MarshalVar(requestContext, funcCaller, funcCaller->GetScriptContext());
             }
             }
         }
         }
 
 

+ 1 - 1
lib/Runtime/Library/JavascriptNumber.cpp

@@ -898,7 +898,7 @@ namespace Js
         else if (JavascriptNumberObject::Is(value))
         else if (JavascriptNumberObject::Is(value))
         {
         {
             JavascriptNumberObject* obj = JavascriptNumberObject::FromVar(value);
             JavascriptNumberObject* obj = JavascriptNumberObject::FromVar(value);
-            return CrossSite::MarshalVar(scriptContext, obj->Unwrap());
+            return CrossSite::MarshalVar(scriptContext, obj->Unwrap(), obj->GetScriptContext());
         }
         }
         else if (Js::JavascriptOperators::GetTypeId(value) == TypeIds_Int64Number)
         else if (Js::JavascriptOperators::GetTypeId(value) == TypeIds_Int64Number)
         {
         {

+ 2 - 1
lib/Runtime/Library/JavascriptObject.cpp

@@ -1040,6 +1040,7 @@ namespace Js
                 if (propertyDescriptor.IsEnumerable())
                 if (propertyDescriptor.IsEnumerable())
                 {
                 {
                     Var value = JavascriptOperators::GetProperty(object, propertyId, scriptContext);
                     Var value = JavascriptOperators::GetProperty(object, propertyId, scriptContext);
+
                     if (!valuesToReturn)
                     if (!valuesToReturn)
                     {
                     {
                         // For Object.entries each entry is key, value pair
                         // For Object.entries each entry is key, value pair
@@ -1168,7 +1169,7 @@ namespace Js
                 }
                 }
                 if (includeStringProperties)
                 if (includeStringProperties)
                 {
                 {
-                    newArr->DirectSetItemAt(propertyIndex++, CrossSite::MarshalVar(scriptContext, propertyName));
+                    newArr->DirectSetItemAt(propertyIndex++, CrossSite::MarshalVar(scriptContext, propertyName, propertyName->GetScriptContext()));
                 }
                 }
             }
             }
         }
         }

+ 7 - 5
lib/Runtime/Library/JavascriptProxy.cpp

@@ -588,7 +588,7 @@ namespace Js
         }
         }
         return FALSE;
         return FALSE;
     }
     }
-  
+
     BOOL JavascriptProxy::GetAccessors(PropertyId propertyId, __out Var* getter, __out Var* setter, ScriptContext * requestContext)
     BOOL JavascriptProxy::GetAccessors(PropertyId propertyId, __out Var* getter, __out Var* setter, ScriptContext * requestContext)
     {
     {
         PropertyDescriptor result;
         PropertyDescriptor result;
@@ -681,7 +681,7 @@ namespace Js
         }
         }
         else
         else
         {
         {
-            // ES2017 Spec'ed (9.1.9.1): 
+            // ES2017 Spec'ed (9.1.9.1):
             // If existingDescriptor is not undefined, then
             // If existingDescriptor is not undefined, then
             //    If IsAccessorDescriptor(existingDescriptor) is true, return false.
             //    If IsAccessorDescriptor(existingDescriptor) is true, return false.
             //    If existingDescriptor.[[Writable]] is false, return false.
             //    If existingDescriptor.[[Writable]] is false, return false.
@@ -1031,7 +1031,8 @@ namespace Js
                                 // if (desc.enumerable) yield key;
                                 // if (desc.enumerable) yield key;
                                 if (desc.IsEnumerable())
                                 if (desc.IsEnumerable())
                                 {
                                 {
-                                    return JavascriptString::FromVar(CrossSite::MarshalVar(scriptContext, propertyName));
+                                    return JavascriptString::FromVar(CrossSite::MarshalVar(
+                                      scriptContext, propertyName, propertyName->GetScriptContext()));
                                 }
                                 }
                             }
                             }
                         }
                         }
@@ -1975,9 +1976,10 @@ namespace Js
             JavascriptError::ThrowTypeError(requestContext, JSERR_NeedFunction, requestContext->GetPropertyName(methodId)->GetBuffer());
             JavascriptError::ThrowTypeError(requestContext, JSERR_NeedFunction, requestContext->GetPropertyName(methodId)->GetBuffer());
         }
         }
 
 
-        varMethod = CrossSite::MarshalVar(requestContext, varMethod);
+        JavascriptFunction* function = JavascriptFunction::FromVar(varMethod);
 
 
-        return JavascriptFunction::FromVar(varMethod);
+        return JavascriptFunction::FromVar(CrossSite::MarshalVar(requestContext,
+          function, function->GetScriptContext()));
     }
     }
 
 
     Var JavascriptProxy::GetValueFromDescriptor(Var instance, PropertyDescriptor propertyDescriptor, ScriptContext* requestContext)
     Var JavascriptProxy::GetValueFromDescriptor(Var instance, PropertyDescriptor propertyDescriptor, ScriptContext* requestContext)

+ 3 - 1
lib/Runtime/Library/JavascriptString.cpp

@@ -3079,7 +3079,9 @@ case_2:
 
 
             // a. Let s be the value of value's [[StringData]] internal slot.
             // a. Let s be the value of value's [[StringData]] internal slot.
             // b. If s is not undefined, then return s.
             // b. If s is not undefined, then return s.
-            *pString = JavascriptString::FromVar(CrossSite::MarshalVar(scriptContext, pStringObj->Unwrap()));
+            *pString = pStringObj->Unwrap();
+            *pString = JavascriptString::FromVar(CrossSite::MarshalVar(scriptContext,
+              *pString, pStringObj->GetScriptContext()));
             return TRUE;
             return TRUE;
         }
         }
 
 

+ 7 - 2
lib/Runtime/Library/JavascriptStringObject.cpp

@@ -246,7 +246,9 @@ namespace Js
         uint32 index;
         uint32 index;
         if (scriptContext->IsNumericPropertyId(propertyId, &index))
         if (scriptContext->IsNumericPropertyId(propertyId, &index))
         {
         {
-            JavascriptString* str = JavascriptString::FromVar(CrossSite::MarshalVar(requestContext, this->InternalUnwrap()));
+            JavascriptString* str = this->InternalUnwrap();
+            str = JavascriptString::FromVar(CrossSite::MarshalVar(requestContext, str, scriptContext));
+
             return JavascriptConversion::BooleanToPropertyQueryFlags(str->GetItemAt(index, value));
             return JavascriptConversion::BooleanToPropertyQueryFlags(str->GetItemAt(index, value));
         }
         }
 
 
@@ -354,7 +356,10 @@ namespace Js
 
 
     PropertyQueryFlags JavascriptStringObject::GetItemQuery(Var originalInstance, uint32 index, Var* value, ScriptContext* requestContext)
     PropertyQueryFlags JavascriptStringObject::GetItemQuery(Var originalInstance, uint32 index, Var* value, ScriptContext* requestContext)
     {
     {
-        JavascriptString* str = JavascriptString::FromVar(CrossSite::MarshalVar(requestContext, this->InternalUnwrap()));
+        Var strObject = CrossSite::MarshalVar(requestContext,
+          this->InternalUnwrap(), this->GetScriptContext());
+
+        JavascriptString* str = JavascriptString::FromVar(strObject);
         if (str->GetItemAt(index, value))
         if (str->GetItemAt(index, value))
         {
         {
             return PropertyQueryFlags::Property_Found;
             return PropertyQueryFlags::Property_Found;

+ 11 - 9
lib/Runtime/Types/TypePropertyCache.cpp

@@ -216,7 +216,8 @@ namespace Js
                 isInlineSlot
                 isInlineSlot
                     ? DynamicObject::FromVar(propertyObject)->GetInlineSlot(propertyIndex)
                     ? DynamicObject::FromVar(propertyObject)->GetInlineSlot(propertyIndex)
                     : DynamicObject::FromVar(propertyObject)->GetAuxSlot(propertyIndex);
                     : DynamicObject::FromVar(propertyObject)->GetAuxSlot(propertyIndex);
-            if(propertyObject->GetScriptContext() == requestContext)
+
+            if (propertyObject->GetScriptContext() == requestContext)
             {
             {
                 Assert(*propertyValue == JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext));
                 Assert(*propertyValue == JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext));
 
 
@@ -235,8 +236,10 @@ namespace Js
                     requestContext);
                     requestContext);
                 return true;
                 return true;
             }
             }
-
-            *propertyValue = CrossSite::MarshalVar(requestContext, *propertyValue);
+            else
+            {
+                *propertyValue = CrossSite::MarshalVar(requestContext, *propertyValue);
+            }
             // Cannot use GetProperty and compare results since they may not compare equal when they're marshaled
             // Cannot use GetProperty and compare results since they may not compare equal when they're marshaled
 
 
             if(operationInfo)
             if(operationInfo)
@@ -296,8 +299,10 @@ namespace Js
                 requestContext);
                 requestContext);
             return true;
             return true;
         }
         }
-
-        *propertyValue = CrossSite::MarshalVar(requestContext, *propertyValue);
+        else
+        {
+            *propertyValue = CrossSite::MarshalVar(requestContext, *propertyValue);
+        }
         // Cannot use GetProperty and compare results since they may not compare equal when they're marshaled
         // Cannot use GetProperty and compare results since they may not compare equal when they're marshaled
 
 
         if(operationInfo)
         if(operationInfo)
@@ -362,10 +367,7 @@ namespace Js
         Assert(object->CanStorePropertyValueDirectly(propertyId, false));
         Assert(object->CanStorePropertyValueDirectly(propertyId, false));
 
 
         ScriptContext *const objectScriptContext = object->GetScriptContext();
         ScriptContext *const objectScriptContext = object->GetScriptContext();
-        if(objectScriptContext != requestContext)
-        {
-            propertyValue = CrossSite::MarshalVar(objectScriptContext, propertyValue);
-        }
+        propertyValue = CrossSite::MarshalVar(objectScriptContext, propertyValue, objectScriptContext);
 
 
         if(isInlineSlot)
         if(isInlineSlot)
         {
         {