• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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