1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ecmascript/global_env.h"
17
18 #include "ecmascript/builtins/builtins_number.h"
19 #include "ecmascript/builtins/builtins_regexp.h"
20 #include "ecmascript/builtins/builtins_string.h"
21 #include "ecmascript/dependent_infos.h"
22 #include "ecmascript/ecma_string_table.h"
23 #include "ecmascript/global_dictionary.h"
24 #include "ecmascript/js_object-inl.h"
25 #include "ecmascript/module/js_module_manager.h"
26 #include "ecmascript/template_map.h"
27
28 namespace panda::ecmascript {
Init(JSThread * thread)29 void GlobalEnv::Init(JSThread *thread)
30 {
31 SetGlobalEnv(thread, JSTaggedValue(this));
32 SetGlobalRecord(thread, GlobalDictionary::Create(thread));
33 auto* vm = thread->GetEcmaVM();
34 JSTaggedValue emptyStr = thread->GlobalConstants()->GetEmptyString();
35 EcmaStringTable *stringTable = vm->GetEcmaStringTable();
36 stringTable->GetOrInternFlattenString(vm, EcmaString::Cast(emptyStr.GetTaggedObject()));
37 SetTemplateMap(thread, TemplateMap::Create(thread));
38 SetObjectLiteralHClassCache(thread, JSTaggedValue::Hole());
39 SetArrayJoinStack(thread, vm->GetFactory()->NewTaggedArray(ArrayJoinStack::MIN_JOIN_STACK_SIZE));
40 SetNumberToStringResultCache(thread, builtins::NumberToStringResultCache::CreateCacheTable(thread));
41 SetStringSplitResultCache(thread, builtins::StringSplitResultCache::CreateCacheTable(thread));
42 SetStringToListResultCache(thread, builtins::StringToListResultCache::CreateCacheTable(thread));
43 SetRegExpCache(thread, builtins::RegExpExecResultCache::CreateCacheTable(thread));
44 SetRegExpGlobalResult(thread, builtins::RegExpGlobalResult::CreateGlobalResultTable(thread));
45 #define INIT_JSAPI_CONTAINER(Type, Name, INDEX) Set##Name(thread, JSTaggedValue::Undefined());
46 GLOBAL_ENV_CONTAINER_ITERATORS(INIT_JSAPI_CONTAINER)
47 #undef INIT_JSAPI_CONTAINER
48 SetModuleManagerNativePointer(thread, ModuleManager::CreateModuleManagerNativePointer(thread));
49 ClearBitField();
50 SetJSThread(thread);
51
52 auto array = vm->GetFactory()->NewTaggedArray(LastBitFieldBits::START_BIT, JSTaggedValue::Undefined());
53 SetDetectorDependentInfos(thread, array);
54 }
55
Iterate(RootVisitor & v)56 void GlobalEnv::Iterate(RootVisitor &v)
57 {
58 for (uint16_t i = 0; i < FINAL_INDEX; i++) {
59 size_t offset = HEADER_SIZE + i * sizeof(JSTaggedType);
60 uintptr_t slotAddress = reinterpret_cast<uintptr_t>(this) + offset;
61 ObjectSlot slot(slotAddress);
62 v.VisitRoot(Root::ROOT_VM, slot);
63 }
64 }
65
GetSymbol(JSThread * thread,const JSHandle<JSTaggedValue> & string)66 JSHandle<JSTaggedValue> GlobalEnv::GetSymbol(JSThread *thread, const JSHandle<JSTaggedValue> &string)
67 {
68 JSHandle<JSTaggedValue> symbolFunction(GetSymbolFunction());
69 return JSObject::GetProperty(thread, symbolFunction, string).GetValue();
70 }
71
GetStringPrototypeFunctionByName(JSThread * thread,const char * name)72 JSHandle<JSTaggedValue> GlobalEnv::GetStringPrototypeFunctionByName(JSThread *thread, const char *name)
73 {
74 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
75 JSHandle<JSTaggedValue> stringFuncPrototype(
76 thread, JSObject::GetPrototype(thread, JSHandle<JSObject>(GetStringFunction())));
77 JSHandle<JSTaggedValue> nameKey(factory->NewFromUtf8(name));
78 return JSObject::GetProperty(thread, stringFuncPrototype, nameKey).GetValue();
79 }
80
GetStringFunctionByName(JSThread * thread,const char * name)81 JSHandle<JSTaggedValue> GlobalEnv::GetStringFunctionByName(JSThread *thread, const char *name)
82 {
83 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
84 JSHandle<JSTaggedValue> stringFuncObj = GetStringFunction();
85 JSHandle<JSTaggedValue> nameKey(factory->NewFromUtf8(name));
86 return JSObject::GetProperty(thread, stringFuncObj, nameKey).GetValue();
87 }
88
NotifyDetectorDeoptimize(JSThread * thread,uint32_t detectorID)89 void GlobalEnv::NotifyDetectorDeoptimize(JSThread *thread, uint32_t detectorID)
90 {
91 JSHandle<JSTaggedValue> dependentInfos = GetDependentInfos(thread, detectorID);
92 if (!dependentInfos->IsHeapObject()) {
93 return;
94 }
95 JSThread *initThread = GetJSThread();
96 DependentInfos::TriggerLazyDeoptimization(
97 JSHandle<DependentInfos>::Cast(dependentInfos), initThread,
98 DependentInfos::DependentState::DETECTOR_CHECK);
99 SetDependentInfos(detectorID, initThread->GlobalConstants()->GetHandledUndefined());
100 }
101
NotifyArrayPrototypeChangedGuardians(JSThread * thread,JSHandle<JSObject> receiver)102 void GlobalEnv::NotifyArrayPrototypeChangedGuardians(JSThread *thread, JSHandle<JSObject> receiver)
103 {
104 if (!GetArrayPrototypeChangedGuardians()) {
105 return;
106 }
107 if (!receiver->GetJSHClass()->IsPrototype() && !receiver->IsJSArray()) {
108 return;
109 }
110 if (receiver.GetTaggedValue() == GetObjectFunctionPrototype().GetTaggedValue() ||
111 receiver.GetTaggedValue() == GetArrayPrototype().GetTaggedValue()) {
112 NotifyDetectorDeoptimize(thread, ArrayPrototypeChangedGuardiansBits::START_BIT);
113 SetArrayPrototypeChangedGuardians(false);
114 return;
115 }
116 }
117
ClearCache(JSThread * thread) const118 void GlobalEnv::ClearCache(JSThread *thread) const
119 {
120 builtins::StringSplitResultCache::ClearCache(thread, GetStringSplitResultCache());
121 }
122
GetBuildinTypedArrayHClassOnHeapIndex(JSType jSType)123 GlobalEnvField GetBuildinTypedArrayHClassOnHeapIndex(JSType jSType)
124 {
125 switch (jSType) {
126 case JSType::JS_INT8_ARRAY:
127 return GlobalEnvField::INT8_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
128 case JSType::JS_UINT8_ARRAY:
129 return GlobalEnvField::UINT8_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
130 case JSType::JS_UINT8_CLAMPED_ARRAY:
131 return GlobalEnvField::UINT8_CLAMPED_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
132 case JSType::JS_INT16_ARRAY:
133 return GlobalEnvField::INT16_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
134 case JSType::JS_UINT16_ARRAY:
135 return GlobalEnvField::UINT16_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
136 case JSType::JS_INT32_ARRAY:
137 return GlobalEnvField::INT32_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
138 case JSType::JS_UINT32_ARRAY:
139 return GlobalEnvField::UINT32_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
140 case JSType::JS_FLOAT32_ARRAY:
141 return GlobalEnvField::FLOAT32_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
142 case JSType::JS_FLOAT64_ARRAY:
143 return GlobalEnvField::FLOAT64_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
144 case JSType::JS_BIGINT64_ARRAY:
145 return GlobalEnvField::BIGINT64_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
146 case JSType::JS_BIGUINT64_ARRAY:
147 return GlobalEnvField::BIGUINT64_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
148 default:
149 return GlobalEnvField::INVALID;
150 }
151 return GlobalEnvField::INVALID;
152 }
153
GetBuildinTypedArrayHClassIndex(JSType jSType)154 GlobalEnvField GetBuildinTypedArrayHClassIndex(JSType jSType)
155 {
156 switch (jSType) {
157 case JSType::JS_INT8_ARRAY:
158 return GlobalEnvField::INT8_ARRAY_ROOT_HCLASS_INDEX;
159 case JSType::JS_UINT8_ARRAY:
160 return GlobalEnvField::UINT8_ARRAY_ROOT_HCLASS_INDEX;
161 case JSType::JS_UINT8_CLAMPED_ARRAY:
162 return GlobalEnvField::UINT8_CLAMPED_ARRAY_ROOT_HCLASS_INDEX;
163 case JSType::JS_INT16_ARRAY:
164 return GlobalEnvField::INT16_ARRAY_ROOT_HCLASS_INDEX;
165 case JSType::JS_UINT16_ARRAY:
166 return GlobalEnvField::UINT16_ARRAY_ROOT_HCLASS_INDEX;
167 case JSType::JS_INT32_ARRAY:
168 return GlobalEnvField::INT32_ARRAY_ROOT_HCLASS_INDEX;
169 case JSType::JS_UINT32_ARRAY:
170 return GlobalEnvField::UINT32_ARRAY_ROOT_HCLASS_INDEX;
171 case JSType::JS_FLOAT32_ARRAY:
172 return GlobalEnvField::FLOAT32_ARRAY_ROOT_HCLASS_INDEX;
173 case JSType::JS_FLOAT64_ARRAY:
174 return GlobalEnvField::FLOAT64_ARRAY_ROOT_HCLASS_INDEX;
175 case JSType::JS_BIGINT64_ARRAY:
176 return GlobalEnvField::BIGINT64_ARRAY_ROOT_HCLASS_INDEX;
177 case JSType::JS_BIGUINT64_ARRAY:
178 return GlobalEnvField::BIGUINT64_ARRAY_ROOT_HCLASS_INDEX;
179 default:
180 return GlobalEnvField::INVALID;
181 }
182 return GlobalEnvField::INVALID;
183 }
184
GetBuildinTypedArrayHClassIndex(JSType jSType,OnHeapMode mode)185 GlobalEnvField GlobalEnv::GetBuildinTypedArrayHClassIndex(JSType jSType, OnHeapMode mode)
186 {
187 if (OnHeap::IsOnHeap(mode)) {
188 return GetBuildinTypedArrayHClassOnHeapIndex(jSType);
189 } else if (OnHeap::IsNotOnHeap(mode)) {
190 return ::panda::ecmascript::GetBuildinTypedArrayHClassIndex(jSType);
191 } else {
192 return GlobalEnvField::INVALID;
193 }
194 }
195 } // namespace panda::ecmascript
196