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