• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 #include "ecmascript/object_factory.h"
16 #include "ecmascript/stubs/runtime_stubs.h"
17 
18 #include "ecmascript/ecma_macros.h"
19 #include "ecmascript/js_tagged_value.h"
20 #include "ecmascript/ecma_vm.h"
21 #include "ecmascript/frames.h"
22 #include "ecmascript/global_env.h"
23 #include "ecmascript/runtime_call_id.h"
24 #include "ecmascript/js_function.h"
25 
26 namespace panda::ecmascript {
27 #if defined(__clang__)
28 #pragma clang diagnostic push
29 #pragma clang diagnostic ignored "-Wunused-parameter"
30 #elif defined(__GNUC__)
31 #pragma GCC diagnostic push
32 #pragma GCC diagnostic ignored "-Wunused-parameter"
33 #endif
34 
35 #define DEF_RUNTIME_STUBS(name) \
36 JSTaggedType RuntimeStubs::name(uintptr_t argGlue, uint32_t argc, uintptr_t argv) \
37 
38 #define RUNTIME_STUBS_HEADER(name)                        \
39     auto thread = JSThread::GlueToJSThread(argGlue);      \
40     [[maybe_unused]] EcmaHandleScope handleScope(thread)  \
41 
42 #define CONVERT_ARG_TAGGED_TYPE_CHECKED(name, index) \
43     ASSERT((index) < argc);                          \
44     JSTaggedType name = *(reinterpret_cast<JSTaggedType *>(argv) + (index))
45 
46 #define CONVERT_ARG_TAGGED_CHECKED(name, index) \
47     ASSERT((index) < argc);                     \
48     JSTaggedValue name = JSTaggedValue(*(reinterpret_cast<JSTaggedType *>(argv) + (index)))
49 
50 #define CONVERT_ARG_HANDLE_CHECKED(type, name, index) \
51     ASSERT((index) < argc);                           \
52     JSHandle<type> name(&(reinterpret_cast<JSTaggedType *>(argv)[index]))
53 
54 #define CONVERT_ARG_PTR_CHECKED(type, name, index) \
55     ASSERT((index) < argc);                        \
56     type name = reinterpret_cast<type>(*(reinterpret_cast<JSTaggedType *>(argv) + (index)))
57 
58 #ifndef NDEBUG
DEF_RUNTIME_STUBS(DefineAotFunc)59 DEF_RUNTIME_STUBS(DefineAotFunc)
60 {
61     RUNTIME_STUBS_HEADER(DefineAotFunc);
62     CONVERT_ARG_TAGGED_CHECKED(funcIndex, 0);
63     CONVERT_ARG_TAGGED_CHECKED(numArgs, 1);
64     EcmaVM *ecmaVm = thread->GetEcmaVM();
65     ObjectFactory *factory = ecmaVm->GetFactory();
66     JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv();
67     auto codeEntry = thread->GetFastStubEntry(funcIndex.GetInt());
68     JSHandle<Method> method = factory->NewMethodForNativeFunction(reinterpret_cast<void *>(codeEntry));
69     method->SetAotCodeBit(true);
70     method->SetNativeBit(false);
71     method->SetNumArgsWithCallField(numArgs.GetInt());
72     method->SetCodeEntryOrLiteral(reinterpret_cast<uintptr_t>(codeEntry));
73     JSHandle<JSFunction> jsfunc = factory->NewJSFunction(env, method);
74     return jsfunc.GetTaggedValue().GetRawData();
75 }
76 
DEF_RUNTIME_STUBS(GetPrintFunc)77 DEF_RUNTIME_STUBS(GetPrintFunc)
78 {
79     RUNTIME_STUBS_HEADER(GetPrintFunc);
80     EcmaVM *ecmaVm = thread->GetEcmaVM();
81     ObjectFactory *factory = ecmaVm->GetFactory();
82     auto env = ecmaVm->GetGlobalEnv();
83     JSHandle<JSTaggedValue> globalObject(thread, env->GetGlobalObject());
84     JSHandle<JSTaggedValue> printString(thread, factory->NewFromStdString("print").GetTaggedValue());
85 
86     return JSObject::GetProperty(thread, globalObject, printString).
87         GetValue().GetTaggedValue().GetRawData();
88 }
89 
DEF_RUNTIME_STUBS(GetBindFunc)90 DEF_RUNTIME_STUBS(GetBindFunc)
91 {
92     RUNTIME_STUBS_HEADER(GetBindFunc);
93     CONVERT_ARG_HANDLE_CHECKED(JSTaggedValue, target, 0);
94     EcmaVM *ecmaVm = thread->GetEcmaVM();
95     ObjectFactory *factory = ecmaVm->GetFactory();
96     JSHandle<JSTaggedValue> bindString(thread, factory->NewFromStdString("bind").GetTaggedValue());
97 
98     return JSObject::GetProperty(thread, target, bindString).GetValue().GetTaggedValue().GetRawData();
99 }
100 
DEF_RUNTIME_STUBS(DefineProxyFunc)101 DEF_RUNTIME_STUBS(DefineProxyFunc)
102 {
103     RUNTIME_STUBS_HEADER(DefineProxyFunc);
104     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
105     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
106     CONVERT_ARG_HANDLE_CHECKED(JSTaggedValue, targetHandle, 0);
107     // 1. handler has no "Call"
108     JSFunction *function = env->GetObjectFunction().GetObject<JSFunction>();
109     JSHandle<JSTaggedValue> hclass(thread, function);
110     ASSERT(targetHandle->IsECMAObject());
111 
112     JSHandle<JSTaggedValue> handlerHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
113     ASSERT(handlerHandle->IsECMAObject());
114     ASSERT(targetHandle->IsECMAObject());
115 
116     JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
117     ASSERT(*proxyHandle != nullptr);
118     // check taggedvalue
119     proxyHandle.GetTaggedValue().D();
120     return proxyHandle.GetTaggedValue().GetRawData();
121 }
122 
DEF_RUNTIME_STUBS(DefineProxyHandler)123 DEF_RUNTIME_STUBS(DefineProxyHandler)
124 {
125     RUNTIME_STUBS_HEADER(DefineProxyHandler);
126     CONVERT_ARG_HANDLE_CHECKED(JSTaggedValue, funcHandle, 0);
127     ASSERT(funcHandle->IsECMAObject());
128     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
129     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
130     JSFunction* function = env->GetObjectFunction().GetObject<JSFunction>();
131     JSHandle<JSTaggedValue> hclass(thread, function);
132 
133     JSHandle<JSTaggedValue> handlerHandle(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
134     ASSERT(handlerHandle->IsECMAObject());
135     // 1. handler has "Call"
136     JSHandle<JSTaggedValue> funcKey = thread->GlobalConstants()->GetHandledApplyString();
137     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handlerHandle), funcKey, funcHandle);
138     handlerHandle.GetTaggedValue().D();
139     return handlerHandle.GetTaggedValue().GetRawData();
140 }
141 
DEF_RUNTIME_STUBS(DefineProxyFunc2)142 DEF_RUNTIME_STUBS(DefineProxyFunc2)
143 {
144     RUNTIME_STUBS_HEADER(DefineProxyFunc2);
145     CONVERT_ARG_HANDLE_CHECKED(JSTaggedValue, targetHandle, 0);
146     CONVERT_ARG_HANDLE_CHECKED(JSTaggedValue, handlerHandle, 1);
147     // 1. handler has "Call"
148     ASSERT(handlerHandle->IsECMAObject());
149     ASSERT(targetHandle->IsECMAObject());
150 
151     JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
152     targetHandle.GetTaggedValue().D();
153     handlerHandle.GetTaggedValue().D();
154     proxyHandle.GetTaggedValue().D();
155     ASSERT(*proxyHandle != nullptr);
156     return proxyHandle.GetTaggedValue().GetRawData();
157 }
158 
DEF_RUNTIME_STUBS(DumpTaggedType)159 DEF_RUNTIME_STUBS(DumpTaggedType)
160 {
161     RUNTIME_STUBS_HEADER(DumpTaggedType);
162     CONVERT_ARG_HANDLE_CHECKED(JSTaggedValue, value, 0);
163     ASSERT(value->IsECMAObject());
164     value->D();
165     return value.GetTaggedValue().GetRawData();
166 }
167 #endif
168 }  // namespace panda::ecmascript
169