• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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