• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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/module/static/static_module_proxy_handler.h"
17 #include "ecmascript/global_env.h"
18 #include "ecmascript/object_factory-inl.h"
19 #include "ecmascript/module/module_path_helper.h"
20 #include "ecmascript/module/js_module_deregister.h"
21 #include "ecmascript/module/js_shared_module_manager.h"
22 #include "ecmascript/shared_objects/js_shared_array.h"
23 #include "ecmascript/module/js_module_source_text.h"
24 #include "ecmascript/module/module_data_extractor.h"
25 #include "ecmascript/builtins/builtins_promise_job.h"
26 #include "ecmascript/interpreter/interpreter.h"
27 #include "ecmascript/js_promise.h"
28 #include "ecmascript/module/module_path_helper.h"
29 
30 namespace panda::ecmascript {
CreateStaticModuleProxyHandler(JSThread * thread,const JSHandle<JSTaggedValue> exportObject)31 JSHandle<JSProxy> StaticModuleProxyHandler::CreateStaticModuleProxyHandler(JSThread *thread,
32     const JSHandle<JSTaggedValue> exportObject)
33 {
34     EcmaVM *vm = thread->GetEcmaVM();
35     ObjectFactory *factory = vm->GetFactory();
36     JSHandle<JSTaggedValue> targetHandler(factory->NewJSFunction(vm->GetGlobalEnv()));
37 
38     JSHandle<JSTaggedValue> setPrototype(factory->NewJSFunction(vm->GetGlobalEnv(),
39         reinterpret_cast<void *>(StaticModuleProxyHandler::SetPrototype)));
40     JSTaggedValue::SetProperty(thread, targetHandler,
41         thread->GlobalConstants()->GetHandledSetPrototypeOfString(), setPrototype);
42 
43     JSHandle<JSTaggedValue> preventExtensions(factory->NewJSFunction(vm->GetGlobalEnv(),
44         reinterpret_cast<void *>(StaticModuleProxyHandler::PreventExtensions)));
45     JSTaggedValue::SetProperty(thread, targetHandler,
46         thread->GlobalConstants()->GetHandledPreventExtensionsString(), preventExtensions);
47 
48     JSHandle<JSTaggedValue> getOwnProperty(factory->NewJSFunction(vm->GetGlobalEnv(),
49         reinterpret_cast<void *>(StaticModuleProxyHandler::GetOwnProperty)));
50     JSTaggedValue::SetProperty(thread, targetHandler,
51         thread->GlobalConstants()->GetHandledGetOwnPropertyDescriptorString(), getOwnProperty);
52 
53     JSHandle<JSTaggedValue> defineOwnProperty(factory->NewJSFunction(vm->GetGlobalEnv(),
54         reinterpret_cast<void *>(StaticModuleProxyHandler::DefineOwnProperty)));
55     JSTaggedValue::SetProperty(thread, targetHandler,
56         thread->GlobalConstants()->GetHandledDefinePropertyString(), defineOwnProperty);
57 
58     JSHandle<JSTaggedValue> hasProperty(factory->NewJSFunction(vm->GetGlobalEnv(),
59         reinterpret_cast<void *>(StaticModuleProxyHandler::HasProperty)));
60     JSTaggedValue::SetProperty(thread, targetHandler,
61         thread->GlobalConstants()->GetHandledHasString(), hasProperty);
62 
63     JSHandle<JSTaggedValue> getProperty(factory->NewJSFunction(vm->GetGlobalEnv(),
64         reinterpret_cast<void *>(StaticModuleProxyHandler::GetProperty)));
65     JSTaggedValue::SetProperty(thread, targetHandler,
66         thread->GlobalConstants()->GetHandledGetString(), getProperty);
67 
68     JSHandle<JSTaggedValue> setProperty(factory->NewJSFunction(vm->GetGlobalEnv(),
69         reinterpret_cast<void *>(StaticModuleProxyHandler::SetProperty)));
70     JSTaggedValue::SetProperty(thread, targetHandler,
71         thread->GlobalConstants()->GetHandledSetString(), setProperty);
72 
73     JSHandle<JSTaggedValue> deleteProperty(factory->NewJSFunction(vm->GetGlobalEnv(),
74         reinterpret_cast<void *>(StaticModuleProxyHandler::DeleteProperty)));
75     JSTaggedValue::SetProperty(thread, targetHandler,
76         thread->GlobalConstants()->GetHandledDeletePropertyString(), deleteProperty);
77 
78     JSHandle<JSTaggedValue> ownPropertyKeys(factory->NewJSFunction(vm->GetGlobalEnv(),
79         reinterpret_cast<void *>(StaticModuleProxyHandler::OwnPropertyKeys)));
80     JSTaggedValue::SetProperty(thread, targetHandler,
81         thread->GlobalConstants()->GetHandledOwnKeysString(), ownPropertyKeys);
82 
83     return JSProxy::ProxyCreate(thread, exportObject, targetHandler);
84 }
85 
GetProperty(EcmaRuntimeCallInfo * argv)86 JSTaggedValue StaticModuleProxyHandler::GetProperty(EcmaRuntimeCallInfo *argv)
87 {
88     JSThread *thread = argv->GetThread();
89     JSHandle<JSTaggedValue> obj(argv->GetCallArg(FIRST));
90     JSHandle<JSTaggedValue> key(argv->GetCallArg(SECOND));
91     // 1. Assert: IsPropertyKey(P) is true.
92     // 2. If Type(P) is Symbol, then
93     //   a. Return ? OrdinaryGet(O, P, Receiver).
94     return GetPropertyInternal(thread, obj, key);
95 }
96 
GetPropertyInternal(JSThread * thread,const JSHandle<JSTaggedValue> & obj,const JSHandle<JSTaggedValue> & key)97 JSTaggedValue StaticModuleProxyHandler::GetPropertyInternal(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
98     const JSHandle<JSTaggedValue> &key)
99 {
100     // 1. Assert: IsPropertyKey(P) is true.
101     ASSERT_PRINT(JSTaggedValue::IsPropertyKey(key), "Key is not a property key");
102     // 2. If Type(P) is Symbol, then
103     //   a. Return ? OrdinaryGet(O, P, Receiver).
104     return JSObject::GetProperty(thread, obj, key).GetValue().GetTaggedValue();
105 }
106 
107 
OwnPropertyKeys(EcmaRuntimeCallInfo * argv)108 JSTaggedValue StaticModuleProxyHandler::OwnPropertyKeys(EcmaRuntimeCallInfo *argv)
109 {
110     JSHandle<JSTaggedValue> obj(argv->GetCallArg(FIRST));
111     JSThread *thread = argv->GetThread();
112     JSHandle<TaggedArray> symbolKeys = JSObject::GetOwnPropertyKeys(thread, JSHandle<JSObject>(obj)); //todo copy array
113     JSHandle<JSArray> propertyKeys = JSArray::CreateArrayFromList(thread, symbolKeys);
114     return propertyKeys.GetTaggedValue();
115 }
116 
GetOwnPropertyInternal(JSThread * thread,const JSHandle<JSTaggedValue> & obj,const JSHandle<JSTaggedValue> & key,PropertyDescriptor & desc)117 bool StaticModuleProxyHandler::GetOwnPropertyInternal(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
118     const JSHandle<JSTaggedValue> &key, PropertyDescriptor &desc)
119 {
120     ASSERT_PRINT(JSTaggedValue::IsPropertyKey(key), "Key is not a property key");
121     // 1. If Type(P) is Symbol, return OrdinaryGetOwnProperty(O, P).
122     if (key->IsSymbol()) {
123         return JSObject::GetOwnProperty(thread, JSHandle<JSObject>(obj), key, desc);
124     }
125     // 2. Let value be ? O.[[Get]](P, O).
126     JSHandle<JSTaggedValue> value(thread, StaticModuleProxyHandler::GetPropertyInternal(thread, obj, key));
127     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
128     if (value->IsUndefined()) {
129         return false;
130     }
131     // 3. Return PropertyDescriptor {
132     //    [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false }.
133     desc.SetValue(value);
134     desc.SetEnumerable(true);
135     desc.SetWritable(true);
136     desc.SetConfigurable(false);
137     return true;
138 }
139 
OwnEnumPropertyKeys(EcmaRuntimeCallInfo * argv)140 JSTaggedValue StaticModuleProxyHandler::OwnEnumPropertyKeys(EcmaRuntimeCallInfo *argv)
141 {
142     JSHandle<JSTaggedValue> obj(argv->GetCallArg(FIRST));
143     JSThread *thread = argv->GetThread();
144     JSHandle<TaggedArray> symbolKeys = JSObject::GetOwnPropertyKeys(thread, JSHandle<JSObject>(obj)); //todo copy array
145     JSHandle<JSArray> propertyKeys = JSArray::CreateArrayFromList(thread, symbolKeys);
146     return propertyKeys.GetTaggedValue();
147 }
148 
PreventExtensions(EcmaRuntimeCallInfo * argv)149 JSTaggedValue StaticModuleProxyHandler::PreventExtensions(EcmaRuntimeCallInfo *argv)
150 {
151     return JSTaggedValue::True();
152 }
153 
DefineOwnProperty(EcmaRuntimeCallInfo * argv)154 JSTaggedValue StaticModuleProxyHandler::DefineOwnProperty(EcmaRuntimeCallInfo *argv)
155 {
156     JSThread *thread = argv->GetThread();
157     JSHandle<JSTaggedValue> obj(argv->GetCallArg(FIRST));
158     JSHandle<JSTaggedValue> key(argv->GetCallArg(SECOND));
159     JSHandle<JSTaggedValue> descObj(argv->GetCallArg(THIRD));
160     PropertyDescriptor desc(thread);
161     if (!descObj->IsUndefined()) {
162         JSObject::ToPropertyDescriptor(thread, descObj, desc);
163     }
164     // 1. If Type(P) is Symbol, return ! OrdinaryDefineOwnProperty(O, P, Desc).
165     if (key->IsSymbol()) {
166         bool res = JSObject::OrdinaryDefineOwnProperty(thread, JSHandle<JSObject>(obj), key, desc);
167         return JSTaggedValue(res);
168     }
169 
170     // 2. Let current be ? O.[[GetOwnProperty]](P).
171     PropertyDescriptor current(thread);
172     // 3. If current is undefined, return false.
173     if (!GetOwnPropertyInternal(thread, obj, key, current)) {
174         return JSTaggedValue::False();
175     }
176     // 4. If Desc has a [[Configurable]] field and Desc.[[Configurable]] is true, return false.
177     // 5. If Desc has an [[Enumerable]] field and Desc.[[Enumerable]] is false, return false.
178     // 6. If IsAccessorDescriptor(Desc) is true, return false.
179     // 7. If Desc has a [[Writable]] field and Desc.[[Writable]] is false, return false.
180     if (desc.IsAccessorDescriptor()) {
181         return JSTaggedValue::False();
182     }
183     if (desc.HasConfigurable() && desc.IsConfigurable()) {
184         return JSTaggedValue::False();
185     }
186     if (desc.HasEnumerable() && !desc.IsEnumerable()) {
187         return JSTaggedValue::False();
188     }
189     if (desc.HasWritable() && !desc.IsWritable()) {
190         return JSTaggedValue::False();
191     }
192 
193     // 8. If Desc has a [[Value]] field, return SameValue(Desc.[[Value]], current.[[Value]]).
194     if (desc.HasValue()) {
195         JSHandle<JSTaggedValue> descValue = desc.GetValue();
196         JSHandle<JSTaggedValue> currentValue = current.GetValue();
197         return JSTaggedValue(JSTaggedValue::SameValue(thread, descValue, currentValue));
198     }
199 
200     // 9. Return true.
201     return JSTaggedValue::True();
202 }
203 
HasProperty(EcmaRuntimeCallInfo * argv)204 JSTaggedValue StaticModuleProxyHandler::HasProperty(EcmaRuntimeCallInfo *argv)
205 {
206     JSThread *thread = argv->GetThread();
207     JSHandle<JSTaggedValue> obj(argv->GetCallArg(FIRST));
208     JSHandle<JSTaggedValue> key(argv->GetCallArg(SECOND));
209     return JSTaggedValue(JSObject::HasProperty(thread, JSHandle<JSObject>(obj), key));
210 }
211 
SetPrototype(EcmaRuntimeCallInfo * argv)212 JSTaggedValue StaticModuleProxyHandler::SetPrototype(EcmaRuntimeCallInfo *argv)
213 {
214     // 1. Assert: Either Type(V) is Object or Type(V) is Null.
215     JSHandle<JSTaggedValue> proto(argv->GetCallArg(SECOND));
216     ASSERT(proto->IsECMAObject() || proto->IsNull());
217     return JSTaggedValue(proto->IsNull());
218 }
219 
GetPrototype(EcmaRuntimeCallInfo * argv)220 JSTaggedValue StaticModuleProxyHandler::GetPrototype(EcmaRuntimeCallInfo *argv)
221 {
222     // 1. Assert: Either Type(V) is Object or Type(V) is Null.
223     return JSTaggedValue::Null();
224 }
225 
226 
GetOwnProperty(EcmaRuntimeCallInfo * argv)227 JSTaggedValue StaticModuleProxyHandler::GetOwnProperty(EcmaRuntimeCallInfo *argv)
228 {
229     JSThread *thread = argv->GetThread();
230     JSHandle<JSTaggedValue> obj(argv->GetCallArg(FIRST));
231     JSHandle<JSTaggedValue> key(argv->GetCallArg(SECOND));
232     JSHandle<JSTaggedValue> descObj(argv->GetCallArg(THIRD));
233     PropertyDescriptor desc(thread);
234     if (!descObj->IsUndefined()) {
235         JSObject::ToPropertyDescriptor(thread, descObj, desc);
236     }
237     return JSTaggedValue(GetOwnPropertyInternal(thread, obj, key, desc));
238 }
239 
SetProperty(EcmaRuntimeCallInfo * argv)240 JSTaggedValue StaticModuleProxyHandler::SetProperty(EcmaRuntimeCallInfo *argv)
241 {
242     JSThread *thread = argv->GetThread();
243     JSHandle<JSTaggedValue> mayThrow(argv->GetCallArg(FIRST));
244     if (mayThrow->ToBoolean()) {
245         THROW_TYPE_ERROR_AND_RETURN(thread, "Cannot assign to read only property of Object Module",
246             JSTaggedValue::False());
247     }
248     return JSTaggedValue::False();
249 }
250 
DeleteProperty(EcmaRuntimeCallInfo * argv)251 JSTaggedValue StaticModuleProxyHandler::DeleteProperty(EcmaRuntimeCallInfo *argv)
252 {
253     JSThread *thread = argv->GetThread();
254     JSHandle<JSTaggedValue> obj(argv->GetCallArg(FIRST));
255     JSHandle<JSTaggedValue> key(argv->GetCallArg(SECOND));
256     // 1. Assert: IsPropertyKey(P) is true.
257     ASSERT_PRINT(JSTaggedValue::IsPropertyKey(key), "Key is not a property key");
258     // 2. If Type(P) is Symbol, then
259     //    Return ? OrdinaryDelete(O, P).
260     if (key->IsSymbol()) {
261         return JSTaggedValue(JSObject::DeleteProperty(thread, JSHandle<JSObject>(obj), key));
262     }
263     // 3. Let exports be O.[[Exports]].
264     JSHandle<JSTaggedValue> value(thread, GetPropertyInternal(thread, obj, key));
265     // 4. If P is an element of exports, return false.
266     if (value->IsUndefined()) {
267         return JSTaggedValue::True();
268     }
269     return JSTaggedValue::False();
270 }
271 
IsExtensible(EcmaRuntimeCallInfo * argv)272 JSTaggedValue StaticModuleProxyHandler::IsExtensible(EcmaRuntimeCallInfo *argv)
273 {
274     return JSTaggedValue::False();
275 }
276 }  // namespace panda::ecmascript
277