Skip to content

Commit 2848475

Browse files
authored
port modules from old runtime to node-api (#12)
* initial work * refactor: runtime code * more refactoring, start completing Console API * add back cli build, add URL module, refactor runtime modules * rename runtime cli to nsr * feat: better error handling * workers support * fix v8 build
1 parent 2e321a0 commit 2848475

File tree

316 files changed

+58417
-2351
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

316 files changed

+58417
-2351
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,6 @@ v8_build
5555
/project-template-ios/.build_env_vars.sh
5656
/project-template-ios/__PROJECT_NAME__.xcodeproj/project.xcworkspace/xcshareddata/
5757
/project-template-vision/.build_env_vars.sh
58-
/project-template-vision/__PROJECT_NAME__.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
58+
/project-template-vision/__PROJECT_NAME__.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
59+
60+
.cache/

NativeScript/CMakeLists.txt

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@ cmake_minimum_required(VERSION 3.15)
22

33
# Metadata
44

5-
project(NativeScript)
5+
project(NativeScript CXX OBJCXX)
66

77
set(NAME NativeScript)
88
set(VERSION 0.1.0)
99
set(BUNDLE_IDENTIFIER "org.nativescript.runtime")
1010

11-
enable_language(OBJCXX)
12-
1311
set(CMAKE_CXX_STANDARD 20)
1412

1513
set(BUILD_FRAMEWORK TRUE)
@@ -21,8 +19,9 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMMON_FLAGS}")
2119
# Arguments
2220

2321
set(TARGET_PLATFORM "macos" CACHE STRING "Target platform for the Objective-C bridge")
24-
set(TARGET_ENGINE "hermes" CACHE STRING "Target JS engine for the NativeScript runtime")
22+
set(TARGET_ENGINE "v8" CACHE STRING "Target JS engine for the NativeScript runtime")
2523
set(METADATA_SIZE 0 CACHE STRING "Size of embedded metadata in bytes")
24+
set(BUILD_CLI_BINARY OFF CACHE BOOL "Build the NativeScript CLI binary")
2625

2726
if(TARGET_PLATFORM STREQUAL "ios")
2827
set(CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "13.0")
@@ -72,7 +71,7 @@ elseif(TARGET_ENGINE STREQUAL "hermes")
7271
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -std=c++20 -DTARGET_ENGINE_HERMES")
7372
elseif(TARGET_ENGINE STREQUAL "v8")
7473
set(TARGET_ENGINE_V8 TRUE)
75-
add_link_options("-fuse-ld=/opt/homebrew/opt/llvm/bin/ld64.lld")
74+
add_link_options("-fuse-ld=lld")
7675
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -stdlib=libc++ -std=c++20 -DTARGET_ENGINE_V8")
7776
elseif(TARGET_ENGINE STREQUAL "quickjs")
7877
set(TARGET_ENGINE_QUICKJS TRUE)
@@ -86,6 +85,7 @@ else()
8685
endif()
8786

8887
if(ENABLE_JS_RUNTIME)
88+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_JS_RUNTIME")
8989
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DENABLE_JS_RUNTIME")
9090
elseif(TARGET_PLATFORM_MACOS)
9191
# If building a generic library for macOS, we'll build a dylib instead of a framework
@@ -102,7 +102,6 @@ message(STATUS "ENABLE_JS_RUNTIME = ${ENABLE_JS_RUNTIME}")
102102
include_directories(
103103
./
104104
../metadata-generator/include
105-
ada
106105
napi/common
107106
libffi/${LIBFFI_BUILD}/include
108107
)
@@ -128,20 +127,30 @@ set(SOURCE_FILES
128127
ffi/Interop.mm
129128
ffi/InlineFunctions.mm
130129
ffi/ClassBuilder.mm
130+
ffi/NativeScriptException.mm
131131
)
132132

133133
if(ENABLE_JS_RUNTIME)
134134
set(SOURCE_FILES
135135
${SOURCE_FILES}
136-
runtime/Console.cpp
136+
runtime/modules/console/Console.cpp
137137
runtime/Runtime.cpp
138-
runtime/Require.cpp
139-
runtime/Performance.cpp
138+
runtime/modules/worker/Worker.mm
139+
runtime/modules/worker/MessageJSON.cpp
140+
runtime/modules/worker/MessageV8.cpp
141+
runtime/modules/worker/ConcurrentQueue.cpp
142+
runtime/modules/worker/WorkerImpl.mm
143+
runtime/modules/worker/WorkerImpl.mm
144+
runtime/modules/module/ModuleInternal.cpp
145+
runtime/modules/performance/Performance.cpp
140146
runtime/Bundle.mm
141-
runtime/Timers.mm
142-
runtime/App.mm
147+
runtime/modules/timers/Timers.mm
148+
runtime/modules/app/App.mm
143149
runtime/NativeScript.mm
144150
runtime/RuntimeConfig.cpp
151+
runtime/modules/url/ada/ada.cpp
152+
runtime/modules/url/URL.cpp
153+
runtime/modules/url/URLSearchParams.cpp
145154
)
146155

