Skip to content
Draft
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions .github/azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ jobs:
platform: x64
jsEngine: V8

- template: jobs/win32.yml
parameters:
name: Win32_x64_QuickJS
platform: x64
jsEngine: QuickJS

# UWP
- template: jobs/uwp.yml
parameters:
Expand Down Expand Up @@ -78,6 +84,11 @@ jobs:
name: Android_V8
jsEngine: V8

- template: jobs/android.yml
parameters:
name: Android_QuickJS
jsEngine: QuickJS

# macOS
- template: jobs/macos.yml
parameters:
Expand Down Expand Up @@ -114,13 +125,20 @@ jobs:

- template: jobs/linux.yml
parameters:
name: Ubuntu_clang
name: Ubuntu_clang_javascriptcore
CC: clang
CXX: clang++

- template: jobs/linux.yml
parameters:
name: Ubuntu_Sanitizers_clang
name: Ubuntu_Sanitizers_clang_javascriptcore
enableSanitizers: true
CC: clang
CXX: clang++

- template: jobs/linux.yml
parameters:
name: Ubuntu_clang_quickjs
jsEngine: QuickJS
CC: clang
CXX: clang++
3 changes: 2 additions & 1 deletion .github/jobs/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ parameters:
enableSanitizers: false
CC: gcc
CXX: g++
jsEngine: 'JavaScriptCore'

jobs:
- job: ${{parameters.name}}
Expand All @@ -23,7 +24,7 @@ jobs:
- script: |
export CC=${{parameters.CC}}
export CXX=${{parameters.CXX}}
cmake -B Build/ubuntu -G Ninja -D CMAKE_BUILD_TYPE=RelWithDebInfo -D ENABLE_SANITIZERS=$(SANITIZER_FLAG) -D CMAKE_C_COMPILER=${{parameters.CC}} -D CMAKE_CXX_COMPILER=${{parameters.CXX}}
cmake -B Build/ubuntu -G Ninja -D CMAKE_BUILD_TYPE=Release -D ENABLE_SANITIZERS=$(SANITIZER_FLAG) -D CMAKE_C_COMPILER=${{parameters.CC}} -D CMAKE_CXX_COMPILER=${{parameters.CXX}} -D NAPI_JAVASCRIPT_ENGINE=${{parameters.jsEngine}}
displayName: 'Configure CMake'

- script: |
Expand Down
4 changes: 2 additions & 2 deletions .github/jobs/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ jobs:
scheme: 'UnitTests'
sdk: 'macosx'
useXcpretty: false
configuration: RelWithDebInfo
configuration: Release
displayName: 'Build Xcode Project'

- script: ./UnitTests
workingDirectory: 'Build/macOS/Tests/UnitTests/RelWithDebInfo'
workingDirectory: 'Build/macOS/Tests/UnitTests/Release'
displayName: 'Run Tests'
6 changes: 3 additions & 3 deletions .github/jobs/win32.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
inputs:
solution: 'Build/Win32/JsRuntimeHost.sln'
maximumCpuCount: true
configuration: 'RelWithDebInfo'
configuration: 'Release'
displayName: 'Build Solution'

- script: |
Expand All @@ -32,12 +32,12 @@ jobs:
displayName: 'Enable Crash Dumps'

- script: UnitTests.exe
workingDirectory: 'Build/Win32/Tests/UnitTests/RelWithDebInfo'
workingDirectory: 'Build/Win32/Tests/UnitTests/Release'
displayName: 'Run Tests'

- task: CopyFiles@2
inputs:
sourceFolder: 'Build/Win32/Tests/UnitTests/RelWithDebInfo'
sourceFolder: 'Build/Win32/Tests/UnitTests/Release'
contents: UnitTests.*
targetFolder: '$(Build.ArtifactStagingDirectory)/Dumps'
cleanTargetFolder: false
Expand Down
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ FetchContent_Declare(UrlLib
GIT_REPOSITORY https://github.com/BabylonJS/UrlLib.git
GIT_TAG 1f9d2c05f792d994b09fdfc1129b25294efbe182
EXCLUDE_FROM_ALL)
FetchContent_Declare(quickjs-ng
GIT_REPOSITORY https://github.com/quickjs-ng/quickjs.git
GIT_TAG 97d23e51dcc835e42c4cd419fb4adee13baf0074
EXCLUDE_FROM_ALL)

# --------------------------------------------------

FetchContent_MakeAvailable(CMakeExtensions)
Expand Down Expand Up @@ -121,6 +126,11 @@ if(BABYLON_DEBUG_TRACE)
add_definitions(-DBABYLON_DEBUG_TRACE)
endif()

if(NAPI_JAVASCRIPT_ENGINE STREQUAL "QuickJS")
option(QJS_BUILD_LIBC "Build QuickJS with libc support." ON)
FetchContent_MakeAvailable_With_Message(quickjs-ng)
endif()

if(NAPI_JAVASCRIPT_ENGINE STREQUAL "V8" AND JSRUNTIMEHOST_CORE_APPRUNTIME_V8_INSPECTOR)
FetchContent_MakeAvailable_With_Message(asio)
add_library(asio INTERFACE)
Expand Down
3 changes: 3 additions & 0 deletions Core/AppRuntime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ if(NAPI_JAVASCRIPT_ENGINE STREQUAL "V8" AND JSRUNTIMEHOST_CORE_APPRUNTIME_V8_INS
PRIVATE v8inspector)

