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 26namespace 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) \ 36JSTaggedType 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 59DEF_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 77DEF_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 90DEF_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 101DEF_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 123DEF_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 142DEF_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 159DEF_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