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