set_property(TARGET v8inspector PROPERTY FOLDER Dependencies)
elseif(NAPI_JAVASCRIPT_ENGINE STREQUAL "QuickJS")
target_link_libraries(AppRuntime PRIVATE qjs)
target_compile_definitions(AppRuntime PRIVATE USE_QUICKJS)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To remove

endif()

set_property(TARGET AppRuntime PROPERTY FOLDER Core)
Expand Down
46 changes: 46 additions & 0 deletions Core/AppRuntime/Source/AppRuntime_QuickJS.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "AppRuntime.h"
#include <napi/env.h>

#ifdef _WIN32
#pragma warning(push)
// cast from int64 to int32
#pragma warning(disable : 4244)
#endif
#include <quickjs.h>
#ifdef _WIN32
#pragma warning(pop)
#endif

namespace Babylon
{
void AppRuntime::RunEnvironmentTier(const char* /*executablePath*/)
{
// Create the runtime.
JSRuntime* runtime = JS_NewRuntime();
if (!runtime)
{
throw std::runtime_error{"Failed to create QuickJS runtime"};
}

// Create the context.
JSContext* context = JS_NewContext(runtime);
if (!context)
{
JS_FreeRuntime(runtime);
throw std::runtime_error{"Failed to create QuickJS context"};
}

// Use the context within a scope.
{
Napi::Env env = Napi::Attach(context);

Run(env);

Napi::Detach(env);
}

// Destroy the context and runtime.
JS_FreeContext(context);
JS_FreeRuntime(runtime);
}
}
21 changes: 21 additions & 0 deletions Core/AppRuntime/Source/WorkQueue.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
#include "WorkQueue.h"

#ifdef USE_QUICKJS
#ifdef _WIN32
#pragma warning(push)
// cast from int64 to int32
#pragma warning(disable : 4244)
#endif
#include <quickjs.h>
#ifdef _WIN32
#pragma warning(pop)
#endif
#endif

namespace Babylon
{
WorkQueue::WorkQueue(std::function<void()> threadProcedure)
Expand Down Expand Up @@ -42,6 +54,15 @@ namespace Babylon
while (!m_cancelSource.cancelled())
{
m_dispatcher.blocking_tick(m_cancelSource);
#ifdef USE_QUICKJS
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How to do it properly?

// Process QuickJS microtasks (promise callbacks, etc.)
JSContext* pending_ctx;
int result;
while ((result = JS_ExecutePendingJob(JS_GetRuntime(Napi::GetContext(env)), &pending_ctx)) > 0)
{
// Keep draining the microtask queue
}
#endif
}

m_dispatcher.clear();
Expand Down
8 changes: 7 additions & 1 deletion Core/Node-API/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,13 @@ if(NAPI_BUILD_ABI)
endfunction()
endif()

if(NAPI_JAVASCRIPT_ENGINE STREQUAL "Chakra")
if(NAPI_JAVASCRIPT_ENGINE STREQUAL "QuickJS")
set(SOURCES ${SOURCES}
"Source/env_quickjs.cc"
"Source/js_native_api_quickjs.cc"
"Source/js_native_api_quickjs.h")
set(LINK_LIBRARIES ${LINK_LIBRARIES} PRIVATE qjs)
elseif(NAPI_JAVASCRIPT_ENGINE STREQUAL "Chakra")
set(SOURCES ${SOURCES}
"Source/env_chakra.cc"
"Source/js_native_api_chakra.cc"
Expand Down
15 changes: 15 additions & 0 deletions Core/Node-API/Include/Engine/QuickJS/napi/env.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include <napi/napi.h>
struct JSContext;

namespace Napi
{
Napi::Env Attach(JSContext* context);

void Detach(Napi::Env);

Napi::Value Eval(Napi::Env env, const char* source, const char* sourceUrl);

JSContext* GetContext(Napi::Env);
}
65 changes: 65 additions & 0 deletions Core/Node-API/Source/env_quickjs.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include <napi/env.h>
#include "js_native_api_quickjs.h"
#include <quickjs.h>

namespace Napi
{
Env Attach(JSContext* context)
{
napi_env env_ptr{new napi_env__};
env_ptr->context = context;
env_ptr->current_context = env_ptr->context;

// Get Object.prototype.hasOwnProperty
JSValue global = JS_GetGlobalObject(context);
JSValue object = JS_GetPropertyStr(context, global, "Object");
if (!JS_IsException(object) && JS_IsObject(object))
{
JSValue prototype = JS_GetPrototype(context, object);
if (!JS_IsException(prototype) && JS_IsObject(prototype))
{
JSValue hasOwnProperty = JS_GetPropertyStr(context, prototype, "hasOwnProperty");
if (!JS_IsException(hasOwnProperty))
{
env_ptr->has_own_property_function = hasOwnProperty;
}
else
{
JS_FreeValue(context, hasOwnProperty);
}
JS_FreeValue(context, prototype);
}
else if (JS_IsException(prototype))
{
JS_FreeValue(context, prototype);
}
JS_FreeValue(context, object);
}
else if (JS_IsException(object))
{
JS_FreeValue(context, object);
}
JS_FreeValue(context, global);

return {env_ptr};
}

void Detach(Env env)
{
napi_env env_ptr{env};
if (env_ptr)
{
if (!JS_IsUndefined(env_ptr->has_own_property_function))
{
JS_FreeValue(env_ptr->context, env_ptr->has_own_property_function);
}
delete env_ptr;
}
}

JSContext* GetContext(Env env)
{
napi_env env_ptr{env};
return env_ptr->context;
}
}
Loading
Loading