void RegexPattern::Finalize(bool isShutdown) { if(isShutdown) return; const auto scriptContext = GetScriptContext(); if(!scriptContext) return; #if DBG if(!isLiteral && !scriptContext->IsClosed()) { const auto source = GetSource(); RegexPattern *p; Assert( !GetScriptContext()->GetDynamicRegexMap()->TryGetValue( RegexKey(source.GetBuffer(), source.GetLength(), GetFlags()), &p) || ( source.GetLength() == 0 ) || p != this); } #endif if(isShallowClone) return; rep.unified.program->FreeBody(scriptContext->RegexAllocator()); }
BOOL JavascriptRegExpConstructor::DeleteProperty(PropertyId propertyId, PropertyOperationFlags flags) { switch (propertyId) { // all globals are 'fNoDelete' in V5.8 case PropertyIds::input: case PropertyIds::$_: case PropertyIds::lastMatch: case PropertyIds::$Ampersand: case PropertyIds::lastParen: case PropertyIds::$Plus: case PropertyIds::leftContext: case PropertyIds::$BackTick: case PropertyIds::rightContext: case PropertyIds::$Tick: case PropertyIds::$1: case PropertyIds::$2: case PropertyIds::$3: case PropertyIds::$4: case PropertyIds::$5: case PropertyIds::$6: case PropertyIds::$7: case PropertyIds::$8: case PropertyIds::$9: case PropertyIds::index: JavascriptError::ThrowCantDeleteIfStrictMode(flags, GetScriptContext(), GetScriptContext()->GetPropertyName(propertyId)->GetBuffer()); return false; default: return JavascriptFunction::DeleteProperty(propertyId, flags); } }
SharedArrayBuffer::SharedArrayBuffer(uint32 length, DynamicType * type, Allocator allocator) : ArrayBufferBase(type), sharedContents(nullptr) { BYTE * buffer = nullptr; if (length > MaxSharedArrayBufferLength) { JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_FunctionArgument_Invalid); } else if (length > 0) { Recycler* recycler = GetType()->GetLibrary()->GetRecycler(); if (recycler->ReportExternalMemoryAllocation(length)) { buffer = (BYTE*)allocator(length); if (buffer == nullptr) { recycler->ReportExternalMemoryFree(length); } } if (buffer == nullptr) { recycler->CollectNow<CollectOnTypedArrayAllocation>(); if (recycler->ReportExternalMemoryAllocation(length)) { buffer = (BYTE*)allocator(length); if (buffer == nullptr) { recycler->ReportExternalMemoryFailure(length); } } else { JavascriptError::ThrowOutOfMemoryError(GetScriptContext()); } } if (buffer != nullptr) { ZeroMemory(buffer, length); sharedContents = HeapNew(SharedContents, buffer, length); if (sharedContents == nullptr) { recycler->ReportExternalMemoryFailure(length); // What else could we do? JavascriptError::ThrowOutOfMemoryError(GetScriptContext()); } #if DBG sharedContents->AddAgent((DWORD_PTR)GetScriptContext()); #endif } } }
SharedArrayBuffer::SharedArrayBuffer(SharedContents * contents, DynamicType * type) : ArrayBufferBase(type), sharedContents(contents) { if (sharedContents == nullptr || sharedContents->bufferLength > MaxSharedArrayBufferLength) { JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_FunctionArgument_Invalid); } InterlockedIncrement(&sharedContents->refCount); #if DBG sharedContents->AddAgent((DWORD_PTR)GetScriptContext()); #endif }
void ArrayObject::ThrowItemNotConfigurableError(PropertyId propId /*= Constants::NoProperty*/) { ScriptContext* scriptContext = GetScriptContext(); JavascriptError::ThrowTypeError(scriptContext, JSERR_DefineProperty_NotConfigurable, propId != Constants::NoProperty ? scriptContext->GetThreadContext()->GetPropertyName(propId)->GetBuffer() : nullptr); }
BOOL JavascriptStringObject::GetProperty(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) { BOOL result; if (GetPropertyBuiltIns(propertyId, value, requestContext, &result)) { return result; } if (DynamicObject::GetProperty(originalInstance, propertyId, value, info, requestContext)) { return true; } // For NumericPropertyIds check that index is less than JavascriptString length ScriptContext*scriptContext = GetScriptContext(); uint32 index; if (scriptContext->IsNumericPropertyId(propertyId, &index)) { JavascriptString* str = JavascriptString::FromVar(CrossSite::MarshalVar(requestContext, this->InternalUnwrap())); return str->GetItemAt(index, value); } *value = requestContext->GetMissingPropertyResult(); return false; }
PropertyQueryFlags JavascriptStringObject::GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) { BOOL result; if (GetPropertyBuiltIns(propertyId, value, requestContext, &result)) { return JavascriptConversion::BooleanToPropertyQueryFlags(result); } if (JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::GetPropertyQuery(originalInstance, propertyId, value, info, requestContext))) { return PropertyQueryFlags::Property_Found; } // For NumericPropertyIds check that index is less than JavascriptString length ScriptContext*scriptContext = GetScriptContext(); uint32 index; if (scriptContext->IsNumericPropertyId(propertyId, &index)) { JavascriptString* str = this->InternalUnwrap(); str = JavascriptString::FromVar(CrossSite::MarshalVar(requestContext, str, scriptContext)); return JavascriptConversion::BooleanToPropertyQueryFlags(str->GetItemAt(index, value)); } *value = requestContext->GetMissingPropertyResult(); return PropertyQueryFlags::Property_NotFound; }
BOOL ForInObjectEnumerator::GetCurrentEnumerator() { Assert(object); ScriptContext* scriptContext = GetScriptContext(); if (VirtualTableInfo<DynamicObject>::HasVirtualTable(object)) { DynamicObject* dynamicObject = (DynamicObject*)object; if (!dynamicObject->GetTypeHandler()->EnsureObjectReady(dynamicObject)) { return false; } dynamicObject->GetDynamicType()->PrepareForTypeSnapshotEnumeration(); embeddedEnumerator.Initialize(dynamicObject, true); currentEnumerator = &embeddedEnumerator; return true; } if (!object->GetEnumerator(TRUE /*enumNonEnumerable*/, (Var *)¤tEnumerator, scriptContext, true /*preferSnapshotSemantics */, enumSymbols)) { currentEnumerator = scriptContext->GetLibrary()->GetNullEnumerator(); return false; } return true; }
PolymorphicInlineCache * PropertyString::CreateBiggerPolymorphicInlineCache(bool isLdElem) { PolymorphicInlineCache * polymorphicInlineCache = isLdElem ? GetLdElemInlineCache() : GetStElemInlineCache(); Assert(polymorphicInlineCache && polymorphicInlineCache->CanAllocateBigger()); uint16 polymorphicInlineCacheSize = polymorphicInlineCache->GetSize(); uint16 newPolymorphicInlineCacheSize = PolymorphicInlineCache::GetNextSize(polymorphicInlineCacheSize); Assert(newPolymorphicInlineCacheSize > polymorphicInlineCacheSize); PolymorphicInlineCache * newPolymorphicInlineCache = ScriptContextPolymorphicInlineCache::New(newPolymorphicInlineCacheSize, GetLibrary()); polymorphicInlineCache->CopyTo(this->propertyRecord->GetPropertyId(), GetScriptContext(), newPolymorphicInlineCache); if (isLdElem) { this->ldElemInlineCache = newPolymorphicInlineCache; } else { this->stElemInlineCache = newPolymorphicInlineCache; } #ifdef ENABLE_DEBUG_CONFIG_OPTIONS if (PHASE_VERBOSE_TRACE1(Js::PolymorphicInlineCachePhase) || PHASE_TRACE1(PropertyStringCachePhase)) { Output::Print(_u("PropertyString '%s' : Bigger PIC, oldSize = %d, newSize = %d\n"), GetString(), polymorphicInlineCacheSize, newPolymorphicInlineCacheSize); } #endif return newPolymorphicInlineCache; }
BOOL ModuleNamespace::FindNextProperty(BigPropertyIndex& index, JavascriptString** propertyString, PropertyId* propertyId, PropertyAttributes* attributes) const { if (index < propertyMap->Count()) { SimpleDictionaryPropertyDescriptor<BigPropertyIndex> propertyDescriptor(propertyMap->GetValueAt(index)); Assert(propertyDescriptor.Attributes == PropertyModuleNamespaceDefault); const PropertyRecord* propertyRecord = propertyMap->GetKeyAt(index); *propertyId = propertyRecord->GetPropertyId(); if (propertyString != nullptr) { *propertyString = GetScriptContext()->GetPropertyString(*propertyId); } if (attributes != nullptr) { *attributes = propertyDescriptor.Attributes; } return TRUE; } else { *propertyId = Constants::NoProperty; if (propertyString != nullptr) { *propertyString = nullptr; } } return FALSE; }
// We will make sure the iterator will iterate through the exported properties in sorted order. // There is no such requirement for enumerator (forin). ListForListIterator* ModuleNamespace::EnsureSortedExportedNames() { if (sortedExportedNames == nullptr) { ExportedNames* exportedNames = moduleRecord->GetExportedNames(nullptr); ScriptContext* scriptContext = GetScriptContext(); sortedExportedNames = ListForListIterator::New(scriptContext->GetRecycler()); exportedNames->Map([&](PropertyId propertyId) { JavascriptString* propertyString = scriptContext->GetPropertyString(propertyId); sortedExportedNames->Add(propertyString); }); sortedExportedNames->Sort([](void* context, const void* left, const void* right) ->int { JavascriptString** leftString = (JavascriptString**) (left); JavascriptString** rightString = (JavascriptString**) (right); if (JavascriptString::LessThan(*leftString, *rightString)) { return -1; } if (JavascriptString::LessThan(*rightString, *leftString)) { return 1; } return 0; }, nullptr); } return sortedExportedNames; }
BOOL JavascriptNumberObject::GetDiagValueString(StringBuilder<ArenaAllocator>* stringBuilder, ScriptContext* requestContext) { ENTER_PINNED_SCOPE(JavascriptString, valueStr); valueStr = JavascriptNumber::ToStringRadix10(this->GetValue(), GetScriptContext()); stringBuilder->Append(valueStr->GetString(), valueStr->GetLength()); LEAVE_PINNED_SCOPE(); return TRUE; }
void JavascriptSet::Add(Var value) { if (!set->ContainsKey(value)) { SetDataNode* node = list.Append(value, GetScriptContext()->GetRecycler()); set->Add(value, node); } }
BOOL ModuleNamespaceEnumerator::Init() { if (!nsObject->DynamicObject::GetEnumerator(&symbolEnumerator, flags, GetScriptContext())) { return FALSE; } nonLocalMap = nsObject->GetUnambiguousNonLocalExports(); Reset(); return TRUE; }
JavascriptString* JavascriptStringObject::InternalUnwrap() { if (value == nullptr) { ScriptContext* scriptContext = GetScriptContext(); value = scriptContext->GetLibrary()->GetEmptyString(); } return value; }
void ModuleNamespace::AddUnambiguousNonLocalExport(PropertyId propertyId, ModuleNameRecord* nonLocalExportNameRecord) { Recycler* recycler = GetScriptContext()->GetRecycler(); if (unambiguousNonLocalExports == nullptr) { unambiguousNonLocalExports = RecyclerNew(recycler, UnambiguousExportMap, recycler, 4); } // keep a local copy of the module/ unambiguousNonLocalExports->AddNew(propertyId, *nonLocalExportNameRecord); }
bool ES5Array::GetPropertyBuiltIns(PropertyId propertyId, Var* value, BOOL* result) { if (propertyId == PropertyIds::length) { *value = JavascriptNumber::ToVar(this->GetLength(), GetScriptContext()); *result = true; return true; } return false; }
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); }
SharedArrayBuffer::SharedArrayBuffer(SharedContents * contents, DynamicType * type) : ArrayBufferBase(type), sharedContents(nullptr) { if (contents == nullptr || contents->bufferLength > MaxSharedArrayBufferLength) { JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_FunctionArgument_Invalid); } if (contents->AddRef() > 1) { sharedContents = contents; } else { Js::Throw::FatalInternalError(); } #if DBG sharedContents->AddAgent((DWORD_PTR)GetScriptContext()); #endif }
ArrayObject* DynamicObject::EnsureObjectArray() { if (!HasObjectArray()) { ScriptContext* scriptContext = GetScriptContext(); ArrayObject* objArray = scriptContext->GetLibrary()->CreateArray(0, SparseArraySegmentBase::SMALL_CHUNK_SIZE); SetObjectArray(objArray); } Assert(HasObjectArray()); return GetObjectArrayOrFlagsAsArray(); }
Var ModuleNamespace::GetNextProperty(BigPropertyIndex& index) { PropertyId propertyId; Var result = GetLibrary()->GetUndefined(); BOOL retVal = FALSE; if (this->FindNextProperty(index, nullptr, &propertyId, nullptr)) { retVal = this->GetProperty(this, propertyId, &result, nullptr, GetScriptContext()); Assert(retVal); } return result; }
PropertyQueryFlags HeapArgumentsObject::HasPropertyQuery(PropertyId id, _Inout_opt_ PropertyValueInfo* info) { ScriptContext *scriptContext = GetScriptContext(); // Try to get a numbered property that maps to an actual argument. uint32 index; if (scriptContext->IsNumericPropertyId(id, &index) && index < this->HeapArgumentsObject::GetNumberOfArguments()) { return HeapArgumentsObject::HasItemQuery(index); } return DynamicObject::HasPropertyQuery(id, info); }
Var DiagNativeStackFrame::CreateHeapArguments() { // We would be creating the arguments object if there is no default arguments object present. Assert(GetArgumentsObject() == NULL); CallInfo const * callInfo = (CallInfo const *)&(((void **)m_stackAddr)[JavascriptFunctionArgIndex_CallInfo]); // At the least we will have 'this' by default. Assert(callInfo->Count > 0); // Get the passed parameter's position (which is starting from 'this') Var * inParams = (Var *)&(((void **)m_stackAddr)[JavascriptFunctionArgIndex_This]); return JavascriptOperators::LoadHeapArguments( m_function, callInfo->Count - 1, &inParams[1], GetScriptContext()->GetLibrary()->GetNull(), (PropertyId*)GetScriptContext()->GetLibrary()->GetNull(), GetScriptContext(), /* formalsAreLetDecls */ false); }
JavascriptWeakMap::WeakMapKeyMap* JavascriptWeakMap::AddWeakMapKeyMapToKey(DynamicObject* key) { // The internal property may exist on an object that has had DynamicObject::ResetObject called on itself. // In that case the value stored in the property slot should be null. DebugOnly(Var unused = nullptr); Assert(!key->GetInternalProperty(key, InternalPropertyIds::WeakMapKeyMap, &unused, nullptr, nullptr) || unused == nullptr); WeakMapKeyMap* weakMapKeyData = RecyclerNew(GetScriptContext()->GetRecycler(), WeakMapKeyMap, GetScriptContext()->GetRecycler()); BOOL success = key->SetInternalProperty(InternalPropertyIds::WeakMapKeyMap, weakMapKeyData, PropertyOperation_Force, nullptr); Assert(success); return weakMapKeyData; }
BOOL ForInObjectEnumerator::InitializeCurrentEnumerator() { Assert(object); ScriptContext* scriptContext = GetScriptContext(); EnumeratorFlags flags = EnumeratorFlags::EnumNonEnumerable | EnumeratorFlags::SnapShotSemantics | (enumSymbols ? EnumeratorFlags::EnumSymbols : EnumeratorFlags::None); if (VirtualTableInfo<DynamicObject>::HasVirtualTable(object)) { DynamicObject* dynamicObject = (DynamicObject*)object; return dynamicObject->DynamicObject::GetEnumerator(&enumerator, flags, scriptContext); } return object->GetEnumerator(&enumerator, flags, scriptContext); }
bool JavascriptStringObject::IsValidIndex(PropertyId propertyId, bool conditionMetBehavior) { ScriptContext*scriptContext = GetScriptContext(); uint32 index; if (scriptContext->IsNumericPropertyId(propertyId, &index)) { if (index < (uint32)this->InternalUnwrap()->GetLength()) { return conditionMetBehavior; } } return !conditionMetBehavior; }
BOOL ES5Array::SetPropertyWithAttributes(PropertyId propertyId, Var value, PropertyAttributes attributes, PropertyValueInfo* info, PropertyOperationFlags flags, SideEffects possibleSideEffects) { if (propertyId == PropertyIds::length) { Assert(attributes == PropertyWritable); Assert(IsWritable(propertyId) && !IsConfigurable(propertyId) && !IsEnumerable(propertyId)); uint32 newLen = ToLengthValue(value, GetScriptContext()); GetTypeHandler()->SetLength(this, newLen, PropertyOperation_None); return true; } return __super::SetPropertyWithAttributes(propertyId, value, attributes, info, flags, possibleSideEffects); }
void JavascriptMap::Set(Var key, Var value) { if (map->ContainsKey(key)) { MapDataNode* node = map->Item(key); node->data = MapDataKeyValuePair(key, value); } else { MapDataKeyValuePair pair(key, value); MapDataNode* node = list.Append(pair, GetScriptContext()->GetRecycler()); map->Add(key, node); } }
void ES5ArrayEnumerator::Reset() { initialLength = arrayObject->GetLength(); dataIndex = JavascriptArray::InvalidIndex; descriptorIndex = JavascriptArray::InvalidIndex; descriptor = nullptr; descriptorValidationToken = nullptr; index = JavascriptArray::InvalidIndex; doneArray = false; doneObject = false; Var enumerator; arrayObject->DynamicObject::GetEnumerator(enumNonEnumerable, &enumerator, GetScriptContext(), true, enumSymbols); objectEnumerator = (JavascriptEnumerator*)enumerator; }
BOOL ModuleNamespace::HasProperty(PropertyId propertyId) { SimpleDictionaryPropertyDescriptor<BigPropertyIndex> propertyDescriptor; const Js::PropertyRecord* propertyRecord = GetScriptContext()->GetThreadContext()->GetPropertyName(propertyId); if (propertyRecord->IsSymbol()) { return this->DynamicObject::HasProperty(propertyId); } if (propertyMap != nullptr && propertyMap->TryGetValue(propertyRecord, &propertyDescriptor)) { return TRUE; } if (unambiguousNonLocalExports != nullptr) { return unambiguousNonLocalExports->ContainsKey(propertyId); } return FALSE; }