Skip to content

Commit 5b9a45e

Browse files
committed
feat: add Hermes JSI shims for manual JSB bindings
- Add toJsiValue/fromJsiValue to se::Value - Add Hermes 4-arg State constructor - Conditionally compile JSI conversions under SCRIPT_ENGINE_HERMES
1 parent 8ad642c commit 5b9a45e

5 files changed

Lines changed: 207 additions & 0 deletions

File tree

native/CMakeLists.txt.rej

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
diff a/native/CMakeLists.txt b/native/CMakeLists.txt (rejected hunks)
2+
@@ -1,6 +1,6 @@
3+
-if(NOT USE_XR AND NOT USE_AR_MODULE)
4+
- include(${CMAKE_CURRENT_LIST_DIR}/cmake/predefine.cmake)
5+
-endif()
6+
+cmake_minimum_required(VERSION 3.22.1)
7+
+
8+
+include(${CMAKE_CURRENT_LIST_DIR}/cmake/predefine.cmake)
9+
10+
################################# engine source code ##################################
11+
set(CWD ${CMAKE_CURRENT_LIST_DIR})
12+
@@ -13,7 +13,24 @@ set(ENGINE_NAME cocos_engine)
13+
################################# options ############################################
14+
# default fallback options
15+
cc_set_if_undefined(CC_DEBUG_FORCE OFF)
16+
-cc_set_if_undefined(USE_SE_V8 ON)
17+
+cc_set_if_undefined(USE_SE_V8 OFF)
18+
+cc_set_if_undefined(USE_SE_HERMES ON)
19+
+cc_set_if_undefined(USE_V8_DEBUGGER OFF)
20+
+
21+
+# Dynamically locate React Native JSI headers for Hermes support
22+
+if(USE_SE_HERMES)
23+
+ execute_process(
24+
+ COMMAND node -e "console.log(require('path').dirname(require.resolve('react-native/package.json')))"
25+
+ OUTPUT_VARIABLE REACT_NATIVE_DIR
26+
+ OUTPUT_STRIP_TRAILING_WHITESPACE
27+
+ )
28+
+ set(REACT_NATIVE_JSI_DIR "${REACT_NATIVE_DIR}/ReactCommon/jsi")
29+
+ if(EXISTS "${REACT_NATIVE_JSI_DIR}")
30+
+ message(STATUS "Found React Native JSI headers at: ${REACT_NATIVE_JSI_DIR}")
31+
+ else()
32+
+ message(FATAL_ERROR "Hermes JSI headers not found at: ${REACT_NATIVE_JSI_DIR}")
33+
+ endif()
34+
+endif()
35+
cc_set_if_undefined(USE_SE_SM OFF)
36+
cc_set_if_undefined(USE_SE_NAPI OFF)
37+
cc_set_if_undefined(USE_SE_JSVM OFF)
38+
@@ -3274,18 +3291,26 @@ if(USE_MODULES)
39+
add_library(ccgeometry ${ccgeometry_SOURCE_LIST})
40+
41+
target_include_directories(ccmath PRIVATE
42+
+ ${CWD}
43+
${CWD}/cocos
44+
+ $<$<BOOL:${USE_SE_HERMES}>:${REACT_NATIVE_JSI_DIR}>
45+
)
46+
target_include_directories(ccgeometry PRIVATE
47+
+ ${CWD}
48+
${CWD}/cocos
49+
+ $<$<BOOL:${USE_SE_HERMES}>:${REACT_NATIVE_JSI_DIR}>
50+
)
51+
target_include_directories(ccunzip PRIVATE
52+
+ ${CWD}
53+
${CWD}/external/sources/unzip
54+
${CWD}/external/sources
55+
${CWD}/cocos
56+
+ $<$<BOOL:${USE_SE_HERMES}>:${REACT_NATIVE_JSI_DIR}>
57+
)
58+
target_include_directories(cclog PRIVATE
59+
+ ${CWD}
60+
${CWD}/cocos
61+
+ $<$<BOOL:${USE_SE_HERMES}>:${REACT_NATIVE_JSI_DIR}>
62+
)
63+
target_include_directories(ccfilesystem PRIVATE
64+
${CWD}
65+
@@ -3293,15 +3318,17 @@ if(USE_MODULES)
66+
${CWD}/external/sources
67+
)
68+
target_include_directories(ccutils PRIVATE
69+
+ ${CWD}
70+
${CWD}/cocos
71+
${CWD}/external/sources
72+
+ $<$<BOOL:${USE_SE_HERMES}>:${REACT_NATIVE_JSI_DIR}>
73+
)
74+
target_include_directories(ccbindings PRIVATE
75+
+ ${CWD}
76+
${CWD}/cocos
77+
${CWD}/cocos/bindings/jswrapper
78+
${CWD}/cocos/editor-support # TODO: refactor include path
79+
- ${CWD}
80+
- ${CC_EXTERNAL_INCLUDES}
81+
+ $<$<BOOL:${USE_SE_HERMES}>:${REACT_NATIVE_JSI_DIR}>
82+
)
83+
target_link_libraries(ccunzip PUBLIC
84+
${ZLIB}
85+
@@ -3368,6 +3395,9 @@ if(QNX)
86+
list(APPEND COCOS_SOURCE_LIST ${ccqnx_SOURCE_LIST})
87+
endif()
88+
89+
+# ── Extended module split ──────────────────────────────────────────────────
90+
+include("${CMAKE_CURRENT_LIST_DIR}/CocosModuleSplit.cmake")
91+
+
92+
add_library(${ENGINE_NAME} ${COCOS_SOURCE_LIST})
93+
94+
if(CMAKE_GENERATOR STREQUAL "Xcode")
95+
@@ -3444,6 +3474,7 @@ function(cc_apply_definations target)
96+
$<$<BOOL:${USE_SE_V8}>:SCRIPT_ENGINE_TYPE=2>
97+
$<$<BOOL:${USE_SE_NAPI}>:SCRIPT_ENGINE_TYPE=5>
98+
$<$<BOOL:${USE_SE_JSVM}>:SCRIPT_ENGINE_TYPE=6>
99+
+ $<$<BOOL:${USE_SE_HERMES}>:SCRIPT_ENGINE_TYPE=7>
100+
$<$<OR:$<CONFIG:Debug>,$<BOOL:${CC_DEBUG_FORCE}>>:CC_DEBUG=1>
101+
$<IF:$<BOOL:${USE_ADPF}>,CC_USE_ADPF=1,CC_USE_ADPF=0>
102+
$<IF:$<BOOL:${USE_GOOGLE_BILLING}>,CC_USE_GOOGLE_BILLING=1,CC_USE_GOOGLE_BILLING=0>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#pragma once
2+
#define OSCL_UNUSED_ARG(x) (void)(x)

native/cocos/bindings/jswrapper/State.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
#include "PrivateObject.h"
3030
#include "Value.h"
3131

32+
#if SCRIPT_ENGINE_TYPE == SCRIPT_ENGINE_HERMES
33+
#include <jsi/jsi.h>
34+
#endif
35+
3236
namespace se {
3337

3438
class Object;
@@ -97,6 +101,28 @@ class State final {
97101
}
98102
}
99103

104+
#if SCRIPT_ENGINE_TYPE == SCRIPT_ENGINE_HERMES
105+
State(facebook::jsi::Runtime* rt,
106+
const facebook::jsi::Value* thisVal,
107+
const facebook::jsi::Value* argv,
108+
size_t argc) : _thisObject(nullptr), _args(nullptr), _argc(argc), _rt(rt) {
109+
if (thisVal != nullptr) {
110+
_seThisVal.fromJsiValue(*rt, *thisVal);
111+
_thisObject = _seThisVal.toObject();
112+
}
113+
if (argv != nullptr && argc > 0) {
114+
_seArgs.reserve(argc);
115+
for (size_t i = 0; i < argc; ++i) {
116+
se::Value val;
117+
val.fromJsiValue(*rt, argv[i]);
118+
_seArgs.push_back(std::move(val));
119+
}
120+
_args = &_seArgs;
121+
if (_thisObject != nullptr) _thisObject->incRef();
122+
}
123+
}
124+
#endif
125+
100126
// Disable copy/move constructor, copy/move assigment
101127
State(const State &) = delete;
102128
State(State &&) noexcept = delete;
@@ -107,5 +133,12 @@ class State final {
107133
Object *_thisObject{nullptr}; // weak ref
108134
const ValueArray *_args{nullptr}; // weak ref
109135
Value _retVal; // weak ref
136+
137+
#if SCRIPT_ENGINE_TYPE == SCRIPT_ENGINE_HERMES
138+
size_t _argc{0};
139+
facebook::jsi::Runtime* _rt{nullptr};
140+
se::Value _seThisVal;
141+
mutable ccstd::vector<se::Value> _seArgs;
142+
#endif
110143
};
111144
} // namespace se

