Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,6 @@ v8_build
/project-template-ios/.build_env_vars.sh
/project-template-ios/__PROJECT_NAME__.xcodeproj/project.xcworkspace/xcshareddata/
/project-template-vision/.build_env_vars.sh
/project-template-vision/__PROJECT_NAME__.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
/project-template-vision/__PROJECT_NAME__.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist

.cache/
57 changes: 39 additions & 18 deletions NativeScript/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ cmake_minimum_required(VERSION 3.15)

# Metadata

project(NativeScript)
project(NativeScript CXX OBJCXX)

set(NAME NativeScript)
set(VERSION 0.1.0)
set(BUNDLE_IDENTIFIER "org.nativescript.runtime")

enable_language(OBJCXX)

set(CMAKE_CXX_STANDARD 20)

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

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

if(TARGET_PLATFORM STREQUAL "ios")
set(CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "13.0")
Expand Down Expand Up @@ -72,7 +71,7 @@ elseif(TARGET_ENGINE STREQUAL "hermes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -std=c++20 -DTARGET_ENGINE_HERMES")
elseif(TARGET_ENGINE STREQUAL "v8")
set(TARGET_ENGINE_V8 TRUE)
add_link_options("-fuse-ld=/opt/homebrew/opt/llvm/bin/ld64.lld")
add_link_options("-fuse-ld=lld")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -stdlib=libc++ -std=c++20 -DTARGET_ENGINE_V8")
elseif(TARGET_ENGINE STREQUAL "quickjs")
set(TARGET_ENGINE_QUICKJS TRUE)
Expand All @@ -86,6 +85,7 @@ else()
endif()

if(ENABLE_JS_RUNTIME)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_JS_RUNTIME")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DENABLE_JS_RUNTIME")
elseif(TARGET_PLATFORM_MACOS)
# If building a generic library for macOS, we'll build a dylib instead of a framework
Expand All @@ -102,7 +102,6 @@ message(STATUS "ENABLE_JS_RUNTIME = ${ENABLE_JS_RUNTIME}")
include_directories(
./
../metadata-generator/include
ada
napi/common
libffi/${LIBFFI_BUILD}/include
)
Expand All @@ -128,20 +127,30 @@ set(SOURCE_FILES
ffi/Interop.mm
ffi/InlineFunctions.mm
ffi/ClassBuilder.mm
ffi/NativeScriptException.mm
)

if(ENABLE_JS_RUNTIME)
set(SOURCE_FILES
${SOURCE_FILES}
runtime/Console.cpp
runtime/modules/console/Console.cpp
runtime/Runtime.cpp
runtime/Require.cpp
runtime/Performance.cpp
runtime/modules/worker/Worker.mm
runtime/modules/worker/MessageJSON.cpp
runtime/modules/worker/MessageV8.cpp
runtime/modules/worker/ConcurrentQueue.cpp
runtime/modules/worker/WorkerImpl.mm
runtime/modules/worker/WorkerImpl.mm
runtime/modules/module/ModuleInternal.cpp
runtime/modules/performance/Performance.cpp
runtime/Bundle.mm
runtime/Timers.mm
runtime/App.mm
runtime/modules/timers/Timers.mm
runtime/modules/app/App.mm
runtime/NativeScript.mm
runtime/RuntimeConfig.cpp
runtime/modules/url/ada/ada.cpp
runtime/modules/url/URL.cpp
runtime/modules/url/URLSearchParams.cpp
)

if(TARGET_ENGINE_V8)
Expand All @@ -161,8 +170,9 @@ if(ENABLE_JS_RUNTIME)
elseif(TARGET_ENGINE_HERMES)
include_directories(
napi/hermes
napi/hermes/hermes
napi/hermes/jsi
napi/hermes/include
napi/hermes/include/hermes
napi/hermes/include/jsi
)

set(SOURCE_FILES
Expand Down Expand Up @@ -219,6 +229,13 @@ else()
)
endif()

