1 /*
2 * Copyright (c) 2025 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/checkpoint/thread_state_transition.h"
17 #include "ecmascript/ecma_global_storage.h"
18 #include "ecmascript/global_env.h"
19 #include "ecmascript/module/napi_module_loader.h"
20 #include "ecmascript/module/module_path_helper.h"
21 #include "ecmascript/napi/include/jsnapi_expo.h"
22 #include "ecmascript/napi/include/jsnapi.h"
23 #include "ecmascript/napi/jsnapi_helper.h"
24
25 namespace panda {
26 using ecmascript::JSTaggedValue;
27 template <typename T>
28 using JSHandle = ecmascript::JSHandle<T>;
29
30 using ModulePathHelper = ecmascript::ModulePathHelper;
31 using ecmascript::ObjectFactory;
32
GetProxyNapiWrapperString(const EcmaVM * vm)33 Local<StringRef> StringRef::GetProxyNapiWrapperString(const EcmaVM *vm)
34 {
35 // Omit exception check because ark calls here may not
36 // cause side effect even pending exception exists.
37 CROSS_THREAD_CHECK(vm);
38 ecmascript::ThreadManagedScope managedScope(thread);
39 JSHandle<JSTaggedValue> proxyNapiWapperString = thread->GlobalConstants()->GetHandledProxyNapiWrapperString();
40 return JSNApiHelper::ToLocal<StringRef>(proxyNapiWapperString);
41 }
42
NewJSXRefObject(const EcmaVM * vm)43 Local<ObjectRef> ObjectRef::NewJSXRefObject(const EcmaVM *vm)
44 {
45 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
46 ecmascript::ThreadManagedScope managedScope(thread);
47 ObjectFactory *factory = vm->GetFactory();
48 JSHandle<JSTaggedValue> object(factory->NewJSXRefObject());
49 return JSNApiHelper::ToLocal<ObjectRef>(object);
50 }
51
SetStackInfo(const EcmaVM * vm,const panda::StackInfo & info)52 void JSNApi::SetStackInfo(const EcmaVM *vm, const panda::StackInfo &info)
53 {
54 JSThread *thread = vm->GetJSThread();
55 thread->SetStackStart(info.stackStart);
56 thread->SetStackLimit(info.stackStart - info.stackSize);
57 }
58
GetStackInfo(const EcmaVM * vm)59 panda::StackInfo JSNApi::GetStackInfo(const EcmaVM *vm)
60 {
61 JSThread *thread = vm->GetJSThread();
62 size_t stackStart = thread->GetStackStart();
63 size_t stackSize = stackStart - thread->GetStackLimit();
64 return {stackStart, stackSize};
65 }
66
GetXRefGlobalHandleAddr(const EcmaVM * vm,uintptr_t localAddress)67 uintptr_t JSNApi::GetXRefGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress)
68 {
69 CROSS_THREAD_CHECK(vm);
70 if (localAddress == 0) {
71 return 0;
72 }
73 ecmascript::ThreadManagedScope scope(thread);
74 JSTaggedType value = *(reinterpret_cast<JSTaggedType *>(localAddress));
75 return thread->NewXRefGlobalHandle(value);
76 }
77
78
DisposeXRefGlobalHandleAddr(const EcmaVM * vm,uintptr_t addr)79 void JSNApi::DisposeXRefGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr)
80 {
81 CROSS_THREAD_CHECK(vm);
82 if (addr == 0 || !reinterpret_cast<ecmascript::Node *>(addr)->IsUsing()) {
83 return;
84 }
85 thread->DisposeXRefGlobalHandle(addr);
86 }
87
88 #ifdef PANDA_JS_ETS_HYBRID_MODE
MarkFromObject(const EcmaVM * vm,uintptr_t addr)89 void JSNApi::MarkFromObject(const EcmaVM *vm, uintptr_t addr)
90 {
91 if (addr == 0 || !reinterpret_cast<ecmascript::Node *>(addr)->IsUsing()) {
92 return;
93 }
94 JSTaggedType value = *(reinterpret_cast<JSTaggedType *>(addr));
95 vm->GetCrossVMOperator()->MarkFromObject(value);
96 }
97
IsObjectAlive(const EcmaVM * vm,uintptr_t addr)98 bool JSNApi::IsObjectAlive(const EcmaVM *vm, uintptr_t addr)
99 {
100 if (addr == 0 || !reinterpret_cast<ecmascript::Node *>(addr)->IsUsing()) {
101 return false;
102 }
103 JSTaggedType value = *(reinterpret_cast<JSTaggedType *>(addr));
104 return vm->GetCrossVMOperator()->IsObjectAlive(value);
105 }
106
IsValidHeapObject(const EcmaVM * vm,uintptr_t addr)107 bool JSNApi::IsValidHeapObject(const EcmaVM *vm, uintptr_t addr)
108 {
109 if (addr == 0 || !reinterpret_cast<ecmascript::Node *>(addr)->IsUsing()) {
110 return false;
111 }
112 JSTaggedType value = *(reinterpret_cast<JSTaggedType *>(addr));
113 return vm->GetCrossVMOperator()->IsValidHeapObject(value);
114 }
115 #endif // PANDA_JS_ETS_HYBRID_MODE
116
GetModuleNameSpaceWithPath(const EcmaVM * vm,const char * path)117 Local<ObjectRef> JSNApi::GetModuleNameSpaceWithPath(const EcmaVM *vm, const char *path)
118 {
119 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
120 auto [filePath, recordName] = ModulePathHelper::ResolvePath(path);
121 ecmascript::ThreadManagedScope managedScope(thread);
122 JSHandle<JSTaggedValue> moduleNamespace =
123 ecmascript::NapiModuleLoader::LoadModuleNameSpaceFromFile(thread, recordName, filePath);
124 return JSNApiHelper::ToLocal<ObjectRef>(moduleNamespace);
125 }
126
ResolveOhmUrl(std::string ohmUrl)127 std::pair<std::string, std::string> JSNApi::ResolveOhmUrl(std::string ohmUrl)
128 {
129 return ModulePathHelper::ResolveOhmUrl(ohmUrl);
130 }
131
132 #ifdef PANDA_JS_ETS_HYBRID_MODE
DoHandshake(EcmaVM * vm,void * stsIface,void ** ecmaIface)133 void HandshakeHelper::DoHandshake([[maybe_unused]] EcmaVM *vm, void *stsIface, void **ecmaIface)
134 {
135 ecmascript::CrossVMOperator::DoHandshake(vm, stsIface, ecmaIface);
136 }
137 #endif // PANDA_JS_ETS_HYBRID_MODE
138
InitHybridVMEnv(EcmaVM * vm)139 void JSNApi::InitHybridVMEnv(EcmaVM *vm)
140 {
141 auto instance = ecmascript::Runtime::GetInstance();
142 ASSERT(instance != nullptr);
143
144 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
145 ecmascript::ThreadManagedScope managedScope(thread);
146
147 instance->SetHybridVm(true);
148 ecmascript::ObjectFactory *factory = vm->GetFactory();
149 JSHandle<ecmascript::GlobalEnv> env = vm->GetGlobalEnv();
150 if (env->GetInterfaceTypeSymbol().GetTaggedValue().IsUndefined()) {
151 JSHandle<JSTaggedValue> interfaceTypeSymbol(factory->NewPrivateNameSymbolWithChar("interfaceType"));
152 env->SetInterfaceTypeSymbol(thread, interfaceTypeSymbol.GetTaggedValue());
153 }
154 vm->CreateHybridParam();
155 }
156
157 } // namespace panda
158