RecyclableObject* ForInObjectEnumerator::GetFirstPrototypeWithEnumerableProperties(RecyclableObject* object) { RecyclableObject* firstPrototype = nullptr; if (JavascriptOperators::GetTypeId(object) != TypeIds_HostDispatch) { firstPrototype = object; while (true) { firstPrototype = firstPrototype->GetPrototype(); if (JavascriptOperators::GetTypeId(firstPrototype) == TypeIds_Null) { firstPrototype = nullptr; break; } if (!DynamicType::Is(firstPrototype->GetTypeId()) || !DynamicObject::FromVar(firstPrototype)->GetHasNoEnumerableProperties()) { break; } } } return firstPrototype; }
DynamicObject* DynamicObject::FromVar(Var aValue) { RecyclableObject* obj = RecyclableObject::FromVar(aValue); AssertMsg(obj->DbgIsDynamicObject(), "Ensure instance is actually a DynamicObject"); Assert(DynamicType::Is(obj->GetTypeId())); return static_cast<DynamicObject*>(obj); }
void CrossSite::MarshalPrototypeChain(ScriptContext* scriptContext, DynamicObject * object) { RecyclableObject * prototype = object->GetPrototype(); while (prototype->GetTypeId() != TypeIds_Null && prototype->GetTypeId() != TypeIds_HostDispatch) { // We should not see any static type or host dispatch here DynamicObject * prototypeObject = DynamicObject::FromVar(prototype); if (prototypeObject->IsCrossSiteObject()) { break; } if (scriptContext != prototypeObject->GetScriptContext() && !prototypeObject->IsExternal()) { MarshalDynamicObject(scriptContext, prototypeObject); } prototype = prototypeObject->GetPrototype(); } }
BOOL ForInObjectEnumerator::InitializeCurrentEnumerator(RecyclableObject * object, ForInCache * forInCache) { EnumeratorFlags flags = enumerator.GetFlags(); RecyclableObject * prototype = object->GetPrototype(); if (prototype == nullptr || prototype->GetTypeId() == TypeIds_Null) { // If this is the last object on the prototype chain, we don't need to get the non-enumerable properties any more to track shadowing flags &= ~EnumeratorFlags::EnumNonEnumerable; } return InitializeCurrentEnumerator(object, flags, GetScriptContext(), forInCache); }
BOOL CrossSite::NeedMarshalVar(Var instance, ScriptContext * requestContext) { if (TaggedNumber::Is(instance)) { return FALSE; } RecyclableObject * object = RecyclableObject::UnsafeFromVar(instance); if (object->GetScriptContext() == requestContext) { return FALSE; } if (DynamicType::Is(object->GetTypeId())) { return !DynamicObject::UnsafeFromVar(object)->IsCrossSiteObject() && !object->IsExternal(); } return TRUE; }