if(BUILD_CLI_BINARY)
set(SOURCE_FILES ${SOURCE_FILES}
cli/main.cpp
cli/segappend.cpp
)
endif()

# Find SDK

find_program(XCODEBUILD_EXECUTABLE xcodebuild)
Expand Down Expand Up @@ -247,11 +264,15 @@ message(STATUS "SDK = ${CMAKE_OSX_SYSROOT}")

# Build targets

add_library(
${NAME}
SHARED
${SOURCE_FILES}
)
if(BUILD_CLI_BINARY)
add_executable(${NAME} ${SOURCE_FILES})
else()
add_library(
${NAME}
SHARED
${SOURCE_FILES}
)
endif()

target_sources(
${NAME}
Expand Down
2 changes: 1 addition & 1 deletion NativeScript/NativeScript.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ extern "C"
#endif // __cplusplus

void
objc_bridge_init(void* env, const char* metadata_path, const void* metadata_ptr);
nativescript_init(void* env, const char* metadata_path, const void* metadata_ptr);

#ifdef __OBJC__

Expand Down
105 changes: 105 additions & 0 deletions NativeScript/cli/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#ifdef ENABLE_JS_RUNTIME

#include <filesystem>
#include <fstream>
#include <iostream>

#include "ffi/NativeScriptException.h"
#include "runtime/Bundle.h"
#include "runtime/Runtime.h"
#include "runtime/RuntimeConfig.h"
#include "segappend.h"

using namespace nativescript;

void bootFromBytecode(std::string baseDir, const void* data, size_t size) {
RuntimeConfig.BaseDir = baseDir;

auto runtime = Runtime();

runtime.Init();

// TODO
// runtime.ExecuteBytecode(data, size);

runtime.RunLoop();
}

void bootFromModuleSpec(std::string baseDir, std::string spec) {
RuntimeConfig.BaseDir = baseDir;

auto runtime = Runtime();

runtime.Init();

try {
runtime.RunModule(spec);
} catch (const nativescript::NativeScriptException& e) {
std::cerr << "Uncaught Exception: " << e.Description() << std::endl;
std::exit(1);
}

runtime.RunLoop();
}

int main(int argc, char** argv) {
RuntimeConfig.LogToSystemConsole = true;

#ifdef __APPLE__
std::string bytecodePath = getBytecodePathFromBundle();
if (!bytecodePath.empty()) {
std::string bundlePath = getBundlePath();

std::ifstream file(bytecodePath, std::ios::binary);
if (!file.is_open()) {
std::cout << "Failed to open bytecode file" << std::endl;
return 1;
}

file.seekg(0, std::ios::end);
size_t size = file.tellg();
file.seekg(0, std::ios::beg);

std::vector<uint8_t> data(size);
file.read((char*)data.data(), size);

file.close();

bootFromBytecode(bundlePath, data.data(), size);

return 0;
}
#endif // __APPLE__

const uint8_t* segmentData;
size_t segmentSize;
auto status = segappend_load_segment("__nativescript_start",
(void**)&segmentData, &segmentSize);

std::string cwd = std::filesystem::current_path().string();

if (status == segappend_ok) {
size_t bytecode_size = *(size_t*)segmentData;
segmentData += sizeof(size_t);

bootFromBytecode(cwd, segmentData, bytecode_size);
} else {
if (argc < 3) {
std::cout << "Usage: " << argv[0] << " run <js file>" << std::endl;
return 1;
}

std::string cmd = argv[1];

if (cmd == "run") {
bootFromModuleSpec(cwd, argv[2]);
} else {
std::cout << "Unknown command: " << cmd << std::endl;
return 1;
}
}

return 0;
}

#endif // ENABLE_JS_RUNTIME
File renamed without changes.
File renamed without changes.
10 changes: 5 additions & 5 deletions NativeScript/ffi/AutoreleasePool.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
#include "node_api_util.h"

extern "C" {
void *objc_autoreleasePoolPush(void);
void objc_autoreleasePoolPop(void *pool);
void* objc_autoreleasePoolPush(void);
void objc_autoreleasePoolPop(void* pool);
}

namespace objc_bridge {
namespace nativescript {

NAPI_FUNCTION(autoreleasepool);

} // namespace objc_bridge
} // namespace nativescript

#endif // AUTORELEASEPOOL_H
#endif // AUTORELEASEPOOL_H
4 changes: 2 additions & 2 deletions NativeScript/ffi/AutoreleasePool.mm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "AutoreleasePool.h"

namespace objc_bridge {
namespace nativescript {

napi_value JS_autoreleasepool(napi_env env, napi_callback_info info) {
napi_value callback;
Expand All @@ -15,4 +15,4 @@ napi_value JS_autoreleasepool(napi_env env, napi_callback_info info) {
return result;
}

} // namespace objc_bridge
} // namespace nativescript
20 changes: 11 additions & 9 deletions NativeScript/ffi/Block.h
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
#ifndef BLOCK_H
#define BLOCK_H

#include <cstdlib>

#include "Cif.h"
#include "Closure.h"
#include "node_api_util.h"
#include <cstdlib>

namespace objc_bridge {
namespace nativescript {

class FunctionPointer {
public:
void *function;
public:
void* function;
metagen::MDSectionOffset offset;
Cif *cif;
Cif* cif;

static napi_value wrap(napi_env env, void *function, metagen::MDSectionOffset offset, bool isBlock);
static void finalize(napi_env env, void *finalize_data, void *finalize_hint);
static napi_value wrap(napi_env env, void* function,
metagen::MDSectionOffset offset, bool isBlock);
static void finalize(napi_env env, void* finalize_data, void* finalize_hint);

static napi_value jsCallAsCFunction(napi_env env, napi_callback_info cbinfo);
static napi_value jsCallAsBlock(napi_env env, napi_callback_info cbinfo);
};

id registerBlock(napi_env env, Closure *closure, napi_value callback);
id registerBlock(napi_env env, Closure* closure, napi_value callback);

NAPI_FUNCTION(registerBlock);

} // namespace objc_bridge
} // namespace nativescript

#endif /* BLOCK_H */
15 changes: 9 additions & 6 deletions NativeScript/ffi/Block.mm
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include "Block.h"
#import <Foundation/Foundation.h>
#include "js_native_api_types.h"
#include "Interop.h"
#include "ObjCBridge.h"
#include "js_native_api.h"
#include "js_native_api_types.h"
#include "node_api_util.h"
#include "objc/runtime.h"

Expand All @@ -24,7 +24,7 @@
void* invoke;
Block_descriptor_1* descriptor;
// imported variables
objc_bridge::Closure* closure;
nativescript::Closure* closure;
};

void block_copy(void* dest, void* src) {}
Expand All @@ -36,7 +36,7 @@ void block_finalize(napi_env env, void* data, void* hint) {
delete block;
}

namespace objc_bridge {
namespace nativescript {

void* stackBlockISA = nullptr;

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

auto bridgeState = ObjCBridgeState::InstanceData(env);

#ifndef ENABLE_JS_RUNTIME
if (napiSupportsThreadsafeFunctions(bridgeState->self_dl)) {
napi_value workName;
napi_create_string_utf8(env, "Block", NAPI_AUTO_LENGTH, &workName);
napi_create_threadsafe_function(env, callback, nullptr, workName, 0, 1, nullptr, nullptr,
closure, Closure::callBlockFromMainThread, &closure->tsfn);
if (closure->tsfn) napi_unref_threadsafe_function(env, closure->tsfn);
}
#endif // ENABLE_JS_RUNTIME

return (id)block;
}
Expand Down Expand Up @@ -207,4 +210,4 @@ id registerBlock(napi_env env, Closure* closure, napi_value callback) {
return cif->returnType->toJS(env, rvalue);
}

} // namespace objc_bridge
} // namespace nativescript
Loading
Loading