• 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/base/builtins_base.h"
17 #include "ecmascript/ecma_runtime_call_info.h"
18 #include "ecmascript/ecma_string.h"
19 #include "ecmascript/ecma_vm.h"
20 #include "ecmascript/global_env.h"
21 #include "ecmascript/interpreter/interpreter.h"
22 #include "ecmascript/js_function.h"
23 #include "ecmascript/js_handle.h"
24 #include "ecmascript/js_hclass.h"
25 #include "ecmascript/js_proxy.h"
26 #include "ecmascript/js_tagged_value-inl.h"
27 #include "ecmascript/object_factory.h"
28 #include "ecmascript/tests/test_helper.h"
29 
30 using namespace panda::ecmascript;
31 using namespace panda::ecmascript::base;
32 
33 namespace panda::test {
34 class JSProxyTest : public testing::Test {
35 public:
SetUpTestCase()36     static void SetUpTestCase()
37     {
38         GTEST_LOG_(INFO) << "SetUpTestCase";
39     }
40 
TearDownTestCase()41     static void TearDownTestCase()
42     {
43         GTEST_LOG_(INFO) << "TearDownCase";
44     }
45 
SetUp()46     void SetUp() override
47     {
48         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
49     }
50 
TearDown()51     void TearDown() override
52     {
53         TestHelper::DestroyEcmaVMWithScope(instance, scope);
54     }
55 
56     EcmaVM *instance {nullptr};
57     ecmascript::EcmaHandleScope *scope {nullptr};
58     JSThread *thread {nullptr};
59 };
60 
JSObjectTestCreate(JSThread * thread)61 static JSFunction *JSObjectTestCreate(JSThread *thread)
62 {
63     EcmaVM *ecmaVM = thread->GetEcmaVM();
64     JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
65     return globalEnv->GetObjectFunction().GetObject<JSFunction>();
66 }
67 
HWTEST_F_L0(JSProxyTest,ProxyCreate)68 HWTEST_F_L0(JSProxyTest, ProxyCreate)
69 {
70     JSHandle<JSTaggedValue> hclass(thread, JSObjectTestCreate(thread));
71     JSHandle<JSTaggedValue> targetHandle(
72         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(hclass), hclass));
73 
74     JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
75     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
76     JSObject::SetProperty(thread, targetHandle, key, value);
77     EXPECT_EQ(JSObject::GetProperty(thread, targetHandle, key).GetValue()->GetInt(), 1);
78 
79     JSHandle<JSTaggedValue> handlerHandle(
80         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(hclass), hclass));
81     EXPECT_TRUE(handlerHandle->IsECMAObject());
82 
83     JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
84     EXPECT_TRUE(*proxyHandle != nullptr);
85 
86     EXPECT_EQ(JSProxy::GetProperty(thread, proxyHandle, key).GetValue()->GetInt(), 1);
87     PropertyDescriptor desc(thread);
88     JSProxy::GetOwnProperty(thread, proxyHandle, key, desc);
89     EXPECT_EQ(desc.GetValue()->GetInt(), 1);
90 }
91 
92 // ES6 9.5.8 [[Get]] (P, Receiver)
93 // Called by the following function
HandlerGetProperty(EcmaRuntimeCallInfo * argv)94 JSTaggedValue HandlerGetProperty([[maybe_unused]] EcmaRuntimeCallInfo *argv)
95 {
96     return JSTaggedValue(10); // 10 : test case
97 }
98 
HWTEST_F_L0(JSProxyTest,GetProperty)99 HWTEST_F_L0(JSProxyTest, GetProperty)
100 {
101     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
102     // 1. handler has no "get"
103     JSHandle<JSTaggedValue> hclass(thread, JSObjectTestCreate(thread));
104     JSHandle<JSTaggedValue> targetHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
105     EXPECT_TRUE(targetHandle->IsECMAObject());
106 
107     JSHandle<JSTaggedValue> key(factory->NewFromASCII("x"));
108     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
109     JSObject::SetProperty(thread, targetHandle, key, value);
110     EXPECT_EQ(JSObject::GetProperty(thread, targetHandle, key).GetValue()->GetInt(), 1);
111 
112     JSHandle<JSTaggedValue> handlerHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
113     EXPECT_TRUE(handlerHandle->IsECMAObject());
114 
115     JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
116     EXPECT_TRUE(*proxyHandle != nullptr);
117 
118     EXPECT_EQ(JSProxy::GetProperty(thread, proxyHandle, key).GetValue()->GetInt(), 1);
119 
120     // 2. handler has "get"
121     EcmaVM *vm = thread->GetEcmaVM();
122     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
123     JSHandle<JSTaggedValue> getKey = thread->GlobalConstants()->GetHandledGetString();
124     JSHandle<JSTaggedValue> getHandle(factory->NewJSFunction(env, reinterpret_cast<void *>(HandlerGetProperty)));
125     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handlerHandle), getKey, getHandle);
126 
127     JSHandle<JSProxy> proxyHandle2(JSProxy::ProxyCreate(thread, targetHandle, handlerHandle));
128     EXPECT_TRUE(*proxyHandle2 != nullptr);
129     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("y"));
130     EXPECT_EQ(JSProxy::GetProperty(thread, proxyHandle2, key2).GetValue()->GetInt(), 10);
131 }
132 
133 // ES6 9.5.5 [[GetOwnProperty]] (P)
134 // Called by the following function
HandlerGetOwnProperty(EcmaRuntimeCallInfo * argv)135 JSTaggedValue HandlerGetOwnProperty([[maybe_unused]] EcmaRuntimeCallInfo *argv)
136 {
137     return JSTaggedValue(JSTaggedValue::Undefined());
138 }
139 
HWTEST_F_L0(JSProxyTest,GetOwnProperty)140 HWTEST_F_L0(JSProxyTest, GetOwnProperty)
141 {
142     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
143     // 1. handler has no "get"
144     JSHandle<JSTaggedValue> hclass(thread, JSObjectTestCreate(thread));
145     JSHandle<JSTaggedValue> targetHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
146     EXPECT_TRUE(targetHandle->IsECMAObject());
147 
148     JSHandle<JSTaggedValue> key(factory->NewFromASCII("x"));
149     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
150     JSObject::SetProperty(thread, targetHandle, key, value);
151     EXPECT_EQ(JSObject::GetProperty(thread, targetHandle, key).GetValue()->GetInt(), 1);
152 
153     JSHandle<JSTaggedValue> handlerHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
154     EXPECT_TRUE(handlerHandle->IsECMAObject());
155 
156     JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
157     EXPECT_TRUE(*proxyHandle != nullptr);
158 
159     PropertyDescriptor desc(thread);
160     JSProxy::GetOwnProperty(thread, proxyHandle, key, desc);
161     EXPECT_EQ(desc.GetValue()->GetInt(), 1);
162 
163     // 2. handler has "get"
164     EcmaVM *vm = thread->GetEcmaVM();
165     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
166     JSHandle<JSTaggedValue> defineKey = thread->GlobalConstants()->GetHandledGetOwnPropertyDescriptorString();
167     JSHandle<JSTaggedValue> defineHandle(factory->NewJSFunction(env, reinterpret_cast<void *>(HandlerGetOwnProperty)));
168     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handlerHandle), defineKey, defineHandle);
169 
170     JSHandle<JSProxy> proxyHandle2 = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
171     EXPECT_TRUE(*proxyHandle2 != nullptr);
172     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("y"));
173     PropertyDescriptor desc2(thread);
174     EXPECT_FALSE(JSProxy::GetOwnProperty(thread, proxyHandle2, key2, desc2));
175 }
176 
177 // ES6 9.5.9 [[Set]] ( P, V, Receiver)
HandlerSetProperty(EcmaRuntimeCallInfo * argv)178 JSTaggedValue HandlerSetProperty([[maybe_unused]] EcmaRuntimeCallInfo *argv)
179 {
180     return JSTaggedValue(JSTaggedValue::False());
181 }
182 
HWTEST_F_L0(JSProxyTest,SetProperty)183 HWTEST_F_L0(JSProxyTest, SetProperty)
184 {
185     // 1. handler has no "get"
186     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
187     // 1. handler has no "get"
188     JSHandle<JSTaggedValue> hclass(thread, JSObjectTestCreate(thread));
189     JSHandle<JSTaggedValue> targetHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
190     EXPECT_TRUE(targetHandle->IsECMAObject());
191 
192     JSHandle<JSTaggedValue> key(factory->NewFromASCII("x"));
193     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
194 
195     JSHandle<JSTaggedValue> handlerHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
196     EXPECT_TRUE(handlerHandle->IsECMAObject());
197 
198     JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
199     EXPECT_TRUE(*proxyHandle != nullptr);
200 
201     EXPECT_TRUE(JSProxy::SetProperty(thread, proxyHandle, key, value));
202     EXPECT_EQ(JSProxy::GetProperty(thread, proxyHandle, key).GetValue()->GetInt(), 1);
203     EXPECT_EQ(JSObject::GetProperty(thread, targetHandle, key).GetValue()->GetInt(), 1);
204 
205     // 2. handler has "set"
206     EcmaVM *vm = thread->GetEcmaVM();
207     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
208     JSHandle<JSTaggedValue> setKey = thread->GlobalConstants()->GetHandledSetString();
209     JSHandle<JSTaggedValue> setHandle(factory->NewJSFunction(env, reinterpret_cast<void *>(HandlerSetProperty)));
210     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handlerHandle), setKey, setHandle);
211 
212     JSHandle<JSProxy> proxyHandle2(JSProxy::ProxyCreate(thread, targetHandle, handlerHandle));
213     EXPECT_TRUE(*proxyHandle2 != nullptr);
214     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(10));
215     EXPECT_FALSE(JSProxy::SetProperty(thread, proxyHandle2, key, value2));
216     EXPECT_EQ(JSProxy::GetProperty(thread, proxyHandle2, key).GetValue()->GetInt(), 1);
217 }
218 
219 // ES6 9.5.6 [[DefineOwnProperty]] (P, Desc)
HandlerDefineOwnProperty(EcmaRuntimeCallInfo * argv)220 JSTaggedValue HandlerDefineOwnProperty([[maybe_unused]] EcmaRuntimeCallInfo *argv)
221 {
222     return JSTaggedValue(JSTaggedValue::False());
223 }
224 
HWTEST_F_L0(JSProxyTest,DefineOwnProperty)225 HWTEST_F_L0(JSProxyTest, DefineOwnProperty)
226 {
227     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
228     // 1. handler has no "defineProperty"
229     JSHandle<JSTaggedValue> hclass(thread, JSObjectTestCreate(thread));
230     JSHandle<JSTaggedValue> targetHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
231     EXPECT_TRUE(targetHandle->IsECMAObject());
232 
233     JSHandle<JSTaggedValue> key(factory->NewFromASCII("x"));
234     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
235 
236     JSHandle<JSTaggedValue> handlerHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
237     EXPECT_TRUE(handlerHandle->IsECMAObject());
238 
239     JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
240     EXPECT_TRUE(*proxyHandle != nullptr);
241 
242     PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)));
243     EXPECT_TRUE(JSProxy::DefineOwnProperty(thread, proxyHandle, key, desc));
244     EXPECT_EQ(JSProxy::GetProperty(thread, proxyHandle, key).GetValue()->GetInt(), 1);
245     EXPECT_EQ(JSObject::GetProperty(thread, targetHandle, key).GetValue()->GetInt(), 1);
246 
247     // 2. handler has "defineProperty"
248     EcmaVM *vm = thread->GetEcmaVM();
249     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
250     JSHandle<JSTaggedValue> setKey = thread->GlobalConstants()->GetHandledDefinePropertyString();
251     JSHandle<JSTaggedValue> setHandle(factory->NewJSFunction(env, reinterpret_cast<void *>(HandlerDefineOwnProperty)));
252     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handlerHandle), setKey, setHandle);
253 
254     JSHandle<JSProxy> proxyHandle2 = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
255     EXPECT_TRUE(*proxyHandle2 != nullptr);
256     PropertyDescriptor desc2(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(10)));
257     EXPECT_FALSE(JSProxy::DefineOwnProperty(thread, proxyHandle, key, desc2));
258     EXPECT_EQ(JSProxy::GetProperty(thread, proxyHandle2, key).GetValue()->GetInt(), 1);
259 }
260 
HandlerDeleteProperty(EcmaRuntimeCallInfo * argv)261 JSTaggedValue HandlerDeleteProperty([[maybe_unused]] EcmaRuntimeCallInfo *argv)
262 {
263     return JSTaggedValue(JSTaggedValue::False());
264 }
265 
266 // ES6 9.5.10 [[Delete]] (P)
HWTEST_F_L0(JSProxyTest,DeleteProperty)267 HWTEST_F_L0(JSProxyTest, DeleteProperty)
268 {
269     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
270     // 1. handler has no "deleteProperty"
271     JSHandle<JSTaggedValue> hclass(thread, JSObjectTestCreate(thread));
272     JSHandle<JSTaggedValue> targetHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
273     EXPECT_TRUE(targetHandle->IsECMAObject());
274 
275     JSHandle<JSTaggedValue> key(factory->NewFromASCII("x"));
276     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
277 
278     JSHandle<JSTaggedValue> handlerHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
279     EXPECT_TRUE(handlerHandle->IsECMAObject());
280 
281     JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
282     EXPECT_TRUE(*proxyHandle != nullptr);
283 
284     PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), true, true, true);
285     EXPECT_TRUE(JSProxy::DefineOwnProperty(thread, proxyHandle, key, desc));
286     EXPECT_EQ(JSProxy::GetProperty(thread, proxyHandle, key).GetValue()->GetInt(), 1);
287     EXPECT_EQ(JSObject::GetProperty(thread, targetHandle, key).GetValue()->GetInt(), 1);
288     EXPECT_TRUE(JSProxy::DeleteProperty(thread, proxyHandle, key));
289     PropertyDescriptor resDesc(thread);
290     JSProxy::GetOwnProperty(thread, proxyHandle, key, resDesc);
291     EXPECT_TRUE(JSTaggedValue::SameValue(resDesc.GetValue().GetTaggedValue(), JSTaggedValue::Undefined()));
292 
293     // 2. handler has "deleteProperty"
294     EcmaVM *vm = thread->GetEcmaVM();
295     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
296     JSHandle<JSTaggedValue> funcKey = thread->GlobalConstants()->GetHandledDeletePropertyString();
297     JSHandle<JSTaggedValue> funcHandle(factory->NewJSFunction(env, reinterpret_cast<void *>(HandlerDeleteProperty)));
298     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handlerHandle), funcKey, funcHandle);
299 
300     JSHandle<JSProxy> proxyHandle2 = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
301     EXPECT_TRUE(*proxyHandle2 != nullptr);
302     PropertyDescriptor desc2(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), true, true, true);
303     EXPECT_TRUE(JSProxy::DefineOwnProperty(thread, proxyHandle2, key, desc2));
304     EXPECT_EQ(JSProxy::GetProperty(thread, proxyHandle2, key).GetValue()->GetInt(), 1);
305     EXPECT_FALSE(JSProxy::DeleteProperty(thread, proxyHandle2, key));
306 }
307 
HandlerGetPrototype(EcmaRuntimeCallInfo * argv)308 JSTaggedValue HandlerGetPrototype([[maybe_unused]] EcmaRuntimeCallInfo *argv)
309 {
310     return JSTaggedValue(JSTaggedValue::Null());
311 }
312 
313 // ES6 9.5.1 [[GetPrototypeOf]] ( )
HWTEST_F_L0(JSProxyTest,GetPrototypeOf)314 HWTEST_F_L0(JSProxyTest, GetPrototypeOf)
315 {
316     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
317     // 1. handler has no "GetPrototypeOf"
318     JSHandle<JSTaggedValue> hclass(thread, JSObjectTestCreate(thread));
319     JSHandle<JSTaggedValue> proto(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
320     JSHandle<JSTaggedValue> targetHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
321     EXPECT_TRUE(targetHandle->IsECMAObject());
322     JSObject::SetPrototype(thread, JSHandle<JSObject>(targetHandle), proto);
323     EXPECT_TRUE(
324         JSTaggedValue::SameValue(JSTaggedValue::GetPrototype(thread, targetHandle), proto.GetTaggedValue()));
325 
326     JSHandle<JSTaggedValue> handlerHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
327     EXPECT_TRUE(handlerHandle->IsECMAObject());
328 
329     JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
330     EXPECT_TRUE(*proxyHandle != nullptr);
331 
332     EXPECT_TRUE(JSTaggedValue::SameValue(JSProxy::GetPrototype(thread, proxyHandle), proto.GetTaggedValue()));
333 
334     // 2. handler has "GetPrototypeOf"
335     EcmaVM *vm = thread->GetEcmaVM();
336     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
337     JSHandle<JSTaggedValue> funcKey = thread->GlobalConstants()->GetHandledGetPrototypeOfString();
338     JSHandle<JSTaggedValue> funcHandle(factory->NewJSFunction(env, reinterpret_cast<void *>(HandlerGetPrototype)));
339     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handlerHandle), funcKey, funcHandle);
340 
341     JSHandle<JSProxy> proxyHandle2 = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
342     EXPECT_TRUE(*proxyHandle2 != nullptr);
343     EXPECT_TRUE(JSTaggedValue::SameValue(JSProxy::GetPrototype(thread, proxyHandle2), JSTaggedValue::Null()));
344 }
345 
HandlerSetPrototype(EcmaRuntimeCallInfo * argv)346 JSTaggedValue HandlerSetPrototype([[maybe_unused]] EcmaRuntimeCallInfo *argv)
347 {
348     return JSTaggedValue(JSTaggedValue::False());
349 }
350 
351 // ES6 9.5.2 [[SetPrototypeOf]] (V)
HWTEST_F_L0(JSProxyTest,SetPrototypeOf)352 HWTEST_F_L0(JSProxyTest, SetPrototypeOf)
353 {
354     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
355     // 1. handler has no "SetPrototypeOf"
356     JSHandle<JSTaggedValue> hclass(thread, JSObjectTestCreate(thread));
357     JSHandle<JSTaggedValue> proto(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
358     JSHandle<JSTaggedValue> targetHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
359     EXPECT_TRUE(targetHandle->IsECMAObject());
360 
361     JSHandle<JSTaggedValue> handlerHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
362     EXPECT_TRUE(handlerHandle->IsECMAObject());
363 
364     JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
365     EXPECT_TRUE(*proxyHandle != nullptr);
366 
367     JSProxy::SetPrototype(thread, proxyHandle, proto);
368     EXPECT_TRUE(
369         JSTaggedValue::SameValue(JSTaggedValue::GetPrototype(thread, targetHandle), proto.GetTaggedValue()));
370 
371     // 2. handler has "SetPrototypeOf"
372     EcmaVM *vm = thread->GetEcmaVM();
373     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
374     JSHandle<JSTaggedValue> funcKey = thread->GlobalConstants()->GetHandledSetPrototypeOfString();
375     JSHandle<JSTaggedValue> funcHandle(factory->NewJSFunction(env, reinterpret_cast<void *>(HandlerSetPrototype)));
376     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handlerHandle), funcKey, funcHandle);
377 
378     JSHandle<JSProxy> proxyHandle2 = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
379     EXPECT_TRUE(*proxyHandle2 != nullptr);
380     EXPECT_FALSE(JSProxy::SetPrototype(thread, proxyHandle2, proto));
381 }
382 
HandlerIsExtensible(EcmaRuntimeCallInfo * argv)383 JSTaggedValue HandlerIsExtensible([[maybe_unused]] EcmaRuntimeCallInfo *argv)
384 {
385     return JSTaggedValue(JSTaggedValue::False());
386 }
387 
388 // ES6 9.5.3 [[IsExtensible]] ( )
HWTEST_F_L0(JSProxyTest,IsExtensible)389 HWTEST_F_L0(JSProxyTest, IsExtensible)
390 {
391     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
392     // 1. handler has no "IsExtensible"
393     JSHandle<JSTaggedValue> hclass(thread, JSObjectTestCreate(thread));
394     JSHandle<JSTaggedValue> targetHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
395     EXPECT_TRUE(targetHandle->IsECMAObject());
396 
397     JSHandle<JSTaggedValue> handlerHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
398     EXPECT_TRUE(handlerHandle->IsECMAObject());
399 
400     JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
401     EXPECT_TRUE(*proxyHandle != nullptr);
402 
403     bool status1 = JSProxy::IsExtensible(thread, proxyHandle);
404     bool status2 = JSHandle<JSObject>::Cast(targetHandle)->IsExtensible();
405     EXPECT_TRUE(status1 == status2);
406 
407     // 2. handler has "IsExtensible"
408     EcmaVM *vm = thread->GetEcmaVM();
409     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
410     JSHandle<JSTaggedValue> funcKey = thread->GlobalConstants()->GetHandledIsExtensibleString();
411     JSHandle<JSTaggedValue> funcHandle(factory->NewJSFunction(env, reinterpret_cast<void *>(HandlerIsExtensible)));
412     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handlerHandle), funcKey, funcHandle);
413 
414     JSHandle<JSProxy> proxyHandle2 = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
415     EXPECT_TRUE(*proxyHandle2 != nullptr);
416     EXPECT_FALSE(JSProxy::IsExtensible(thread, proxyHandle2));
417 }
418 
HandlerPreventExtensions(EcmaRuntimeCallInfo * argv)419 JSTaggedValue HandlerPreventExtensions([[maybe_unused]] EcmaRuntimeCallInfo *argv)
420 {
421     return JSTaggedValue(JSTaggedValue::False());
422 }
423 
424 // ES6 9.5.4 [[PreventExtensions]] ( )
HWTEST_F_L0(JSProxyTest,PreventExtensions)425 HWTEST_F_L0(JSProxyTest, PreventExtensions)
426 {
427     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
428     // 1. handler has no "PreventExtensions"
429     JSHandle<JSTaggedValue> hclass(thread, JSObjectTestCreate(thread));
430     JSHandle<JSTaggedValue> targetHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
431     EXPECT_TRUE(targetHandle->IsECMAObject());
432 
433     JSHandle<JSTaggedValue> handlerHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
434     EXPECT_TRUE(handlerHandle->IsECMAObject());
435 
436     JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
437     EXPECT_TRUE(*proxyHandle != nullptr);
438 
439     bool status1 = JSProxy::PreventExtensions(thread, proxyHandle);
440     EXPECT_TRUE(status1);
441     bool status2 = JSHandle<JSObject>::Cast(targetHandle)->IsExtensible();
442     EXPECT_FALSE(status2);
443 
444     // 2. handler has "PreventExtensions"
445     EcmaVM *vm = thread->GetEcmaVM();
446     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
447     JSHandle<JSTaggedValue> funcKey = thread->GlobalConstants()->GetHandledPreventExtensionsString();
448     JSHandle<JSTaggedValue> funcHandle(
449         factory->NewJSFunction(env, reinterpret_cast<void *>(HandlerPreventExtensions)));
450     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handlerHandle), funcKey, funcHandle);
451 
452     JSHandle<JSProxy> proxyHandle2 = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
453     EXPECT_TRUE(*proxyHandle2 != nullptr);
454     EXPECT_FALSE(JSProxy::PreventExtensions(thread, proxyHandle2));
455 }
456 
HandlerHasProperty(EcmaRuntimeCallInfo * argv)457 JSTaggedValue HandlerHasProperty([[maybe_unused]] EcmaRuntimeCallInfo *argv)
458 {
459     return JSTaggedValue(JSTaggedValue::False());
460 }
461 
462 // ES6 9.5.7 [[HasProperty]] (P)
HWTEST_F_L0(JSProxyTest,HasProperty)463 HWTEST_F_L0(JSProxyTest, HasProperty)
464 {
465     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
466     // 1. handler has no "HasProperty"
467     JSHandle<JSTaggedValue> hclass(thread, JSObjectTestCreate(thread));
468     JSHandle<JSTaggedValue> targetHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
469     EXPECT_TRUE(targetHandle->IsECMAObject());
470 
471     JSHandle<JSTaggedValue> key(factory->NewFromASCII("x"));
472     PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)));
473     JSObject::DefineOwnProperty(thread, JSHandle<JSObject>::Cast(targetHandle), key, desc);
474 
475     JSHandle<JSTaggedValue> handlerHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
476     EXPECT_TRUE(handlerHandle->IsECMAObject());
477 
478     JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
479     EXPECT_TRUE(*proxyHandle != nullptr);
480 
481     EXPECT_TRUE(JSProxy::HasProperty(thread, proxyHandle, key));
482 
483     // 2. handler has "HasProperty"
484     EcmaVM *vm = thread->GetEcmaVM();
485     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
486     JSHandle<JSTaggedValue> funcKey = thread->GlobalConstants()->GetHandledHasString();
487     JSHandle<JSTaggedValue> funcHandle(factory->NewJSFunction(env, reinterpret_cast<void *>(HandlerHasProperty)));
488     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handlerHandle), funcKey, funcHandle);
489 
490     JSHandle<JSProxy> proxyHandle2 = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
491     EXPECT_TRUE(*proxyHandle2 != nullptr);
492     EXPECT_FALSE(JSProxy::HasProperty(thread, proxyHandle2, key));
493 }
494 
HandlerOwnPropertyKeys(EcmaRuntimeCallInfo * argv)495 JSTaggedValue HandlerOwnPropertyKeys([[maybe_unused]] EcmaRuntimeCallInfo *argv)
496 {
497     auto thread = argv->GetThread();
498     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
499     JSHandle<JSArray> arr = factory->NewJSArray();
500     return JSTaggedValue(arr.GetTaggedValue());
501 }
502 
503 // ES6 9.5.12 [[OwnPropertyKeys]] ()
HWTEST_F_L0(JSProxyTest,OwnPropertyKeys)504 HWTEST_F_L0(JSProxyTest, OwnPropertyKeys)
505 {
506     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
507     // 1. handler has no "OwnPropertyKeys"
508     JSHandle<JSTaggedValue> hclass(thread, JSObjectTestCreate(thread));
509     JSHandle<JSTaggedValue> targetHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
510     EXPECT_TRUE(targetHandle->IsECMAObject());
511 
512     JSHandle<JSTaggedValue> key(factory->NewFromASCII("x"));
513     PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)));
514     JSObject::DefineOwnProperty(thread, JSHandle<JSObject>::Cast(targetHandle), key, desc);
515 
516     JSHandle<JSTaggedValue> handlerHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
517     EXPECT_TRUE(handlerHandle->IsECMAObject());
518 
519     JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
520     EXPECT_TRUE(*proxyHandle != nullptr);
521     JSHandle<TaggedArray> res = JSProxy::OwnPropertyKeys(thread, proxyHandle);
522 
523     EXPECT_TRUE(JSTaggedValue::SameValue(res->Get(0), key.GetTaggedValue()));
524 
525     // 2. handler has "OwnPropertyKeys"
526     EcmaVM *vm = thread->GetEcmaVM();
527     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
528     JSHandle<JSTaggedValue> funcKey = thread->GlobalConstants()->GetHandledOwnKeysString();
529     JSHandle<JSTaggedValue> funcHandle(factory->NewJSFunction(env, reinterpret_cast<void *>(HandlerOwnPropertyKeys)));
530     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handlerHandle), funcKey, funcHandle);
531 
532     JSHandle<JSProxy> proxyHandle2 = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
533     EXPECT_TRUE(*proxyHandle2 != nullptr);
534     JSHandle<TaggedArray> res2 = JSProxy::OwnPropertyKeys(thread, proxyHandle2);
535     EXPECT_TRUE(res2->GetLength() == 0U || !JSTaggedValue::SameValue(res2->Get(0), key.GetTaggedValue()));
536 }
537 
HandlerCall(EcmaRuntimeCallInfo * argv)538 JSTaggedValue HandlerCall([[maybe_unused]] EcmaRuntimeCallInfo *argv)
539 {
540     return JSTaggedValue(JSTaggedValue::False());
541 }
HandlerFunction(EcmaRuntimeCallInfo * argv)542 JSTaggedValue HandlerFunction([[maybe_unused]] EcmaRuntimeCallInfo *argv)
543 {
544     return JSTaggedValue(JSTaggedValue::True());
545 }
546 
547 // ES6 9.5.13 [[Call]] (thisArgument, argumentsList)
HWTEST_F_L0(JSProxyTest,Call)548 HWTEST_F_L0(JSProxyTest, Call)
549 {
550     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
551     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
552     // 1. handler has no "Call"
553     JSHandle<JSTaggedValue> hclass(thread, JSObjectTestCreate(thread));
554     JSHandle<JSTaggedValue> targetHandle(factory->NewJSFunction(env, reinterpret_cast<void *>(HandlerFunction)));
555     EXPECT_TRUE(targetHandle->IsECMAObject());
556 
557     JSHandle<JSTaggedValue> handlerHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
558     EXPECT_TRUE(handlerHandle->IsECMAObject());
559 
560     JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
561     EXPECT_TRUE(*proxyHandle != nullptr);
562 
563     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
564     EcmaRuntimeCallInfo *info =
565         EcmaInterpreter::NewRuntimeCallInfo(thread, JSHandle<JSTaggedValue>(proxyHandle),
566         JSHandle<JSTaggedValue>(proxyHandle), undefined, 0);
567     JSTaggedValue res = JSProxy::CallInternal(info);
568     EXPECT_TRUE(JSTaggedValue::SameValue(res, JSTaggedValue::True()));
569 
570     // 2. handler has "Call"
571     JSHandle<JSTaggedValue> funcKey = thread->GlobalConstants()->GetHandledApplyString();
572     JSHandle<JSTaggedValue> funcHandle(factory->NewJSFunction(env, reinterpret_cast<void *>(HandlerCall)));
573     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handlerHandle), funcKey, funcHandle);
574 
575     JSHandle<JSProxy> proxyHandle2 = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
576     EXPECT_TRUE(*proxyHandle2 != nullptr);
577 
578     EcmaRuntimeCallInfo *runtimeInfo =
579         EcmaInterpreter::NewRuntimeCallInfo(thread, JSHandle<JSTaggedValue>(proxyHandle2),
580         JSHandle<JSTaggedValue>(proxyHandle2), undefined, 0);
581     JSTaggedValue res2 = JSProxy::CallInternal(runtimeInfo);
582     EXPECT_TRUE(JSTaggedValue::SameValue(res2, JSTaggedValue::False()));
583 }
584 
HandlerConstruct(EcmaRuntimeCallInfo * argv)585 JSTaggedValue HandlerConstruct([[maybe_unused]] EcmaRuntimeCallInfo *argv)
586 {
587     auto thread = argv->GetThread();
588     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
589     JSHandle<JSTaggedValue> hclass(thread, JSObjectTestCreate(thread));
590     JSHandle<JSTaggedValue> obj(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
591 
592     JSHandle<JSTaggedValue> key(factory->NewFromASCII("x"));
593     PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(2))); // 2 : test case
594     JSObject::DefineOwnProperty(argv->GetThread(), JSHandle<JSObject>::Cast(obj), key, desc);
595     return JSTaggedValue(obj.GetTaggedValue());
596 }
HandlerConFunc(EcmaRuntimeCallInfo * argv)597 JSTaggedValue HandlerConFunc([[maybe_unused]] EcmaRuntimeCallInfo *argv)
598 {
599     auto thread = argv->GetThread();
600     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
601     JSHandle<JSTaggedValue> hclass(thread, JSObjectTestCreate(thread));
602     JSHandle<JSTaggedValue> obj(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
603 
604     JSHandle<JSTaggedValue> key(factory->NewFromASCII("x"));
605     PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)));
606     JSObject::DefineOwnProperty(argv->GetThread(), JSHandle<JSObject>::Cast(obj), key, desc);
607     return JSTaggedValue(obj.GetTaggedValue());
608 }
609 
610 // ES6 9.5.14 [[Construct]] ( argumentsList, newTarget)
HWTEST_F_L0(JSProxyTest,Construct)611 HWTEST_F_L0(JSProxyTest, Construct)
612 {
613     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
614     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
615     // 1. handler has no "Construct"
616     JSHandle<JSTaggedValue> hclass(thread, JSObjectTestCreate(thread));
617     JSHandle<JSTaggedValue> targetHandle(factory->NewJSFunction(env, reinterpret_cast<void *>(HandlerConFunc)));
618     JSHandle<JSFunction>::Cast(targetHandle)->GetJSHClass()->SetConstructor(true);
619     EXPECT_TRUE(targetHandle->IsECMAObject());
620 
621     JSHandle<JSTaggedValue> handlerHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
622     EXPECT_TRUE(handlerHandle->IsECMAObject());
623 
624     JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
625     EXPECT_TRUE(*proxyHandle != nullptr);
626     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
627     EcmaRuntimeCallInfo *info =
628         EcmaInterpreter::NewRuntimeCallInfo(thread, JSHandle<JSTaggedValue>(proxyHandle), handlerHandle, undefined, 0);
629     JSTaggedValue res = JSProxy::ConstructInternal(info);
630     JSHandle<JSTaggedValue> taggedRes(thread, res);
631     JSHandle<JSTaggedValue> key(factory->NewFromASCII("x"));
632     EXPECT_EQ(JSObject::GetProperty(thread, taggedRes, key).GetValue()->GetInt(), 1);
633 
634     // 2. handler has "Construct"
635     JSHandle<JSTaggedValue> funcKey = thread->GlobalConstants()->GetHandledProxyConstructString();
636     JSHandle<JSTaggedValue> funcHandle(factory->NewJSFunction(env, reinterpret_cast<void *>(HandlerConstruct)));
637     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handlerHandle), funcKey, funcHandle);
638 
639     JSHandle<JSProxy> proxyHandle2 = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
640     EXPECT_TRUE(*proxyHandle2 != nullptr);
641     EcmaRuntimeCallInfo *runtimeInfo =
642         EcmaInterpreter::NewRuntimeCallInfo(thread, JSHandle<JSTaggedValue>(proxyHandle2), targetHandle, undefined, 0);
643     JSTaggedValue res2 = JSProxy::ConstructInternal(runtimeInfo);
644     JSHandle<JSTaggedValue> taggedRes2(thread, res2);
645     EXPECT_EQ(JSObject::GetProperty(thread, taggedRes2, key).GetValue()->GetInt(), 2);
646 }
647 }  // namespace panda::test
648