| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "RuntimeLibraryPch.h"
- namespace Js
- {
- ModuleRoot::ModuleRoot(DynamicType * type):
- RootObjectBase(type)
- {
- }
- void ModuleRoot::SetHostObject(ModuleID moduleID, HostObjectBase * hostObject)
- {
- this->moduleID = moduleID;
- __super::SetHostObject(hostObject);
- }
- PropertyQueryFlags ModuleRoot::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
- {
- if (JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId, info)))
- {
- return PropertyQueryFlags::Property_Found;
- }
- else if (this->hostObject && JavascriptOperators::HasProperty(this->hostObject, propertyId))
- {
- return PropertyQueryFlags::Property_Found;
- }
- return this->GetLibrary()->GetGlobalObject()->GlobalObject::HasPropertyQuery(propertyId, info);
- }
- BOOL ModuleRoot::EnsureProperty(PropertyId propertyId)
- {
- if (!RootObjectBase::HasOwnPropertyCheckNoRedecl(propertyId))
- {
- // Cannot pass the extra PropertyOperation_PreInit flag, because module root uses SetSlot directly from
- // SetRootProperty. If the property is not yet initialized SetSlot will (correctly) assert.
- this->InitProperty(propertyId, this->GetLibrary()->GetUndefined(), (PropertyOperationFlags)(PropertyOperation_SpecialValue | PropertyOperation_NonFixedValue));
- }
- return true;
- }
- BOOL ModuleRoot::HasRootProperty(PropertyId propertyId)
- {
- if (__super::HasRootProperty(propertyId))
- {
- return TRUE;
- }
- else if (this->hostObject && JavascriptOperators::HasProperty(this->hostObject, propertyId))
- {
- return TRUE;
- }
- return this->GetLibrary()->GetGlobalObject()->GlobalObject::HasRootProperty(propertyId);
- }
- BOOL ModuleRoot::HasOwnProperty(PropertyId propertyId)
- {
- return JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId, nullptr /*info*/));
- }
- PropertyQueryFlags ModuleRoot::GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
- {
- PropertyIndex index = GetPropertyIndex(propertyId);
- if (index != Constants::NoSlot)
- {
- *value = this->GetSlot(index);
- if (info) // Avoid testing IsWritable if info not being queried
- {
- PropertyValueInfo::Set(info, this, index, IsWritable(propertyId) ? PropertyWritable : PropertyNone);
- #if ENABLE_FIXED_FIELDS
- if (this->IsFixedProperty(propertyId))
- {
- PropertyValueInfo::DisableStoreFieldCache(info);
- }
- #endif
- }
- return PropertyQueryFlags::Property_Found;
- }
- if (this->hostObject && JavascriptOperators::GetProperty(this->hostObject, propertyId, value, requestContext))
- {
- return PropertyQueryFlags::Property_Found;
- }
- //
- // Try checking the global object
- // if the module root doesn't have the property and the host object also doesn't have it
- //
- GlobalObject* globalObj = this->GetLibrary()->GetGlobalObject();
- return globalObj->GlobalObject::GetPropertyQuery(originalInstance, propertyId, value, NULL, requestContext);
- }
- BOOL ModuleRoot::GetRootProperty(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
- {
- PropertyIndex index = GetRootPropertyIndex(propertyId);
- if (index != Constants::NoSlot)
- {
- *value = this->GetSlot(index);
- if (info) // Avoid testing IsWritable if info not being queried
- {
- PropertyValueInfo::Set(info, this, index, IsWritable(propertyId) ? PropertyWritable : PropertyNone);
- #if ENABLE_FIXED_FIELDS
- if (this->IsFixedProperty(propertyId))
- {
- PropertyValueInfo::DisableStoreFieldCache(info);
- }
- #endif
- }
- return TRUE;
- }
- if (this->hostObject && JavascriptOperators::GetProperty(this->hostObject, propertyId, value, requestContext))
- {
- return TRUE;
- }
- //
- // Try checking the global object
- // if the module root doesn't have the property and the host object also doesn't have it
- //
- GlobalObject* globalObj = this->GetLibrary()->GetGlobalObject();
- return globalObj->GlobalObject::GetRootProperty(originalInstance, propertyId, value, NULL, requestContext);
- }
- PropertyQueryFlags ModuleRoot::GetPropertyQuery(Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
- {
- PropertyRecord const * propertyRecord;
- this->GetScriptContext()->GetOrAddPropertyRecord(propertyNameString, &propertyRecord);
- return ModuleRoot::GetPropertyQuery(originalInstance, propertyRecord->GetPropertyId(), value, info, requestContext);
- }
- _Check_return_ _Success_(return) BOOL ModuleRoot::GetAccessors(PropertyId propertyId, _Outptr_result_maybenull_ Var* getter, _Outptr_result_maybenull_ Var* setter, ScriptContext* requestContext)
- {
- if (DynamicObject::GetAccessors(propertyId, getter, setter, requestContext))
- {
- return TRUE;
- }
- if (this->hostObject)
- {
- return this->hostObject->GetAccessors(propertyId, getter, setter, requestContext);
- }
- // Try checking the global object
- GlobalObject* globalObj = this->GetLibrary()->GetGlobalObject();
- return globalObj->GlobalObject::GetAccessors(propertyId, getter, setter, requestContext);
- }
- PropertyQueryFlags ModuleRoot::GetPropertyReferenceQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info,
- ScriptContext* requestContext)
- {
- PropertyIndex index = GetPropertyIndex(propertyId);
- if (index != Constants::NoSlot)
- {
- *value = this->GetSlot(index);
- if (info) // Avoid testing IsWritable if info not being queried
- {
- PropertyValueInfo::Set(info, this, index, IsWritable(propertyId) ? PropertyWritable : PropertyNone);
- #if ENABLE_FIXED_FIELDS
- if (this->IsFixedProperty(propertyId))
- {
- PropertyValueInfo::DisableStoreFieldCache(info);
- }
- #endif
- }
- return PropertyQueryFlags::Property_Found;
- }
- if (this->hostObject && JavascriptOperators::GetPropertyReference(this->hostObject, propertyId, value, requestContext))
- {
- return PropertyQueryFlags::Property_NotFound;
- }
- //
- // Try checking the global object
- // if the module root doesn't have the property and the host object also doesn't have it
- //
- GlobalObject* globalObj = this->GetLibrary()->GetGlobalObject();
- return globalObj->GlobalObject::GetPropertyReferenceQuery(originalInstance, propertyId, value, NULL, requestContext);
- }
- BOOL ModuleRoot::GetRootPropertyReference(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info,
- ScriptContext* requestContext)
- {
- PropertyIndex index = GetRootPropertyIndex(propertyId);
- if (index != Constants::NoSlot)
- {
- *value = this->GetSlot(index);
- if (info) // Avoid testing IsWritable if info not being queried
- {
- PropertyValueInfo::Set(info, this, index, IsWritable(propertyId) ? PropertyWritable : PropertyNone);
- #if ENABLE_FIXED_FIELDS
- if (this->IsFixedProperty(propertyId))
- {
- PropertyValueInfo::DisableStoreFieldCache(info);
- }
- #endif
- }
- return TRUE;
- }
- if (this->hostObject && JavascriptOperators::GetPropertyReference(this->hostObject, propertyId, value, requestContext))
- {
- return TRUE;
- }
- //
- // Try checking the global object
- // if the module root doesn't have the property and the host object also doesn't have it
- //
- GlobalObject* globalObj = this->GetLibrary()->GetGlobalObject();
- return globalObj->GlobalObject::GetRootPropertyReference(originalInstance, propertyId, value, NULL, requestContext);
- }
- BOOL ModuleRoot::SetProperty(PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info)
- {
- PropertyIndex index = GetPropertyIndex(propertyId);
- if (index != Constants::NoSlot)
- {
- if (this->IsWritable(propertyId) == FALSE)
- {
- JavascriptError::ThrowCantAssignIfStrictMode(flags, this->GetScriptContext());
- #if ENABLE_FIXED_FIELDS
- if (this->IsFixedProperty(propertyId))
- {
- PropertyValueInfo::SetNoCache(info, this);
- }
- else
- #endif
- {
- PropertyValueInfo::Set(info, this, index, PropertyNone); // Try to cache property info even if not writable
- }
- return FALSE;
- }
- this->SetSlot(SetSlotArguments(propertyId, index, value));
- #if ENABLE_FIXED_FIELDS
- if (this->IsFixedProperty(propertyId))
- {
- PropertyValueInfo::SetNoCache(info, this);
- }
- else
- #endif
- {
- PropertyValueInfo::Set(info, this, index);
- }
- return TRUE;
- }
- else if (this->hostObject && this->hostObject->HasProperty(propertyId))
- {
- return this->hostObject->SetProperty(propertyId, value, flags, NULL);
- }
- //
- // Try checking the global object
- // if the module root doesn't have the property and the host object also doesn't have it
- //
- GlobalObject* globalObj = this->GetLibrary()->GetGlobalObject();
- BOOL setAttempted = TRUE;
- if (globalObj->SetExistingProperty(propertyId, value, NULL, &setAttempted))
- {
- return TRUE;
- }
- //
- // Set was attempted. But the set operation returned false.
- // This happens, when the property is read only.
- // In those scenarios, we should be setting the property with default attributes
- //
- if (setAttempted)
- {
- return FALSE;
- }
- return DynamicObject::SetProperty(propertyId, value, flags, info);
- }
- BOOL ModuleRoot::SetRootProperty(PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info)
- {
- PropertyIndex index = GetRootPropertyIndex(propertyId);
- if (index != Constants::NoSlot)
- {
- if (this->IsWritable(propertyId) == FALSE)
- {
- JavascriptError::ThrowCantAssignIfStrictMode(flags, this->GetScriptContext());
- #if ENABLE_FIXED_FIELDS
- if (this->IsFixedProperty(propertyId))
- {
- PropertyValueInfo::SetNoCache(info, this);
- }
- else
- #endif
- {
- PropertyValueInfo::Set(info, this, index, PropertyNone); // Try to cache property info even if not writable
- }
- return FALSE;
- }
- this->SetSlot(SetSlotArgumentsRoot(propertyId, true, index, value));
- #if ENABLE_FIXED_FIELDS
- if (this->IsFixedProperty(propertyId))
- {
- PropertyValueInfo::SetNoCache(info, this);
- }
- else
- #endif
- {
- PropertyValueInfo::Set(info, this, index);
- }
- return TRUE;
- }
- else if (this->hostObject && this->hostObject->HasProperty(propertyId))
- {
- return this->hostObject->SetProperty(propertyId, value, flags, NULL);
- }
- //
- // Try checking the global object
- // if the module root doesn't have the property and the host object also doesn't have it
- //
- GlobalObject* globalObj = this->GetLibrary()->GetGlobalObject();
- BOOL setAttempted = TRUE;
- if (globalObj->SetExistingRootProperty(propertyId, value, NULL, &setAttempted))
- {
- return TRUE;
- }
- //
- // Set was attempted. But the set operation returned false.
- // This happens, when the property is read only.
- // In those scenarios, we should be setting the property with default attributes
- //
- if (setAttempted)
- {
- return FALSE;
- }
- return __super::SetRootProperty(propertyId, value, (PropertyOperationFlags)(flags | PropertyOperation_NonFixedValue), info);
- }
- BOOL ModuleRoot::SetProperty(JavascriptString* propertyNameString, Var value, PropertyOperationFlags flags, PropertyValueInfo* info)
- {
- PropertyRecord const * propertyRecord;
- this->GetScriptContext()->GetOrAddPropertyRecord(propertyNameString, &propertyRecord);
- return ModuleRoot::SetProperty(propertyRecord->GetPropertyId(), value, (PropertyOperationFlags)(flags | PropertyOperation_NonFixedValue), info);
- }
- BOOL ModuleRoot::InitPropertyScoped(PropertyId propertyId, Var value)
- {
- return DynamicObject::InitProperty(propertyId, value, PropertyOperation_NonFixedValue);
- }
- BOOL ModuleRoot::InitFuncScoped(PropertyId propertyId, Var value)
- {
- // Var binding of functions declared in eval are elided when conflicting
- // with global scope let/const variables, so do not actually set the
- // property if it exists and is a let/const variable.
- bool noRedecl = false;
- if (!GetTypeHandler()->HasRootProperty(this, propertyId, &noRedecl) || !noRedecl)
- {
- DynamicObject::InitProperty(propertyId, value, PropertyOperation_NonFixedValue);
- }
- return true;
- }
- BOOL ModuleRoot::SetAccessors(PropertyId propertyId, Var getter, Var setter, PropertyOperationFlags flags)
- {
- if (DynamicObject::SetAccessors(propertyId, getter, setter, flags))
- {
- return TRUE;
- }
- if (this->hostObject)
- {
- return this->hostObject->SetAccessors(propertyId, getter, setter, flags);
- }
- //
- // Try checking the global object
- // if the module root doesn't have the property and the host object also doesn't have it
- //
- GlobalObject* globalObj = GetScriptContext()->GetGlobalObject();
- return globalObj->GlobalObject::SetAccessors(propertyId, getter, setter, flags);
- }
- BOOL ModuleRoot::DeleteProperty(PropertyId propertyId, PropertyOperationFlags flags)
- {
- int index = GetPropertyIndex(propertyId);
- if (index != Constants::NoSlot)
- {
- return FALSE;
- }
- else if (this->hostObject && this->hostObject->HasProperty(propertyId))
- {
- return this->hostObject->DeleteProperty(propertyId, flags);
- }
- return this->GetLibrary()->GetGlobalObject()->GlobalObject::DeleteProperty(propertyId, flags);
- }
- BOOL ModuleRoot::DeleteProperty(JavascriptString *propertyNameString, PropertyOperationFlags flags)
- {
- PropertyRecord const *propertyRecord = nullptr;
- if (JavascriptOperators::ShouldTryDeleteProperty(this, propertyNameString, &propertyRecord))
- {
- Assert(propertyRecord);
- return DeleteProperty(propertyRecord->GetPropertyId(), flags);
- }
- return TRUE;
- }
- BOOL ModuleRoot::DeleteRootProperty(PropertyId propertyId, PropertyOperationFlags flags)
- {
- int index = GetRootPropertyIndex(propertyId);
- if (index != Constants::NoSlot)
- {
- return FALSE;
- }
- else if (this->hostObject && this->hostObject->HasProperty(propertyId))
- {
- return this->hostObject->DeleteProperty(propertyId, flags);
- }
- return this->GetLibrary()->GetGlobalObject()->GlobalObject::DeleteRootProperty(propertyId, flags);
- }
- PropertyQueryFlags ModuleRoot::HasItemQuery(uint32 index)
- {
- return JavascriptConversion::BooleanToPropertyQueryFlags(JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasItemQuery(index))
- || (this->hostObject && JavascriptOperators::HasItem(this->hostObject, index)));
- }
- BOOL ModuleRoot::HasOwnItem(uint32 index)
- {
- return JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasItemQuery(index));
- }
- PropertyQueryFlags ModuleRoot::GetItemReferenceQuery(Var originalInstance, uint32 index, Var* value, ScriptContext * requestContext)
- {
- if (JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::GetItemReferenceQuery(originalInstance, index, value, requestContext)))
- {
- return PropertyQueryFlags::Property_Found;
- }
- if (this->hostObject && JavascriptConversion::PropertyQueryFlagsToBoolean(this->hostObject->GetItemReferenceQuery(originalInstance, index, value, requestContext)))
- {
- return PropertyQueryFlags::Property_Found;
- }
- *value = requestContext->GetMissingItemResult();
- return PropertyQueryFlags::Property_NotFound;
- }
- BOOL ModuleRoot::SetItem(uint32 index, Var value, PropertyOperationFlags flags)
- {
- if (DynamicObject::SetItem(index, value, flags))
- {
- return TRUE;
- }
- if (this->hostObject)
- {
- return this->hostObject->SetItem(index, value, flags);
- }
- return FALSE;
- }
- PropertyQueryFlags ModuleRoot::GetItemQuery(Var originalInstance, uint32 index, Var* value, ScriptContext * requestContext)
- {
- if (JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::GetItemQuery(originalInstance, index, value, requestContext)))
- {
- return PropertyQueryFlags::Property_Found;
- }
- if (this->hostObject && this->hostObject->GetItem(originalInstance, index, value, requestContext))
- {
- return PropertyQueryFlags::Property_Found;
- }
- *value = requestContext->GetMissingItemResult();
- return PropertyQueryFlags::Property_NotFound;
- }
- BOOL ModuleRoot::GetDiagValueString(StringBuilder<ArenaAllocator>* stringBuilder, ScriptContext* requestContext)
- {
- stringBuilder->AppendCppLiteral(_u("{Named Item}"));
- return TRUE;
- }
- BOOL ModuleRoot::GetDiagTypeString(StringBuilder<ArenaAllocator>* stringBuilder, ScriptContext* requestContext)
- {
- stringBuilder->AppendCppLiteral(_u("Object, (Named Item)"));
- return TRUE;
- }
- }
|