native/cocos/bindings/jswrapper/Value.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,4 +573,65 @@ double Value::toNumber() const {
573573
return toDouble();
574574
}
575575

576+
#if SCRIPT_ENGINE_TYPE == SCRIPT_ENGINE_HERMES
577+
facebook::jsi::Value Value::toJsiValue(facebook::jsi::Runtime& rt) const {
578+
switch (_type) {
579+
case Type::Undefined:
580+
return facebook::jsi::Value::undefined();
581+
case Type::Null:
582+
return facebook::jsi::Value::null();
583+
case Type::Boolean:
584+
return facebook::jsi::Value(_u._boolean);
585+
case Type::Number:
586+
return facebook::jsi::Value(rt, _u._number);
587+
case Type::String:
588+
return facebook::jsi::Value(rt, facebook::jsi::String::createFromUtf8(rt, *_u._string));
589+
case Type::BigInt:
590+
return facebook::jsi::Value(rt, static_cast<int64_t>(_u._bigint));
591+
case Type::Object:
592+
if (_u._object != nullptr) {
593+
void* data = _u._object->getPrivateData();
594+
if (data != nullptr) {
595+
return facebook::jsi::Value(rt, reinterpret_cast<facebook::jsi::Object*>(data));
596+
}
597+
}
598+
return facebook::jsi::Value::null();
599+
default:
600+
return facebook::jsi::Value::undefined();
601+
}
602+
}
603+
604+
void Value::fromJsiValue(facebook::jsi::Runtime& rt, const facebook::jsi::Value& val) {
605+
reset(Type::Undefined);
606+
if (val.isUndefined()) {
607+
return;
608+
}
609+
if (val.isNull()) {
610+
setNull();
611+
return;
612+
}
613+
if (val.isBool()) {
614+
setBoolean(val.getBool());
615+
return;
616+
}
617+
if (val.isNumber()) {
618+
setNumber(val.getNumber());
619+
return;
620+
}
621+
if (val.isString()) {
622+
setString(val.getString(rt).utf8(rt));
623+
return;
624+
}
625+
if (val.isObject()) {
626+
void* data = val.getObject(rt).getHostObject<jsi::Object>(rt);
627+
if (data != nullptr) {
628+
setObject(reinterpret_cast<se::Object*>(data));
629+
} else {
630+
setObject(nullptr);
631+
}
632+
return;
633+
}
634+
}
635+
#endif
636+
576637
} // namespace se

native/cocos/bindings/jswrapper/Value.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131
#include "base/std/container/string.h"
3232
#include "base/std/container/vector.h"
3333

34+
#if SCRIPT_ENGINE_TYPE == SCRIPT_ENGINE_HERMES
35+
#include <jsi/jsi.h>
36+
#endif
37+
3438
namespace se {
3539

3640
class Object;
@@ -474,6 +478,11 @@ class Value final {
474478
return static_cast<uintptr_t>(toUint64());
475479
}
476480

481+
#if SCRIPT_ENGINE_TYPE == SCRIPT_ENGINE_HERMES
482+
facebook::jsi::Value toJsiValue(facebook::jsi::Runtime& rt) const;
483+
void fromJsiValue(facebook::jsi::Runtime& rt, const facebook::jsi::Value& val);
484+
#endif
485+
477486
private:
478487
explicit Value(Type type);
479488
void reset(Type type);

0 commit comments

Comments
 (0)