147156
if(TARGET_ENGINE_V8)
@@ -220,6 +229,13 @@ else()
220229
)
221230
endif()
222231

232+
if(BUILD_CLI_BINARY)
233+
set(SOURCE_FILES ${SOURCE_FILES}
234+
cli/main.cpp
235+
cli/segappend.cpp
236+
)
237+
endif()
238+
223239
# Find SDK
224240

225241
find_program(XCODEBUILD_EXECUTABLE xcodebuild)
@@ -248,11 +264,15 @@ message(STATUS "SDK = ${CMAKE_OSX_SYSROOT}")
248264

249265
# Build targets
250266

251-
add_library(
252-
${NAME}
253-
SHARED
254-
${SOURCE_FILES}
255-
)
267+
if(BUILD_CLI_BINARY)
268+
add_executable(${NAME} ${SOURCE_FILES})
269+
else()
270+
add_library(
271+
${NAME}
272+
SHARED
273+
${SOURCE_FILES}
274+
)
275+
endif()
256276

257277
target_sources(
258278
${NAME}

NativeScript/NativeScript.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ extern "C"
88
#endif // __cplusplus
99

1010
void
11-
objc_bridge_init(void* env, const char* metadata_path, const void* metadata_ptr);
11+
nativescript_init(void* env, const char* metadata_path, const void* metadata_ptr);
1212

1313
#ifdef __OBJC__
1414

NativeScript/cli/main.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#ifdef ENABLE_JS_RUNTIME
2+
3+
#include <filesystem>
4+
#include <fstream>
5+
#include <iostream>
6+
7+
#include "ffi/NativeScriptException.h"
8+
#include "runtime/Bundle.h"
9+
#include "runtime/Runtime.h"
10+
#include "runtime/RuntimeConfig.h"
11+
#include "segappend.h"
12+
13+
using namespace nativescript;
14+
15+
void bootFromBytecode(std::string baseDir, const void* data, size_t size) {
16+
RuntimeConfig.BaseDir = baseDir;
17+
18+
auto runtime = Runtime();
19+
20+
runtime.Init();
21+
22+
// TODO
23+
// runtime.ExecuteBytecode(data, size);
24+
25+
runtime.RunLoop();
26+
}
27+
28+
void bootFromModuleSpec(std::string baseDir, std::string spec) {
29+
RuntimeConfig.BaseDir = baseDir;
30+
31+
auto runtime = Runtime();
32+
33+
runtime.Init();
34+
35+
try {
36+
runtime.RunModule(spec);
37+
} catch (const nativescript::NativeScriptException& e) {
38+
std::cerr << "Uncaught Exception: " << e.Description() << std::endl;
39+
std::exit(1);
40+
}
41+
42+
runtime.RunLoop();
43+
}
44+
45+
int main(int argc, char** argv) {
46+
RuntimeConfig.LogToSystemConsole = true;
47+
48+
#ifdef __APPLE__
49+
std::string bytecodePath = getBytecodePathFromBundle();
50+
if (!bytecodePath.empty()) {
51+
std::string bundlePath = getBundlePath();
52+
53+
std::ifstream file(bytecodePath, std::ios::binary);
54+
if (!file.is_open()) {
55+
std::cout << "Failed to open bytecode file" << std::endl;
56+
return 1;
57+
}
58+
59+
file.seekg(0, std::ios::end);
60+
size_t size = file.tellg();
61+
file.seekg(0, std::ios::beg);
62+
63+
std::vector<uint8_t> data(size);
64+
file.read((char*)data.data(), size);
65+
66+
file.close();
67+
68+
bootFromBytecode(bundlePath, data.data(), size);
69+
70+
return 0;
71+
}
72+
#endif // __APPLE__
73+
74+
const uint8_t* segmentData;
75+
size_t segmentSize;
76+
auto status = segappend_load_segment("__nativescript_start",
77+
(void**)&segmentData, &segmentSize);
78+
79+
std::string cwd = std::filesystem::current_path().string();
80+
81+
if (status == segappend_ok) {
82+
size_t bytecode_size = *(size_t*)segmentData;
83+
segmentData += sizeof(size_t);
84+
85+
bootFromBytecode(cwd, segmentData, bytecode_size);
86+
} else {
87+
if (argc < 3) {
88+
std::cout << "Usage: " << argv[0] << " run <js file>" << std::endl;
89+
return 1;
90+
}
91+
92+
std::string cmd = argv[1];
93+
94+
if (cmd == "run") {
95+
bootFromModuleSpec(cwd, argv[2]);
96+
} else {
97+
std::cout << "Unknown command: " << cmd << std::endl;
98+
return 1;
99+
}
100+
}
101+
102+
return 0;
103+
}
104+
105+
#endif // ENABLE_JS_RUNTIME
File renamed without changes.
File renamed without changes.

NativeScript/ffi/AutoreleasePool.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
#include "node_api_util.h"
55

66
extern "C" {
7-
void *objc_autoreleasePoolPush(void);
8-
void objc_autoreleasePoolPop(void *pool);
7+
void* objc_autoreleasePoolPush(void);
8+
void objc_autoreleasePoolPop(void* pool);
99
}
1010

11-
namespace objc_bridge {
11+
namespace nativescript {
1212

1313
NAPI_FUNCTION(autoreleasepool);
1414

15-
} // namespace objc_bridge
15+
} // namespace nativescript
1616

17-
#endif // AUTORELEASEPOOL_H
17+
#endif // AUTORELEASEPOOL_H

NativeScript/ffi/AutoreleasePool.mm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "AutoreleasePool.h"
22

3-
namespace objc_bridge {
3+
namespace nativescript {
44

55
napi_value JS_autoreleasepool(napi_env env, napi_callback_info info) {
66
napi_value callback;
@@ -15,4 +15,4 @@ napi_value JS_autoreleasepool(napi_env env, napi_callback_info info) {
1515
return result;
1616
}
1717

18-
} // namespace objc_bridge
18+
} // namespace nativescript

NativeScript/ffi/Block.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,32 @@
11
#ifndef BLOCK_H
22
#define BLOCK_H
33

4+
#include <cstdlib>
5+
46
#include "Cif.h"
57
#include "Closure.h"
68
#include "node_api_util.h"
7-
#include <cstdlib>
89

9-
namespace objc_bridge {
10+
namespace nativescript {
1011

1112
class FunctionPointer {
12-
public:
13-
void *function;
13+
public:
14+
void* function;
1415
metagen::MDSectionOffset offset;
15-
Cif *cif;
16+
Cif* cif;
1617

17-
static napi_value wrap(napi_env env, void *function, metagen::MDSectionOffset offset, bool isBlock);
18-
static void finalize(napi_env env, void *finalize_data, void *finalize_hint);
18+
static napi_value wrap(napi_env env, void* function,
19+
metagen::MDSectionOffset offset, bool isBlock);
20+
static void finalize(napi_env env, void* finalize_data, void* finalize_hint);
1921

2022
static napi_value jsCallAsCFunction(napi_env env, napi_callback_info cbinfo);
2123
static napi_value jsCallAsBlock(napi_env env, napi_callback_info cbinfo);
2224
};
2325

24-
id registerBlock(napi_env env, Closure *closure, napi_value callback);
26+
id registerBlock(napi_env env, Closure* closure, napi_value callback);
2527

2628
NAPI_FUNCTION(registerBlock);
2729

28-
} // namespace objc_bridge
30+
} // namespace nativescript
2931

3032
#endif /* BLOCK_H */

NativeScript/ffi/Block.mm

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#include "Block.h"
22
#import <Foundation/Foundation.h>
3-
#include "js_native_api_types.h"
43
#include "Interop.h"
54
#include "ObjCBridge.h"
65
#include "js_native_api.h"
6+
#include "js_native_api_types.h"
77
#include "node_api_util.h"
88
#include "objc/runtime.h"
99

@@ -24,7 +24,7 @@
2424
void* invoke;
2525
Block_descriptor_1* descriptor;
2626
// imported variables
27-
objc_bridge::Closure* closure;
27+
nativescript::Closure* closure;
2828
};
2929

3030
void block_copy(void* dest, void* src) {}
@@ -36,7 +36,7 @@ void block_finalize(napi_env env, void* data, void* hint) {
3636
delete block;
3737
}
3838

39-
namespace objc_bridge {
39+
namespace nativescript {
4040

4141
void* stackBlockISA = nullptr;
4242

@@ -63,22 +63,25 @@ id registerBlock(napi_env env, Closure* closure, napi_value callback) {
6363
// TODO: fix memory management of objc blocks here
6464
// napi_wrap(env, callback, block, block_finalize, nullptr, &ref);
6565
// if (ref == nullptr) {
66-
// Deno doesn't handle napi_wrap properly.
67-
ref = make_ref(env, callback, 1);
66+
// Deno doesn't handle napi_wrap properly.
67+
ref = make_ref(env, callback, 1);
6868
// } else {
6969
// uint32_t refCount;
7070
// napi_reference_ref(env, ref, &refCount);
7171
// }
7272
closure->func = ref;
7373

7474
auto bridgeState = ObjCBridgeState::InstanceData(env);
75+
76+
#ifndef ENABLE_JS_RUNTIME
7577
if (napiSupportsThreadsafeFunctions(bridgeState->self_dl)) {
7678
napi_value workName;
7779
napi_create_string_utf8(env, "Block", NAPI_AUTO_LENGTH, &workName);
7880
napi_create_threadsafe_function(env, callback, nullptr, workName, 0, 1, nullptr, nullptr,
7981
closure, Closure::callBlockFromMainThread, &closure->tsfn);
8082
if (closure->tsfn) napi_unref_threadsafe_function(env, closure->tsfn);
8183
}
84+
#endif // ENABLE_JS_RUNTIME
8285

8386
return (id)block;
8487
}
@@ -207,4 +210,4 @@ id registerBlock(napi_env env, Closure* closure, napi_value callback) {
207210
return cif->returnType->toJS(env, rvalue);
208211
}
209212

210-
} // namespace objc_bridge
213+
} // namespace nativescript

0 commit comments

Comments
 (0)