diff --git a/android/CMakeLists.txt b/android/CMakeLists.txt index dfb6221d..a0d4a6e8 100644 --- a/android/CMakeLists.txt +++ b/android/CMakeLists.txt @@ -1,161 +1,161 @@ - -add_library(crypto STATIC IMPORTED GLOBAL) -set_target_properties(crypto PROPERTIES - IMPORTED_LOCATION ${platform_spec_path}/libcrypto.a -) - -add_library(freetype STATIC IMPORTED GLOBAL) -set_target_properties(freetype PROPERTIES - IMPORTED_LOCATION ${platform_spec_path}/libfreetype.a -) - -add_library(jpeg STATIC IMPORTED GLOBAL) -set_target_properties(jpeg PROPERTIES - IMPORTED_LOCATION ${platform_spec_path}/libjpeg.a -) - -add_library(png STATIC IMPORTED GLOBAL) -set_target_properties(png PROPERTIES - IMPORTED_LOCATION ${platform_spec_path}/libpng.a -) - -add_library(ssl STATIC IMPORTED GLOBAL) -set_target_properties(ssl PROPERTIES - IMPORTED_LOCATION ${platform_spec_path}/libssl.a -) - -add_library(uv STATIC IMPORTED GLOBAL) -set_target_properties(uv PROPERTIES - IMPORTED_LOCATION ${platform_spec_path}/libuv.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/uv -) - -add_library(openxr SHARED IMPORTED GLOBAL) -set_target_properties(openxr PROPERTIES - IMPORTED_LOCATION ${platform_spec_path}/libxr_loader.so - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/openxr -) - -add_library(webp STATIC IMPORTED GLOBAL) -set_target_properties(webp PROPERTIES - IMPORTED_LOCATION ${platform_spec_path}/libwebp.a -) - -add_library(websockets STATIC IMPORTED GLOBAL) -set_target_properties(websockets PROPERTIES - IMPORTED_LOCATION ${platform_spec_path}/libwebsockets.a -) - -add_library(z STATIC IMPORTED GLOBAL) -set_target_properties(z PROPERTIES - IMPORTED_LOCATION ${platform_spec_path}/libz.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/zlib -) - -add_library(android_platform STATIC - ${CMAKE_ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c -) -target_include_directories(android_platform PUBLIC - ${CMAKE_ANDROID_NDK}/sources/android/cpufeatures - ${CMAKE_ANDROID_NDK}/sources/android/native_app_glue -) - -## Settings from ${CMAKE_ANDROID_NDK}/sources/android/native_app_glue/Android.mk -# set_property(TARGET android_platform APPEND_STRING PROPERTY LINK_FLAGS "-u ANativeActivity_onCreate") -# target_link_libraries(android_platform PUBLIC -# android log dl -# ) - -set(se_libs_name) - -if(USE_SE_V8) - - add_library(v8_monolith STATIC IMPORTED GLOBAL) - set_target_properties(v8_monolith PROPERTIES - IMPORTED_LOCATION ${platform_spec_path}/v8/libv8_monolith.a - ) - - if(ANDROID_ABI STREQUAL "arm64-v8a" OR ANDROID_ABI STREQUAL "x86_64") - set_property(TARGET v8_monolith - APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS V8_COMPRESS_POINTERS - ) - endif() - - add_library(v8_inspector STATIC IMPORTED GLOBAL) - set_target_properties(v8_inspector PROPERTIES - IMPORTED_LOCATION ${platform_spec_path}/v8/libinspector.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/v8 - ) - set(se_libs_name v8_monolith v8_inspector) -endif() - -if(USE_SOCKET) - list(APPEND CC_EXTERNAL_LIBS - websockets - ssl - crypto - ) -endif() - -if(USE_SE_V8 AND USE_V8_DEBUGGER) - list(APPEND CC_EXTERNAL_LIBS - v8_inspector - ) -endif() - -############################# glslang ############################# - -set(glslang_libs_name glslang glslang-default-resource-limits MachineIndependent OGLCompiler OSDependent SPIRV SPIRV-Tools-opt SPIRV-Tools GenericCodeGen) -foreach(lib IN LISTS glslang_libs_name) - add_library(${lib} STATIC IMPORTED GLOBAL) - set_target_properties(${lib} PROPERTIES - IMPORTED_LOCATION ${platform_spec_path}/glslang/lib${lib}.a - ) -endforeach() - -############################# TBB ############################# - -add_library(tbb STATIC IMPORTED GLOBAL) -set_target_properties(tbb PROPERTIES - IMPORTED_LOCATION ${platform_spec_path}/libtbb_static.a -) -set(tbb_libs_name tbb) - -if(USE_PHYSICS_PHYSX) - set(PhysXSDK PhysXCooking PhysXCharacterKinematic PhysXVehicle PhysXExtensions PhysX PhysXPvdSDK PhysXCommon PhysXFoundation) - foreach(PX IN LISTS PhysXSDK) - add_library(${PX} STATIC IMPORTED GLOBAL) - set_target_properties(${PX} PROPERTIES - IMPORTED_LOCATION ${platform_spec_path}/PhysX/lib${PX}_static.a - ) - endforeach() -else() - set(PhysXSDK) -endif() - -list(APPEND CC_EXTERNAL_LIBS - freetype - jpeg - png - uv - webp - android_platform - ${glslang_libs_name} - ${tbb_libs_name} - ${PhysXSDK} -) - -set(ZLIB z) -if(NOT USE_MODULES) - list(APPEND CC_EXTERNAL_LIBS ${ZLIB} ${se_libs_name}) -endif() - - - -list(APPEND CC_EXTERNAL_INCLUDES - ${platform_spec_path}/include - ${platform_spec_path}/include/v8 - ${platform_spec_path}/include/uv - ${platform_spec_path}/include/glslang - ${CMAKE_ANDROID_NDK}/sources/android/native_app_glue -) + +add_library(crypto STATIC IMPORTED GLOBAL) +set_target_properties(crypto PROPERTIES + IMPORTED_LOCATION ${platform_spec_path}/libcrypto.a +) + +add_library(freetype STATIC IMPORTED GLOBAL) +set_target_properties(freetype PROPERTIES + IMPORTED_LOCATION ${platform_spec_path}/libfreetype.a +) + +add_library(jpeg STATIC IMPORTED GLOBAL) +set_target_properties(jpeg PROPERTIES + IMPORTED_LOCATION ${platform_spec_path}/libjpeg.a +) + +add_library(png STATIC IMPORTED GLOBAL) +set_target_properties(png PROPERTIES + IMPORTED_LOCATION ${platform_spec_path}/libpng.a +) + +add_library(ssl STATIC IMPORTED GLOBAL) +set_target_properties(ssl PROPERTIES + IMPORTED_LOCATION ${platform_spec_path}/libssl.a +) + +add_library(uv STATIC IMPORTED GLOBAL) +set_target_properties(uv PROPERTIES + IMPORTED_LOCATION ${platform_spec_path}/libuv.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/uv +) + +add_library(openxr SHARED IMPORTED GLOBAL) +set_target_properties(openxr PROPERTIES + IMPORTED_LOCATION ${platform_spec_path}/libxr_loader.so + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/openxr +) + +add_library(webp STATIC IMPORTED GLOBAL) +set_target_properties(webp PROPERTIES + IMPORTED_LOCATION ${platform_spec_path}/libwebp.a +) + +add_library(websockets STATIC IMPORTED GLOBAL) +set_target_properties(websockets PROPERTIES + IMPORTED_LOCATION ${platform_spec_path}/libwebsockets.a +) + +add_library(z STATIC IMPORTED GLOBAL) +set_target_properties(z PROPERTIES + IMPORTED_LOCATION ${platform_spec_path}/libz.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/zlib +) + +add_library(android_platform STATIC + ${CMAKE_ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c +) +target_include_directories(android_platform PUBLIC + ${CMAKE_ANDROID_NDK}/sources/android/cpufeatures + ${CMAKE_ANDROID_NDK}/sources/android/native_app_glue +) + +## Settings from ${CMAKE_ANDROID_NDK}/sources/android/native_app_glue/Android.mk +# set_property(TARGET android_platform APPEND_STRING PROPERTY LINK_FLAGS "-u ANativeActivity_onCreate") +# target_link_libraries(android_platform PUBLIC +# android log dl +# ) + +set(se_libs_name) + +if(USE_SE_V8 OR USE_NODE_NAPI) + + add_library(v8_monolith STATIC IMPORTED GLOBAL) + set_target_properties(v8_monolith PROPERTIES + IMPORTED_LOCATION ${platform_spec_path}/v8/libv8_monolith.a + ) + + if(ANDROID_ABI STREQUAL "arm64-v8a" OR ANDROID_ABI STREQUAL "x86_64") + set_property(TARGET v8_monolith + APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS V8_COMPRESS_POINTERS + ) + endif() + + add_library(v8_inspector STATIC IMPORTED GLOBAL) + set_target_properties(v8_inspector PROPERTIES + IMPORTED_LOCATION ${platform_spec_path}/v8/libinspector.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/v8 + ) + set(se_libs_name v8_monolith v8_inspector) +endif() + +if(USE_SOCKET) + list(APPEND CC_EXTERNAL_LIBS + websockets + ssl + crypto + ) +endif() + +if(USE_SE_V8 AND USE_V8_DEBUGGER) + list(APPEND CC_EXTERNAL_LIBS + v8_inspector + ) +endif() + +############################# glslang ############################# + +set(glslang_libs_name glslang glslang-default-resource-limits MachineIndependent OGLCompiler OSDependent SPIRV SPIRV-Tools-opt SPIRV-Tools GenericCodeGen) +foreach(lib IN LISTS glslang_libs_name) + add_library(${lib} STATIC IMPORTED GLOBAL) + set_target_properties(${lib} PROPERTIES + IMPORTED_LOCATION ${platform_spec_path}/glslang/lib${lib}.a + ) +endforeach() + +############################# TBB ############################# + +add_library(tbb STATIC IMPORTED GLOBAL) +set_target_properties(tbb PROPERTIES + IMPORTED_LOCATION ${platform_spec_path}/libtbb_static.a +) +set(tbb_libs_name tbb) + +if(USE_PHYSICS_PHYSX) + set(PhysXSDK PhysXCooking PhysXCharacterKinematic PhysXVehicle PhysXExtensions PhysX PhysXPvdSDK PhysXCommon PhysXFoundation) + foreach(PX IN LISTS PhysXSDK) + add_library(${PX} STATIC IMPORTED GLOBAL) + set_target_properties(${PX} PROPERTIES + IMPORTED_LOCATION ${platform_spec_path}/PhysX/lib${PX}_static.a + ) + endforeach() +else() + set(PhysXSDK) +endif() + +list(APPEND CC_EXTERNAL_LIBS + freetype + jpeg + png + uv + webp + android_platform + ${glslang_libs_name} + ${tbb_libs_name} + ${PhysXSDK} +) + +set(ZLIB z) +if(NOT USE_MODULES) + list(APPEND CC_EXTERNAL_LIBS ${ZLIB} ${se_libs_name}) +endif() + + + +list(APPEND CC_EXTERNAL_INCLUDES + ${platform_spec_path}/include + ${platform_spec_path}/include/v8 + ${platform_spec_path}/include/uv + ${platform_spec_path}/include/glslang + ${CMAKE_ANDROID_NDK}/sources/android/native_app_glue +) diff --git a/emscripten/CMakeLists.txt b/emscripten/CMakeLists.txt index ea696af2..2e5bc659 100644 --- a/emscripten/CMakeLists.txt +++ b/emscripten/CMakeLists.txt @@ -1,72 +1,72 @@ - -add_library(z STATIC IMPORTED GLOBAL) -set_target_properties(z PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libz.a - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/zlib -) - -############################# SPIRV-Cross ############################# -# add_library(spirv-cross-core STATIC IMPORTED GLOBAL) -# set_target_properties(spirv-cross-core PROPERTIES -# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libspirv-cross-core.a -# INTERFACE_INCLUDE_DIRECTORIES "${SPIRV_INCLUDE_DIRS}" -# ) -# add_library(spirv-cross-msl STATIC IMPORTED GLOBAL) -# set_target_properties(spirv-cross-msl PROPERTIES -# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libspirv-cross-msl.a -# ) -# add_library(spirv-cross-glsl STATIC IMPORTED GLOBAL) -# set_target_properties(spirv-cross-glsl PROPERTIES -# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libspirv-cross-glsl.a -# ) -# set(spirv-cross_libs_name spirv-cross-core spirv-cross-glsl spirv-cross-msl) - -############################# TBB ############################# - -# add_library(tbb STATIC IMPORTED GLOBAL) -# set_target_properties(tbb PROPERTIES -# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libtbb_static.a -# ) -# add_library(tbbmalloc STATIC IMPORTED GLOBAL) -# set_target_properties(tbbmalloc PROPERTIES -# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libtbbmalloc_static.a -# ) -# add_library(tbbmalloc_proxy STATIC IMPORTED GLOBAL) -# set_target_properties(tbbmalloc_proxy PROPERTIES -# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libtbbmalloc_proxy_static.a -# ) -# set(tbb_libs_name tbb tbbmalloc tbbmalloc_proxy) - -#if(USE_PHYSICS_PHYSX) -# set(PhysXSDK PhysX PhysXCommon PhysXFoundation PhysXExtensions PhysXCooking PhysXCharacterKinematic PhysXVehicle PhysXPvdSDK) -# foreach(PX IN LISTS PhysXSDK) -# add_library(${PX} STATIC IMPORTED GLOBAL) -# set_target_properties(${PX} PROPERTIES -# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/PhysX/lib${PX}_static_64.a -# ) -# endforeach() -#else() -# set(PhysXSDK) -#endif() - -list(APPEND CC_EXTERNAL_LIBS - #freetype - #jpeg - #png - #webp - #curl - #crypto - #ssl - #${tbb_libs_name} - #${PhysXSDK} -) - -set(ZLIB z) -if(NOT USE_MODULES) - list(APPEND CC_EXTERNAL_LIBS ${ZLIB}) -endif() - - -list(APPEND CC_EXTERNAL_INCLUDES - ${CMAKE_CURRENT_LIST_DIR}/include -) + +add_library(z STATIC IMPORTED GLOBAL) +set_target_properties(z PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libz.a + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/zlib +) + +############################# SPIRV-Cross ############################# +# add_library(spirv-cross-core STATIC IMPORTED GLOBAL) +# set_target_properties(spirv-cross-core PROPERTIES +# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libspirv-cross-core.a +# INTERFACE_INCLUDE_DIRECTORIES "${SPIRV_INCLUDE_DIRS}" +# ) +# add_library(spirv-cross-msl STATIC IMPORTED GLOBAL) +# set_target_properties(spirv-cross-msl PROPERTIES +# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libspirv-cross-msl.a +# ) +# add_library(spirv-cross-glsl STATIC IMPORTED GLOBAL) +# set_target_properties(spirv-cross-glsl PROPERTIES +# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libspirv-cross-glsl.a +# ) +# set(spirv-cross_libs_name spirv-cross-core spirv-cross-glsl spirv-cross-msl) + +############################# TBB ############################# + +# add_library(tbb STATIC IMPORTED GLOBAL) +# set_target_properties(tbb PROPERTIES +# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libtbb_static.a +# ) +# add_library(tbbmalloc STATIC IMPORTED GLOBAL) +# set_target_properties(tbbmalloc PROPERTIES +# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libtbbmalloc_static.a +# ) +# add_library(tbbmalloc_proxy STATIC IMPORTED GLOBAL) +# set_target_properties(tbbmalloc_proxy PROPERTIES +# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libtbbmalloc_proxy_static.a +# ) +# set(tbb_libs_name tbb tbbmalloc tbbmalloc_proxy) + +#if(USE_PHYSICS_PHYSX) +# set(PhysXSDK PhysX PhysXCommon PhysXFoundation PhysXExtensions PhysXCooking PhysXCharacterKinematic PhysXVehicle PhysXPvdSDK) +# foreach(PX IN LISTS PhysXSDK) +# add_library(${PX} STATIC IMPORTED GLOBAL) +# set_target_properties(${PX} PROPERTIES +# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/PhysX/lib${PX}_static_64.a +# ) +# endforeach() +#else() +# set(PhysXSDK) +#endif() + +list(APPEND CC_EXTERNAL_LIBS + #freetype + #jpeg + #png + #webp + #curl + #crypto + #ssl + #${tbb_libs_name} + #${PhysXSDK} +) + +set(ZLIB z) +if(NOT USE_MODULES) + list(APPEND CC_EXTERNAL_LIBS ${ZLIB}) +endif() + + +list(APPEND CC_EXTERNAL_INCLUDES + ${CMAKE_CURRENT_LIST_DIR}/include +) diff --git a/ios-m1-simulator/CMakeLists.txt b/ios-m1-simulator/CMakeLists.txt index f56b4bde..e2d474ec 100644 --- a/ios-m1-simulator/CMakeLists.txt +++ b/ios-m1-simulator/CMakeLists.txt @@ -1,212 +1,212 @@ - -add_library(crypto STATIC IMPORTED GLOBAL) -set_target_properties(crypto PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcrypto.a -) - -add_library(freetype STATIC IMPORTED GLOBAL) -set_target_properties(freetype PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libfreetype.a -) - -add_library(jpeg STATIC IMPORTED GLOBAL) -set_target_properties(jpeg PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libjpeg.a -) - -add_library(png STATIC IMPORTED GLOBAL) -set_target_properties(png PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libpng.a -) - -add_library(ssl STATIC IMPORTED GLOBAL) -set_target_properties(ssl PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libssl.a -) - -add_library(uv STATIC IMPORTED GLOBAL) -set_target_properties(uv PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libuv_a.a - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/uv -) - -add_library(webp STATIC IMPORTED GLOBAL) -set_target_properties(webp PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libwebp.a -) - -add_library(v8_monolith STATIC IMPORTED GLOBAL) -set(V8_COMPILE_FLAGS - V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64 - ENABLE_MINOR_MC - ENABLE_HANDLE_ZAPPING - V8_ATOMIC_OBJECT_FIELD_WRITES - V8_ATOMIC_MARKING_STATE - V8_ENABLE_LAZY_SOURCE_POSITIONS - V8_SHARED_RO_HEAP - V8_WIN64_UNWINDING_INFO - V8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH - V8_SNAPSHOT_COMPRESSION - V8_ENABLE_SYSTEM_INSTRUMENTATION - V8_ENABLE_WEBASSEMBLY - V8_DEPRECATION_WARNINGS - V8_IMMINENT_DEPRECATION_WARNINGS - CPPGC_CAGED_HEAP - V8_TARGET_ARCH_ARM64 - V8_HAVE_TARGET_OS - V8_TARGET_OS_IOS - DISABLE_UNTRUSTED_CODE_MITIGATIONS -) -set_target_properties(v8_monolith PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libv8_monolith.a - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/v8 - # INTERFACE_COMPILE_DEFINITIONS ${V8_COMPILE_FLAGS} -) -set_property(TARGET v8_monolith APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS ${V8_COMPILE_FLAGS}) - - -# add_library(inspector STATIC IMPORTED GLOBAL) -# set_target_properties(inspector PROPERTIES -# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libinspector.a -# ) - -add_library(js_static STATIC IMPORTED GLOBAL) -set_target_properties(js_static PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libjs_static.a - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/spidermonkey -) - -add_library(mozglue STATIC IMPORTED GLOBAL) -set_target_properties(mozglue PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libmozglue.a -) - -set(se_libs_name) - -if(USE_SE_V8) - list(APPEND se_libs_name - v8_monolith - uv - ) -# if(USE_V8_DEBUGGER) -# list(APPEND se_libs_name) -# endif() -endif() - -if(USE_SE_JSC) - find_library(JAVASCRIPT_CORE_LIBRARY JavaScriptCore REQUIRED) - set(se_libs_name ${JAVASCRIPT_CORE_LIBRARY}) -endif() - -############################# glslang ############################# - -add_library(GenericCodeGen STATIC IMPORTED GLOBAL) -set_target_properties(GenericCodeGen PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libGenericCodeGen.a -) - -add_library(glslang STATIC IMPORTED GLOBAL) -set_target_properties(glslang PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libglslang.a -) - -add_library(glslang-default-resource-limits STATIC IMPORTED GLOBAL) -set_target_properties(glslang-default-resource-limits PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libglslang-default-resource-limits.a -) - -add_library(MachineIndependent STATIC IMPORTED GLOBAL) -set_target_properties(MachineIndependent PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libMachineIndependent.a -) - -add_library(OGLCompiler STATIC IMPORTED GLOBAL) -set_target_properties(OGLCompiler PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libOGLCompiler.a -) - -add_library(OSDependent STATIC IMPORTED GLOBAL) -set_target_properties(OSDependent PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libOSDependent.a -) - -add_library(SPIRV STATIC IMPORTED GLOBAL) -set_target_properties(SPIRV PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV.a -) - -add_library(SPIRV-Tools STATIC IMPORTED GLOBAL) -set_target_properties(SPIRV-Tools PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV-Tools.a -) - -add_library(SPIRV-Tools-opt STATIC IMPORTED GLOBAL) -set_target_properties(SPIRV-Tools-opt PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV-Tools-opt.a -) - -add_library(SPVRemapper STATIC IMPORTED GLOBAL) -set_target_properties(SPVRemapper PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPVRemapper.a -) - -set(glslang_libs_name glslang glslang-default-resource-limits MachineIndependent OGLCompiler OSDependent SPIRV SPIRV-Tools-opt SPIRV-Tools SPVRemapper GenericCodeGen) - -############################# SPIRV-Cross ############################# - -add_library(spirv-cross-core STATIC IMPORTED GLOBAL) -set_target_properties(spirv-cross-core PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/spirv-cross/libspirv-cross-core.a -) -add_library(spirv-cross-msl STATIC IMPORTED GLOBAL) -set_target_properties(spirv-cross-msl PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/spirv-cross/libspirv-cross-msl.a -) -add_library(spirv-cross-glsl STATIC IMPORTED GLOBAL) -set_target_properties(spirv-cross-glsl PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/spirv-cross/libspirv-cross-glsl.a -) -set(spirv-cross_libs_name spirv-cross-core spirv-cross-glsl spirv-cross-msl) - -############################# TBB ############################# - -add_library(tbb STATIC IMPORTED GLOBAL) -set_target_properties(tbb PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libtbb_static.a -) -set(tbb_libs_name tbb) - -## PHYSICS_PHYSX do not support simulator -# if(USE_PHYSICS_PHYSX) -# set(PhysXSDK PhysX PhysXCommon PhysXFoundation PhysXExtensions PhysXCooking PhysXCharacterKinematic PhysXVehicle PhysXPvdSDK) -# foreach(PX IN LISTS PhysXSDK) -# add_library(${PX} STATIC IMPORTED GLOBAL) -# set_target_properties(${PX} PROPERTIES -# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/PhysX/lib${PX}_static_64.a -# ) -# endforeach() -# else() -# set(PhysXSDK) -# endif() - -list(APPEND CC_EXTERNAL_INCLUDES - ${CMAKE_CURRENT_LIST_DIR}/include -) - -list(APPEND CC_EXTERNAL_LIBS - freetype - jpeg - png - webp - crypto - ssl - ${glslang_libs_name} - ${spirv-cross_libs_name} - ${tbb_libs_name} - ${PhysXSDK} -) - -set(ZLIB z) -if(NOT USE_MODULES) - list(APPEND CC_EXTERNAL_LIBS ${se_libs_name}) -endif() + +add_library(crypto STATIC IMPORTED GLOBAL) +set_target_properties(crypto PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcrypto.a +) + +add_library(freetype STATIC IMPORTED GLOBAL) +set_target_properties(freetype PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libfreetype.a +) + +add_library(jpeg STATIC IMPORTED GLOBAL) +set_target_properties(jpeg PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libjpeg.a +) + +add_library(png STATIC IMPORTED GLOBAL) +set_target_properties(png PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libpng.a +) + +add_library(ssl STATIC IMPORTED GLOBAL) +set_target_properties(ssl PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libssl.a +) + +add_library(uv STATIC IMPORTED GLOBAL) +set_target_properties(uv PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libuv_a.a + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/uv +) + +add_library(webp STATIC IMPORTED GLOBAL) +set_target_properties(webp PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libwebp.a +) + +add_library(v8_monolith STATIC IMPORTED GLOBAL) +set(V8_COMPILE_FLAGS + V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64 + ENABLE_MINOR_MC + ENABLE_HANDLE_ZAPPING + V8_ATOMIC_OBJECT_FIELD_WRITES + V8_ATOMIC_MARKING_STATE + V8_ENABLE_LAZY_SOURCE_POSITIONS + V8_SHARED_RO_HEAP + V8_WIN64_UNWINDING_INFO + V8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH + V8_SNAPSHOT_COMPRESSION + V8_ENABLE_SYSTEM_INSTRUMENTATION + V8_ENABLE_WEBASSEMBLY + V8_DEPRECATION_WARNINGS + V8_IMMINENT_DEPRECATION_WARNINGS + CPPGC_CAGED_HEAP + V8_TARGET_ARCH_ARM64 + V8_HAVE_TARGET_OS + V8_TARGET_OS_IOS + DISABLE_UNTRUSTED_CODE_MITIGATIONS +) +set_target_properties(v8_monolith PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libv8_monolith.a + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/v8 + # INTERFACE_COMPILE_DEFINITIONS ${V8_COMPILE_FLAGS} +) +set_property(TARGET v8_monolith APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS ${V8_COMPILE_FLAGS}) + + +# add_library(inspector STATIC IMPORTED GLOBAL) +# set_target_properties(inspector PROPERTIES +# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libinspector.a +# ) + +add_library(js_static STATIC IMPORTED GLOBAL) +set_target_properties(js_static PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libjs_static.a + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/spidermonkey +) + +add_library(mozglue STATIC IMPORTED GLOBAL) +set_target_properties(mozglue PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libmozglue.a +) + +set(se_libs_name) + +if(USE_SE_V8 OR USE_NODE_NAPI) + list(APPEND se_libs_name + v8_monolith + uv + ) +# if(USE_V8_DEBUGGER) +# list(APPEND se_libs_name) +# endif() +endif() + +if(USE_SE_JSC) + find_library(JAVASCRIPT_CORE_LIBRARY JavaScriptCore REQUIRED) + set(se_libs_name ${JAVASCRIPT_CORE_LIBRARY}) +endif() + +############################# glslang ############################# + +add_library(GenericCodeGen STATIC IMPORTED GLOBAL) +set_target_properties(GenericCodeGen PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libGenericCodeGen.a +) + +add_library(glslang STATIC IMPORTED GLOBAL) +set_target_properties(glslang PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libglslang.a +) + +add_library(glslang-default-resource-limits STATIC IMPORTED GLOBAL) +set_target_properties(glslang-default-resource-limits PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libglslang-default-resource-limits.a +) + +add_library(MachineIndependent STATIC IMPORTED GLOBAL) +set_target_properties(MachineIndependent PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libMachineIndependent.a +) + +add_library(OGLCompiler STATIC IMPORTED GLOBAL) +set_target_properties(OGLCompiler PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libOGLCompiler.a +) + +add_library(OSDependent STATIC IMPORTED GLOBAL) +set_target_properties(OSDependent PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libOSDependent.a +) + +add_library(SPIRV STATIC IMPORTED GLOBAL) +set_target_properties(SPIRV PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV.a +) + +add_library(SPIRV-Tools STATIC IMPORTED GLOBAL) +set_target_properties(SPIRV-Tools PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV-Tools.a +) + +add_library(SPIRV-Tools-opt STATIC IMPORTED GLOBAL) +set_target_properties(SPIRV-Tools-opt PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV-Tools-opt.a +) + +add_library(SPVRemapper STATIC IMPORTED GLOBAL) +set_target_properties(SPVRemapper PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPVRemapper.a +) + +set(glslang_libs_name glslang glslang-default-resource-limits MachineIndependent OGLCompiler OSDependent SPIRV SPIRV-Tools-opt SPIRV-Tools SPVRemapper GenericCodeGen) + +############################# SPIRV-Cross ############################# + +add_library(spirv-cross-core STATIC IMPORTED GLOBAL) +set_target_properties(spirv-cross-core PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/spirv-cross/libspirv-cross-core.a +) +add_library(spirv-cross-msl STATIC IMPORTED GLOBAL) +set_target_properties(spirv-cross-msl PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/spirv-cross/libspirv-cross-msl.a +) +add_library(spirv-cross-glsl STATIC IMPORTED GLOBAL) +set_target_properties(spirv-cross-glsl PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/spirv-cross/libspirv-cross-glsl.a +) +set(spirv-cross_libs_name spirv-cross-core spirv-cross-glsl spirv-cross-msl) + +############################# TBB ############################# + +add_library(tbb STATIC IMPORTED GLOBAL) +set_target_properties(tbb PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libtbb_static.a +) +set(tbb_libs_name tbb) + +## PHYSICS_PHYSX do not support simulator +# if(USE_PHYSICS_PHYSX) +# set(PhysXSDK PhysX PhysXCommon PhysXFoundation PhysXExtensions PhysXCooking PhysXCharacterKinematic PhysXVehicle PhysXPvdSDK) +# foreach(PX IN LISTS PhysXSDK) +# add_library(${PX} STATIC IMPORTED GLOBAL) +# set_target_properties(${PX} PROPERTIES +# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/PhysX/lib${PX}_static_64.a +# ) +# endforeach() +# else() +# set(PhysXSDK) +# endif() + +list(APPEND CC_EXTERNAL_INCLUDES + ${CMAKE_CURRENT_LIST_DIR}/include +) + +list(APPEND CC_EXTERNAL_LIBS + freetype + jpeg + png + webp + crypto + ssl + ${glslang_libs_name} + ${spirv-cross_libs_name} + ${tbb_libs_name} + ${PhysXSDK} +) + +set(ZLIB z) +if(NOT USE_MODULES) + list(APPEND CC_EXTERNAL_LIBS ${se_libs_name}) +endif() diff --git a/ios/CMakeLists.txt b/ios/CMakeLists.txt index e7bccfba..a2e514d4 100644 --- a/ios/CMakeLists.txt +++ b/ios/CMakeLists.txt @@ -1,208 +1,208 @@ - -add_library(crypto STATIC IMPORTED GLOBAL) -set_target_properties(crypto PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcrypto.a -) - -add_library(freetype STATIC IMPORTED GLOBAL) -set_target_properties(freetype PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libfreetype.a -) - -add_library(jpeg STATIC IMPORTED GLOBAL) -set_target_properties(jpeg PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libjpeg.a -) - -add_library(png STATIC IMPORTED GLOBAL) -set_target_properties(png PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libpng.a -) - -add_library(ssl STATIC IMPORTED GLOBAL) -set_target_properties(ssl PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libssl.a -) - -add_library(uv STATIC IMPORTED GLOBAL) -set_target_properties(uv PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libuv_a.a - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/uv -) - -add_library(webp STATIC IMPORTED GLOBAL) -set_target_properties(webp PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libwebp.a -) - -add_library(v8_monolith STATIC IMPORTED GLOBAL) -set(V8_COMPILE_FLAGS - V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64 - ENABLE_MINOR_MC - ENABLE_HANDLE_ZAPPING - V8_ATOMIC_OBJECT_FIELD_WRITES - V8_ATOMIC_MARKING_STATE - V8_ENABLE_LAZY_SOURCE_POSITIONS - V8_SHARED_RO_HEAP - V8_WIN64_UNWINDING_INFO - V8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH - V8_SNAPSHOT_COMPRESSION - V8_ENABLE_SYSTEM_INSTRUMENTATION - V8_ENABLE_WEBASSEMBLY - V8_DEPRECATION_WARNINGS - V8_IMMINENT_DEPRECATION_WARNINGS - CPPGC_CAGED_HEAP - V8_TARGET_ARCH_ARM64 - V8_HAVE_TARGET_OS - V8_TARGET_OS_IOS - DISABLE_UNTRUSTED_CODE_MITIGATIONS -) -set_target_properties(v8_monolith PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libv8_monolith.a - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/v8 - # INTERFACE_COMPILE_DEFINITIONS ${V8_COMPILE_FLAGS} -) -set_property(TARGET v8_monolith APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS ${V8_COMPILE_FLAGS}) - - -# add_library(inspector STATIC IMPORTED GLOBAL) -# set_target_properties(inspector PROPERTIES -# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libinspector.a -# ) - -add_library(js_static STATIC IMPORTED GLOBAL) -set_target_properties(js_static PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libjs_static.a - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/spidermonkey -) - -add_library(mozglue STATIC IMPORTED GLOBAL) -set_target_properties(mozglue PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libmozglue.a -) - -set(se_libs_name) - -if(USE_SE_V8) - list(APPEND se_libs_name - v8_monolith - uv - ) -# if(USE_V8_DEBUGGER) -# list(APPEND se_libs_name) -# endif() -endif() - -if(USE_SE_JSC) - find_library(JAVASCRIPT_CORE_LIBRARY JavaScriptCore REQUIRED) - set(se_libs_name ${JAVASCRIPT_CORE_LIBRARY}) -endif() - -############################# glslang ############################# - -add_library(GenericCodeGen STATIC IMPORTED GLOBAL) -set_target_properties(GenericCodeGen PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libGenericCodeGen.a -) - -add_library(glslang STATIC IMPORTED GLOBAL) -set_target_properties(glslang PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libglslang.a -) - -add_library(glslang-default-resource-limits STATIC IMPORTED GLOBAL) -set_target_properties(glslang-default-resource-limits PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libglslang-default-resource-limits.a -) - -add_library(MachineIndependent STATIC IMPORTED GLOBAL) -set_target_properties(MachineIndependent PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libMachineIndependent.a -) - -add_library(OGLCompiler STATIC IMPORTED GLOBAL) -set_target_properties(OGLCompiler PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libOGLCompiler.a -) - -add_library(OSDependent STATIC IMPORTED GLOBAL) -set_target_properties(OSDependent PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libOSDependent.a -) - -add_library(SPIRV STATIC IMPORTED GLOBAL) -set_target_properties(SPIRV PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV.a -) - -add_library(SPIRV-Tools STATIC IMPORTED GLOBAL) -set_target_properties(SPIRV-Tools PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV-Tools.a -) - -add_library(SPIRV-Tools-opt STATIC IMPORTED GLOBAL) -set_target_properties(SPIRV-Tools-opt PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV-Tools-opt.a -) - - - -set(glslang_libs_name glslang glslang-default-resource-limits MachineIndependent OGLCompiler OSDependent SPIRV SPIRV-Tools-opt SPIRV-Tools GenericCodeGen) - -############################# SPIRV-Cross ############################# - -add_library(spirv-cross-core STATIC IMPORTED GLOBAL) -set_target_properties(spirv-cross-core PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/spirv-cross/libspirv-cross-core.a -) -add_library(spirv-cross-msl STATIC IMPORTED GLOBAL) -set_target_properties(spirv-cross-msl PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/spirv-cross/libspirv-cross-msl.a -) -add_library(spirv-cross-glsl STATIC IMPORTED GLOBAL) -set_target_properties(spirv-cross-glsl PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/spirv-cross/libspirv-cross-glsl.a -) -set(spirv-cross_libs_name spirv-cross-core spirv-cross-glsl spirv-cross-msl) - -############################# TBB ############################# - -add_library(tbb STATIC IMPORTED GLOBAL) -set_target_properties(tbb PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libtbb_static.a -) -set(tbb_libs_name tbb) - -if(USE_PHYSICS_PHYSX) - set(PhysXSDK PhysX PhysXCommon PhysXFoundation PhysXExtensions PhysXCooking PhysXCharacterKinematic PhysXVehicle PhysXPvdSDK) - foreach(PX IN LISTS PhysXSDK) - add_library(${PX} STATIC IMPORTED GLOBAL) - set_target_properties(${PX} PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/PhysX/lib${PX}_static_64.a - ) - endforeach() -else() - set(PhysXSDK) -endif() - -list(APPEND CC_EXTERNAL_INCLUDES - ${CMAKE_CURRENT_LIST_DIR}/include -) - -list(APPEND CC_EXTERNAL_LIBS - freetype - jpeg - png - webp - crypto - ssl - ${glslang_libs_name} - ${spirv-cross_libs_name} - ${tbb_libs_name} - ${PhysXSDK} -) - -set(ZLIB z) -if(NOT USE_MODULES) - list(APPEND CC_EXTERNAL_LIBS ${se_libs_name}) -endif() + +add_library(crypto STATIC IMPORTED GLOBAL) +set_target_properties(crypto PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcrypto.a +) + +add_library(freetype STATIC IMPORTED GLOBAL) +set_target_properties(freetype PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libfreetype.a +) + +add_library(jpeg STATIC IMPORTED GLOBAL) +set_target_properties(jpeg PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libjpeg.a +) + +add_library(png STATIC IMPORTED GLOBAL) +set_target_properties(png PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libpng.a +) + +add_library(ssl STATIC IMPORTED GLOBAL) +set_target_properties(ssl PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libssl.a +) + +add_library(uv STATIC IMPORTED GLOBAL) +set_target_properties(uv PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libuv_a.a + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/uv +) + +add_library(webp STATIC IMPORTED GLOBAL) +set_target_properties(webp PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libwebp.a +) + +add_library(v8_monolith STATIC IMPORTED GLOBAL) +set(V8_COMPILE_FLAGS + V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64 + ENABLE_MINOR_MC + ENABLE_HANDLE_ZAPPING + V8_ATOMIC_OBJECT_FIELD_WRITES + V8_ATOMIC_MARKING_STATE + V8_ENABLE_LAZY_SOURCE_POSITIONS + V8_SHARED_RO_HEAP + V8_WIN64_UNWINDING_INFO + V8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH + V8_SNAPSHOT_COMPRESSION + V8_ENABLE_SYSTEM_INSTRUMENTATION + V8_ENABLE_WEBASSEMBLY + V8_DEPRECATION_WARNINGS + V8_IMMINENT_DEPRECATION_WARNINGS + CPPGC_CAGED_HEAP + V8_TARGET_ARCH_ARM64 + V8_HAVE_TARGET_OS + V8_TARGET_OS_IOS + DISABLE_UNTRUSTED_CODE_MITIGATIONS +) +set_target_properties(v8_monolith PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libv8_monolith.a + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/v8 + # INTERFACE_COMPILE_DEFINITIONS ${V8_COMPILE_FLAGS} +) +set_property(TARGET v8_monolith APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS ${V8_COMPILE_FLAGS}) + + +# add_library(inspector STATIC IMPORTED GLOBAL) +# set_target_properties(inspector PROPERTIES +# IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libinspector.a +# ) + +add_library(js_static STATIC IMPORTED GLOBAL) +set_target_properties(js_static PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libjs_static.a + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/spidermonkey +) + +add_library(mozglue STATIC IMPORTED GLOBAL) +set_target_properties(mozglue PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libmozglue.a +) + +set(se_libs_name) + +if(USE_SE_V8 OR USE_NODE_NAPI) + list(APPEND se_libs_name + v8_monolith + uv + ) +# if(USE_V8_DEBUGGER) +# list(APPEND se_libs_name) +# endif() +endif() + +if(USE_SE_JSC) + find_library(JAVASCRIPT_CORE_LIBRARY JavaScriptCore REQUIRED) + set(se_libs_name ${JAVASCRIPT_CORE_LIBRARY}) +endif() + +############################# glslang ############################# + +add_library(GenericCodeGen STATIC IMPORTED GLOBAL) +set_target_properties(GenericCodeGen PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libGenericCodeGen.a +) + +add_library(glslang STATIC IMPORTED GLOBAL) +set_target_properties(glslang PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libglslang.a +) + +add_library(glslang-default-resource-limits STATIC IMPORTED GLOBAL) +set_target_properties(glslang-default-resource-limits PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libglslang-default-resource-limits.a +) + +add_library(MachineIndependent STATIC IMPORTED GLOBAL) +set_target_properties(MachineIndependent PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libMachineIndependent.a +) + +add_library(OGLCompiler STATIC IMPORTED GLOBAL) +set_target_properties(OGLCompiler PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libOGLCompiler.a +) + +add_library(OSDependent STATIC IMPORTED GLOBAL) +set_target_properties(OSDependent PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libOSDependent.a +) + +add_library(SPIRV STATIC IMPORTED GLOBAL) +set_target_properties(SPIRV PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV.a +) + +add_library(SPIRV-Tools STATIC IMPORTED GLOBAL) +set_target_properties(SPIRV-Tools PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV-Tools.a +) + +add_library(SPIRV-Tools-opt STATIC IMPORTED GLOBAL) +set_target_properties(SPIRV-Tools-opt PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV-Tools-opt.a +) + + + +set(glslang_libs_name glslang glslang-default-resource-limits MachineIndependent OGLCompiler OSDependent SPIRV SPIRV-Tools-opt SPIRV-Tools GenericCodeGen) + +############################# SPIRV-Cross ############################# + +add_library(spirv-cross-core STATIC IMPORTED GLOBAL) +set_target_properties(spirv-cross-core PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/spirv-cross/libspirv-cross-core.a +) +add_library(spirv-cross-msl STATIC IMPORTED GLOBAL) +set_target_properties(spirv-cross-msl PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/spirv-cross/libspirv-cross-msl.a +) +add_library(spirv-cross-glsl STATIC IMPORTED GLOBAL) +set_target_properties(spirv-cross-glsl PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/spirv-cross/libspirv-cross-glsl.a +) +set(spirv-cross_libs_name spirv-cross-core spirv-cross-glsl spirv-cross-msl) + +############################# TBB ############################# + +add_library(tbb STATIC IMPORTED GLOBAL) +set_target_properties(tbb PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libtbb_static.a +) +set(tbb_libs_name tbb) + +if(USE_PHYSICS_PHYSX) + set(PhysXSDK PhysX PhysXCommon PhysXFoundation PhysXExtensions PhysXCooking PhysXCharacterKinematic PhysXVehicle PhysXPvdSDK) + foreach(PX IN LISTS PhysXSDK) + add_library(${PX} STATIC IMPORTED GLOBAL) + set_target_properties(${PX} PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/PhysX/lib${PX}_static_64.a + ) + endforeach() +else() + set(PhysXSDK) +endif() + +list(APPEND CC_EXTERNAL_INCLUDES + ${CMAKE_CURRENT_LIST_DIR}/include +) + +list(APPEND CC_EXTERNAL_LIBS + freetype + jpeg + png + webp + crypto + ssl + ${glslang_libs_name} + ${spirv-cross_libs_name} + ${tbb_libs_name} + ${PhysXSDK} +) + +set(ZLIB z) +if(NOT USE_MODULES) + list(APPEND CC_EXTERNAL_LIBS ${se_libs_name}) +endif() diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 5961aa6c..df53c74f 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -1,168 +1,168 @@ -set(linux_lib_dir ${platform_spec_path}/lib) -MESSAGE(STATUS "${platform_spec_path}") -add_library(uv STATIC IMPORTED GLOBAL) -set_target_properties(uv PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/libuv/libuv_a.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/libuv -) - -add_library(mpg123 STATIC IMPORTED GLOBAL) -set_target_properties(mpg123 PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/mpg123/libmpg123.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/mpg123 -) - -add_library(ogg STATIC IMPORTED GLOBAL) -set_target_properties(ogg PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/ogg/libogg.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/ogg -) - -add_library(vorbisfile STATIC IMPORTED GLOBAL) -set_target_properties(vorbisfile PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/vorbis/libvorbisfile.a -) - -add_library(vorbis STATIC IMPORTED GLOBAL) -set_target_properties(vorbis PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/vorbis/libvorbis.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/vorbis -) - -add_library(libz STATIC IMPORTED GLOBAL) -set_target_properties(libz PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/libz/libz.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/libz -) - -add_library(sqlite3 STATIC IMPORTED GLOBAL) -set_target_properties(sqlite3 PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/sqlite/libsqlite3.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/sqlite -) - -add_library(v8 STATIC IMPORTED GLOBAL) -set_target_properties(v8 PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/v8/libv8_monolith.a -) - -add_library(openal STATIC IMPORTED GLOBAL) -set_target_properties(openal PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/openal-soft/libopenal.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/openal-soft -) - -add_library(jpeg STATIC IMPORTED GLOBAL) -set_target_properties(jpeg PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/jpeg/libjpeg.a -) - -add_library(png STATIC IMPORTED GLOBAL) -set_target_properties(png PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/libpng/libpng16.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/libpng -) - -add_library(ssl STATIC IMPORTED GLOBAL) -set_target_properties(ssl PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/openssl/libssl.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/openssl -) -add_library(crypto STATIC IMPORTED GLOBAL) -set_target_properties(crypto PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/openssl/libcrypto.a -) -set(optional_libs_name ssl crypto) - -add_library(websockets STATIC IMPORTED GLOBAL) -set_target_properties(websockets PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/libwebsockets/libwebsockets.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/libwebsockets -) - -add_library(curl STATIC IMPORTED GLOBAL) -set_target_properties(curl PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/curl/libcurl.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/curl -) - -add_library(webp STATIC IMPORTED GLOBAL) -set_target_properties(webp PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/libwebp/libwebp.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/libwebp -) - -add_library(tbb STATIC IMPORTED GLOBAL) -set_target_properties(tbb PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/tbb/libtbb_static.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/tbb -) -set(optional_libs_name ${optional_libs_name} tbb) - -add_library(sdl2 STATIC IMPORTED GLOBAL) -set_target_properties(sdl2 PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/sdl2/libSDL2.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/sdl2 -) - -#glslang -add_library(libGenericCodeGen STATIC IMPORTED GLOBAL) -set_target_properties(libGenericCodeGen PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/glslang/libGenericCodeGen.a -) -add_library(libglslang STATIC IMPORTED GLOBAL) -set_target_properties(libglslang PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/glslang/libglslang.a -) -add_library(libglslang-default-resource-limits STATIC IMPORTED GLOBAL) -set_target_properties(libglslang-default-resource-limits PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/glslang/libglslang-default-resource-limits.a -) -add_library(libSPIRV STATIC IMPORTED GLOBAL) -set_target_properties(libSPIRV PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/glslang/libSPIRV.a -) -add_library(libMachineIndependent STATIC IMPORTED GLOBAL) -set_target_properties(libMachineIndependent PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/glslang/libMachineIndependent.a -) -add_library(libOGLCompiler STATIC IMPORTED GLOBAL) -set_target_properties(libOGLCompiler PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/glslang/libOGLCompiler.a -) -add_library(libOSDependent STATIC IMPORTED GLOBAL) -set_target_properties(libOSDependent PROPERTIES - IMPORTED_LOCATION ${linux_lib_dir}/glslang/libOSDependent.a -) - -set(glslang_libs_name libMachineIndependent libGenericCodeGen libglslang libglslang-default-resource-limits libSPIRV libOGLCompiler libOSDependent) - - -list(APPEND CC_EXTERNAL_INCLUDES - ${platform_spec_path}/include - ${platform_spec_path}/include/v8 - ${platform_spec_path}/include/uv -) - -list(APPEND CC_EXTERNAL_LIBS - uv - vorbisfile - vorbis - ogg - libz - sqlite3 - v8 - openal - mpg123 - jpeg - png - websockets - webp - curl - ${optional_libs_name} - ${glslang_libs_name} -) - -if(NOT USE_SERVER_MODE) - list(APPEND CC_EXTERNAL_LIBS sdl2) +set(linux_lib_dir ${platform_spec_path}/lib) +MESSAGE(STATUS "${platform_spec_path}") +add_library(uv STATIC IMPORTED GLOBAL) +set_target_properties(uv PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/libuv/libuv_a.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/libuv +) + +add_library(mpg123 STATIC IMPORTED GLOBAL) +set_target_properties(mpg123 PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/mpg123/libmpg123.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/mpg123 +) + +add_library(ogg STATIC IMPORTED GLOBAL) +set_target_properties(ogg PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/ogg/libogg.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/ogg +) + +add_library(vorbisfile STATIC IMPORTED GLOBAL) +set_target_properties(vorbisfile PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/vorbis/libvorbisfile.a +) + +add_library(vorbis STATIC IMPORTED GLOBAL) +set_target_properties(vorbis PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/vorbis/libvorbis.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/vorbis +) + +add_library(libz STATIC IMPORTED GLOBAL) +set_target_properties(libz PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/libz/libz.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/libz +) + +add_library(sqlite3 STATIC IMPORTED GLOBAL) +set_target_properties(sqlite3 PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/sqlite/libsqlite3.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/sqlite +) + +add_library(v8 STATIC IMPORTED GLOBAL) +set_target_properties(v8 PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/v8/libv8_monolith.a +) + +add_library(openal STATIC IMPORTED GLOBAL) +set_target_properties(openal PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/openal-soft/libopenal.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/openal-soft +) + +add_library(jpeg STATIC IMPORTED GLOBAL) +set_target_properties(jpeg PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/jpeg/libjpeg.a +) + +add_library(png STATIC IMPORTED GLOBAL) +set_target_properties(png PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/libpng/libpng16.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/libpng +) + +add_library(ssl STATIC IMPORTED GLOBAL) +set_target_properties(ssl PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/openssl/libssl.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/openssl +) +add_library(crypto STATIC IMPORTED GLOBAL) +set_target_properties(crypto PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/openssl/libcrypto.a +) +set(optional_libs_name ssl crypto) + +add_library(websockets STATIC IMPORTED GLOBAL) +set_target_properties(websockets PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/libwebsockets/libwebsockets.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/libwebsockets +) + +add_library(curl STATIC IMPORTED GLOBAL) +set_target_properties(curl PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/curl/libcurl.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/curl +) + +add_library(webp STATIC IMPORTED GLOBAL) +set_target_properties(webp PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/libwebp/libwebp.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/libwebp +) + +add_library(tbb STATIC IMPORTED GLOBAL) +set_target_properties(tbb PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/tbb/libtbb_static.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/tbb +) +set(optional_libs_name ${optional_libs_name} tbb) + +add_library(sdl2 STATIC IMPORTED GLOBAL) +set_target_properties(sdl2 PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/sdl2/libSDL2.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/sdl2 +) + +#glslang +add_library(libGenericCodeGen STATIC IMPORTED GLOBAL) +set_target_properties(libGenericCodeGen PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/glslang/libGenericCodeGen.a +) +add_library(libglslang STATIC IMPORTED GLOBAL) +set_target_properties(libglslang PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/glslang/libglslang.a +) +add_library(libglslang-default-resource-limits STATIC IMPORTED GLOBAL) +set_target_properties(libglslang-default-resource-limits PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/glslang/libglslang-default-resource-limits.a +) +add_library(libSPIRV STATIC IMPORTED GLOBAL) +set_target_properties(libSPIRV PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/glslang/libSPIRV.a +) +add_library(libMachineIndependent STATIC IMPORTED GLOBAL) +set_target_properties(libMachineIndependent PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/glslang/libMachineIndependent.a +) +add_library(libOGLCompiler STATIC IMPORTED GLOBAL) +set_target_properties(libOGLCompiler PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/glslang/libOGLCompiler.a +) +add_library(libOSDependent STATIC IMPORTED GLOBAL) +set_target_properties(libOSDependent PROPERTIES + IMPORTED_LOCATION ${linux_lib_dir}/glslang/libOSDependent.a +) + +set(glslang_libs_name libMachineIndependent libGenericCodeGen libglslang libglslang-default-resource-limits libSPIRV libOGLCompiler libOSDependent) + + +list(APPEND CC_EXTERNAL_INCLUDES + ${platform_spec_path}/include + ${platform_spec_path}/include/v8 + ${platform_spec_path}/include/uv +) + +list(APPEND CC_EXTERNAL_LIBS + uv + vorbisfile + vorbis + ogg + libz + sqlite3 + v8 + openal + mpg123 + jpeg + png + websockets + webp + curl + ${optional_libs_name} + ${glslang_libs_name} +) + +if(NOT USE_SERVER_MODE) + list(APPEND CC_EXTERNAL_LIBS sdl2) endif() \ No newline at end of file diff --git a/mac/CMakeLists.txt b/mac/CMakeLists.txt index 29b34da0..20bc01b1 100644 --- a/mac/CMakeLists.txt +++ b/mac/CMakeLists.txt @@ -1,209 +1,209 @@ - -add_library(crypto STATIC IMPORTED GLOBAL) -set_target_properties(crypto PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcrypto.a -) - -add_library(curl STATIC IMPORTED GLOBAL) -set_target_properties(curl PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcurl.a -) - -add_library(freetype STATIC IMPORTED GLOBAL) -set_target_properties(freetype PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libfreetype.a -) - -add_library(glfw3 STATIC IMPORTED GLOBAL) -set_target_properties(glfw3 PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libglfw3.a -) - - -add_library(jpeg STATIC IMPORTED GLOBAL) -set_target_properties(jpeg PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libjpeg.a -) - -add_library(png STATIC IMPORTED GLOBAL) -set_target_properties(png PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libpng.a -) - -add_library(ssl STATIC IMPORTED GLOBAL) -set_target_properties(ssl PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libssl.a -) - -add_library(uv STATIC IMPORTED GLOBAL) -set_target_properties(uv PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libuv_a.a - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/uv -) - -add_library(webp STATIC IMPORTED GLOBAL) -set_target_properties(webp PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libwebp.a -) - -add_library(websockets STATIC IMPORTED GLOBAL) -set_target_properties(websockets PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libwebsockets.a -) - -add_library(z STATIC IMPORTED GLOBAL) -set_target_properties(z PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libz.a - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/zlib -) - -add_library(v8_monolith STATIC IMPORTED GLOBAL) -set_target_properties(v8_monolith PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libv8_monolith.a - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/v8 - INTERFACE_COMPILE_DEFINITIONS V8_COMPRESS_POINTERS -) - -add_library(inspector STATIC IMPORTED GLOBAL) -set_target_properties(inspector PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libinspector.a -) -add_library(EGL SHARED IMPORTED GLOBAL) -set_target_properties(EGL PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libEGL.dylib -) - -add_library(GLESv2 SHARED IMPORTED GLOBAL) -set_target_properties(GLESv2 PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libGLESv2.dylib -) - -set(se_libs_name) - -if(CC_EDITOR) - message(STATUS "CC_EDITOR USE V8 FROM NODEJS") -elseif(USE_SE_V8) - list(APPEND se_libs_name - v8_monolith - uv - ) - if(USE_V8_DEBUGGER) - list(APPEND se_libs_name inspector) - endif() -endif() - -# if(USE_SOCKETS) -# list(APPEND CC_EXTERNAL_LIBS -# websockets -# ) -# endif() - -############################# glslang ############################# - -add_library(GenericCodeGen STATIC IMPORTED GLOBAL) -set_target_properties(GenericCodeGen PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libGenericCodeGen.a -) - -add_library(glslang STATIC IMPORTED GLOBAL) -set_target_properties(glslang PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libglslang.a -) - -add_library(glslang-default-resource-limits STATIC IMPORTED GLOBAL) -set_target_properties(glslang-default-resource-limits PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libglslang-default-resource-limits.a -) - -add_library(MachineIndependent STATIC IMPORTED GLOBAL) -set_target_properties(MachineIndependent PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libMachineIndependent.a -) - -add_library(OGLCompiler STATIC IMPORTED GLOBAL) -set_target_properties(OGLCompiler PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libOGLCompiler.a -) - -add_library(OSDependent STATIC IMPORTED GLOBAL) -set_target_properties(OSDependent PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libOSDependent.a -) - -add_library(SPIRV STATIC IMPORTED GLOBAL) -set_target_properties(SPIRV PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV.a -) - -add_library(SPIRV-Tools STATIC IMPORTED GLOBAL) -set_target_properties(SPIRV-Tools PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV-Tools.a -) - -add_library(SPIRV-Tools-opt STATIC IMPORTED GLOBAL) -set_target_properties(SPIRV-Tools-opt PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV-Tools-opt.a -) - - -set(glslang_libs_name glslang glslang-default-resource-limits MachineIndependent OGLCompiler OSDependent SPIRV SPIRV-Tools SPIRV-Tools-opt GenericCodeGen) - -############################# SPIRV-Cross ############################# - -add_library(spirv-cross-core STATIC IMPORTED GLOBAL) -set_target_properties(spirv-cross-core PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libspirv-cross-core.a -) -add_library(spirv-cross-msl STATIC IMPORTED GLOBAL) -set_target_properties(spirv-cross-msl PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libspirv-cross-msl.a -) -add_library(spirv-cross-glsl STATIC IMPORTED GLOBAL) -set_target_properties(spirv-cross-glsl PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libspirv-cross-glsl.a -) -set(spirv-cross_libs_name spirv-cross-core spirv-cross-glsl spirv-cross-msl) - -############################# TBB ############################# - -add_library(tbb STATIC IMPORTED GLOBAL) -set_target_properties(tbb PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libtbb_static.a -) -set(tbb_libs_name tbb) - -if(USE_PHYSICS_PHYSX) - set(PhysXSDK PhysX PhysXCommon PhysXFoundation PhysXExtensions PhysXCooking PhysXCharacterKinematic PhysXVehicle PhysXPvdSDK) - foreach(PX IN LISTS PhysXSDK) - add_library(${PX} STATIC IMPORTED GLOBAL) - set_target_properties(${PX} PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/PhysX/lib${PX}_static_64.a - ) - endforeach() -else() - set(PhysXSDK) -endif() - -list(APPEND CC_EXTERNAL_LIBS - freetype - jpeg - png - webp - curl - crypto - ssl - ${glslang_libs_name} - ${spirv-cross_libs_name} - ${tbb_libs_name} - ${PhysXSDK} -) - -set(ZLIB z) -if(NOT USE_MODULES) - list(APPEND CC_EXTERNAL_LIBS ${ZLIB} ${se_libs_name}) -endif() - - -list(APPEND CC_EXTERNAL_INCLUDES - ${CMAKE_CURRENT_LIST_DIR}/include -) + +add_library(crypto STATIC IMPORTED GLOBAL) +set_target_properties(crypto PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcrypto.a +) + +add_library(curl STATIC IMPORTED GLOBAL) +set_target_properties(curl PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcurl.a +) + +add_library(freetype STATIC IMPORTED GLOBAL) +set_target_properties(freetype PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libfreetype.a +) + +add_library(glfw3 STATIC IMPORTED GLOBAL) +set_target_properties(glfw3 PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libglfw3.a +) + + +add_library(jpeg STATIC IMPORTED GLOBAL) +set_target_properties(jpeg PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libjpeg.a +) + +add_library(png STATIC IMPORTED GLOBAL) +set_target_properties(png PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libpng.a +) + +add_library(ssl STATIC IMPORTED GLOBAL) +set_target_properties(ssl PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libssl.a +) + +add_library(uv STATIC IMPORTED GLOBAL) +set_target_properties(uv PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libuv_a.a + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/uv +) + +add_library(webp STATIC IMPORTED GLOBAL) +set_target_properties(webp PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libwebp.a +) + +add_library(websockets STATIC IMPORTED GLOBAL) +set_target_properties(websockets PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libwebsockets.a +) + +add_library(z STATIC IMPORTED GLOBAL) +set_target_properties(z PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libz.a + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/zlib +) + +add_library(v8_monolith STATIC IMPORTED GLOBAL) +set_target_properties(v8_monolith PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libv8_monolith.a + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/v8 + INTERFACE_COMPILE_DEFINITIONS V8_COMPRESS_POINTERS +) + +add_library(inspector STATIC IMPORTED GLOBAL) +set_target_properties(inspector PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libinspector.a +) +add_library(EGL SHARED IMPORTED GLOBAL) +set_target_properties(EGL PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libEGL.dylib +) + +add_library(GLESv2 SHARED IMPORTED GLOBAL) +set_target_properties(GLESv2 PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libGLESv2.dylib +) + +set(se_libs_name) + +if(CC_EDITOR) + message(STATUS "CC_EDITOR USE V8 FROM NODEJS") +elseif(USE_SE_V8 OR USE_NODE_NAPI) + list(APPEND se_libs_name + v8_monolith + uv + ) + if(USE_V8_DEBUGGER) + list(APPEND se_libs_name inspector) + endif() +endif() + +# if(USE_SOCKETS) +# list(APPEND CC_EXTERNAL_LIBS +# websockets +# ) +# endif() + +############################# glslang ############################# + +add_library(GenericCodeGen STATIC IMPORTED GLOBAL) +set_target_properties(GenericCodeGen PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libGenericCodeGen.a +) + +add_library(glslang STATIC IMPORTED GLOBAL) +set_target_properties(glslang PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libglslang.a +) + +add_library(glslang-default-resource-limits STATIC IMPORTED GLOBAL) +set_target_properties(glslang-default-resource-limits PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libglslang-default-resource-limits.a +) + +add_library(MachineIndependent STATIC IMPORTED GLOBAL) +set_target_properties(MachineIndependent PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libMachineIndependent.a +) + +add_library(OGLCompiler STATIC IMPORTED GLOBAL) +set_target_properties(OGLCompiler PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libOGLCompiler.a +) + +add_library(OSDependent STATIC IMPORTED GLOBAL) +set_target_properties(OSDependent PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libOSDependent.a +) + +add_library(SPIRV STATIC IMPORTED GLOBAL) +set_target_properties(SPIRV PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV.a +) + +add_library(SPIRV-Tools STATIC IMPORTED GLOBAL) +set_target_properties(SPIRV-Tools PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV-Tools.a +) + +add_library(SPIRV-Tools-opt STATIC IMPORTED GLOBAL) +set_target_properties(SPIRV-Tools-opt PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/libSPIRV-Tools-opt.a +) + + +set(glslang_libs_name glslang glslang-default-resource-limits MachineIndependent OGLCompiler OSDependent SPIRV SPIRV-Tools SPIRV-Tools-opt GenericCodeGen) + +############################# SPIRV-Cross ############################# + +add_library(spirv-cross-core STATIC IMPORTED GLOBAL) +set_target_properties(spirv-cross-core PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libspirv-cross-core.a +) +add_library(spirv-cross-msl STATIC IMPORTED GLOBAL) +set_target_properties(spirv-cross-msl PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libspirv-cross-msl.a +) +add_library(spirv-cross-glsl STATIC IMPORTED GLOBAL) +set_target_properties(spirv-cross-glsl PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libspirv-cross-glsl.a +) +set(spirv-cross_libs_name spirv-cross-core spirv-cross-glsl spirv-cross-msl) + +############################# TBB ############################# + +add_library(tbb STATIC IMPORTED GLOBAL) +set_target_properties(tbb PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libtbb_static.a +) +set(tbb_libs_name tbb) + +if(USE_PHYSICS_PHYSX) + set(PhysXSDK PhysX PhysXCommon PhysXFoundation PhysXExtensions PhysXCooking PhysXCharacterKinematic PhysXVehicle PhysXPvdSDK) + foreach(PX IN LISTS PhysXSDK) + add_library(${PX} STATIC IMPORTED GLOBAL) + set_target_properties(${PX} PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/PhysX/lib${PX}_static_64.a + ) + endforeach() +else() + set(PhysXSDK) +endif() + +list(APPEND CC_EXTERNAL_LIBS + freetype + jpeg + png + webp + curl + crypto + ssl + ${glslang_libs_name} + ${spirv-cross_libs_name} + ${tbb_libs_name} + ${PhysXSDK} +) + +set(ZLIB z) +if(NOT USE_MODULES) + list(APPEND CC_EXTERNAL_LIBS ${ZLIB} ${se_libs_name}) +endif() + + +list(APPEND CC_EXTERNAL_INCLUDES + ${CMAKE_CURRENT_LIST_DIR}/include +) diff --git a/ohos/CMakeLists.txt b/ohos/CMakeLists.txt index be7364b6..7ae56674 100644 --- a/ohos/CMakeLists.txt +++ b/ohos/CMakeLists.txt @@ -1,197 +1,197 @@ - -set(ohos_lib_dir ${platform_spec_path}/lib) - -add_library(crypto STATIC IMPORTED GLOBAL) -set_target_properties(crypto PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libcrypto.a -) - -add_library(freetype STATIC IMPORTED GLOBAL) -set_target_properties(freetype PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libfreetype.a -) - -add_library(jpeg STATIC IMPORTED GLOBAL) -set_target_properties(jpeg PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libjpeg.a -) - -add_library(png STATIC IMPORTED GLOBAL) -set_target_properties(png PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libpng16.a -) - -add_library(ssl STATIC IMPORTED GLOBAL) -set_target_properties(ssl PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libssl.a -) - -add_library(uv STATIC IMPORTED GLOBAL) -set_target_properties(uv PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libuv_a.a -) - -add_library(webp STATIC IMPORTED GLOBAL) -set_target_properties(webp PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libwebp.a -) - -add_library(websockets STATIC IMPORTED GLOBAL) -set_target_properties(websockets PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libwebsockets.a -) -add_library(sqlite3 STATIC IMPORTED GLOBAL) -set_target_properties(sqlite3 PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libsqlite3.a -) -add_library(z STATIC IMPORTED GLOBAL) -set_target_properties(z PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libz.a -) - -add_library(OpenALSoft SHARED IMPORTED GLOBAL) -set_target_properties(OpenALSoft PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libopenal.a -) - -add_library(mpg123 SHARED IMPORTED GLOBAL) -set_target_properties(mpg123 PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libmpg123.a -) - -set(se_libs_name) - -if(USE_SE_V8) - add_library(v8_monolith STATIC IMPORTED GLOBAL) - set_target_properties(v8_monolith PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libv8_monolith.a - ) - - set(OHOS_ARM64_MACROS - V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64 - ENABLE_MINOR_MC - V8_INTL_SUPPORT - V8_CONCURRENT_MARKING - V8_ENABLE_LAZY_SOURCE_POSITIONS - V8_EMBEDDED_BUILTINS - V8_WIN64_UNWINDING_INFO - V8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH - V8_SNAPSHOT_COMPRESSION - V8_31BIT_SMIS_ON_64BIT_ARCH - V8_DEPRECATION_WARNINGS - V8_IMMINENT_DEPRECATION_WARNINGS - V8_TARGET_ARCH_ARM64 - V8_HAVE_TARGET_OS - V8_TARGET_OS_LINUX - DISABLE_UNTRUSTED_CODE_MITIGATIONS - V8_COMPRESS_POINTERS - U_USING_ICU_NAMESPACE=0 - U_ENABLE_DYLOAD=0 - USE_CHROMIUM_ICU=1 - U_STATIC_IMPLEMENTATION - ) - - if(OHOS_ARCH STREQUAL "arm64-v8a") - set_property(TARGET v8_monolith - APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS ${OHOS_ARM64_MACROS} - ) - endif() - - add_library(v8_inspector STATIC IMPORTED GLOBAL) - set_target_properties(v8_inspector PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libinspector.a - INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/v8 - ) - - set(se_libs_name v8_monolith v8_inspector) -endif() - -if(USE_SOCKET) - list(APPEND CC_EXTERNAL_LIBS - websockets - ssl - crypto - ) -endif() - -if(USE_SE_V8 AND USE_V8_DEBUGGER) - list(APPEND CC_EXTERNAL_LIBS - v8_inspector - ) -endif() - -add_library(glslang STATIC IMPORTED GLOBAL) -set_target_properties(glslang PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libglslang.a -) -add_library(OGLCompiler STATIC IMPORTED GLOBAL) -set_target_properties(OGLCompiler PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libOGLCompiler.a -) -add_library(OSDependent STATIC IMPORTED GLOBAL) -set_target_properties(OSDependent PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libOSDependent.a -) -add_library(SPIRV STATIC IMPORTED GLOBAL) -set_target_properties(SPIRV PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libSPIRV.a -) -add_library(glslang-default-resource-limits STATIC IMPORTED GLOBAL) -set_target_properties(glslang-default-resource-limits PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libglslang-default-resource-limits.a -) -set(glslang_libs_name glslang OGLCompiler OSDependent SPIRV glslang-default-resource-limits) - - -############################# TBB ############################# -if(USE_JOB_SYSTEM_TBB) - add_library(tbb STATIC IMPORTED GLOBAL) - set_target_properties(tbb PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libtbb_static.a - ) - add_library(tbbmalloc STATIC IMPORTED GLOBAL) - set_target_properties(tbbmalloc PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libtbbmalloc_static.a - ) - add_library(tbbmalloc_proxy STATIC IMPORTED GLOBAL) - set_target_properties(tbbmalloc_proxy PROPERTIES - IMPORTED_LOCATION ${ohos_lib_dir}/libtbbmalloc_proxy_static.a - ) - set(tbb_libs_name tbbmalloc_proxy tbbmalloc tbb) - list(APPEND CC_EXTERNAL_LIBS - ${tbb_libs_name} - ) -endif() - -list(APPEND CC_EXTERNAL_LIBS - freetype - jpeg - png - webp - sqlite3 - ${se_libs_name} - ${glslang_libs_name} - OpenALSoft - mpg123 -) - -set(ZLIB z) -if(NOT USE_MODULES) - list(APPEND CC_EXTERNAL_LIBS ${ZLIB}) -endif() - - -if(USE_V8_DEBUGGER OR USE_WEBSOCKET_SERVER) - list(APPEND CC_EXTERNAL_LIBS - uv - ) -endif() - -list(APPEND CC_EXTERNAL_INCLUDES - ${platform_spec_path}/include - ${platform_spec_path}/include/v8 -) - -#TODO: remove in future version -link_directories(${platform_spec_path}/ext/usr/lib) -include_directories(${platform_spec_path}/ext/usr/include) + +set(ohos_lib_dir ${platform_spec_path}/lib) + +add_library(crypto STATIC IMPORTED GLOBAL) +set_target_properties(crypto PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libcrypto.a +) + +add_library(freetype STATIC IMPORTED GLOBAL) +set_target_properties(freetype PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libfreetype.a +) + +add_library(jpeg STATIC IMPORTED GLOBAL) +set_target_properties(jpeg PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libjpeg.a +) + +add_library(png STATIC IMPORTED GLOBAL) +set_target_properties(png PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libpng16.a +) + +add_library(ssl STATIC IMPORTED GLOBAL) +set_target_properties(ssl PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libssl.a +) + +add_library(uv STATIC IMPORTED GLOBAL) +set_target_properties(uv PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libuv_a.a +) + +add_library(webp STATIC IMPORTED GLOBAL) +set_target_properties(webp PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libwebp.a +) + +add_library(websockets STATIC IMPORTED GLOBAL) +set_target_properties(websockets PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libwebsockets.a +) +add_library(sqlite3 STATIC IMPORTED GLOBAL) +set_target_properties(sqlite3 PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libsqlite3.a +) +add_library(z STATIC IMPORTED GLOBAL) +set_target_properties(z PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libz.a +) + +add_library(OpenALSoft SHARED IMPORTED GLOBAL) +set_target_properties(OpenALSoft PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libopenal.a +) + +add_library(mpg123 SHARED IMPORTED GLOBAL) +set_target_properties(mpg123 PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libmpg123.a +) + +set(se_libs_name) + +if(USE_SE_V8) + add_library(v8_monolith STATIC IMPORTED GLOBAL) + set_target_properties(v8_monolith PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libv8_monolith.a + ) + + set(OHOS_ARM64_MACROS + V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64 + ENABLE_MINOR_MC + V8_INTL_SUPPORT + V8_CONCURRENT_MARKING + V8_ENABLE_LAZY_SOURCE_POSITIONS + V8_EMBEDDED_BUILTINS + V8_WIN64_UNWINDING_INFO + V8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH + V8_SNAPSHOT_COMPRESSION + V8_31BIT_SMIS_ON_64BIT_ARCH + V8_DEPRECATION_WARNINGS + V8_IMMINENT_DEPRECATION_WARNINGS + V8_TARGET_ARCH_ARM64 + V8_HAVE_TARGET_OS + V8_TARGET_OS_LINUX + DISABLE_UNTRUSTED_CODE_MITIGATIONS + V8_COMPRESS_POINTERS + U_USING_ICU_NAMESPACE=0 + U_ENABLE_DYLOAD=0 + USE_CHROMIUM_ICU=1 + U_STATIC_IMPLEMENTATION + ) + + if(OHOS_ARCH STREQUAL "arm64-v8a") + set_property(TARGET v8_monolith + APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS ${OHOS_ARM64_MACROS} + ) + endif() + + add_library(v8_inspector STATIC IMPORTED GLOBAL) + set_target_properties(v8_inspector PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libinspector.a + INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/v8 + ) + + set(se_libs_name v8_monolith v8_inspector) +endif() + +if(USE_SOCKET) + list(APPEND CC_EXTERNAL_LIBS + websockets + ssl + crypto + ) +endif() + +if(USE_SE_V8 AND USE_V8_DEBUGGER) + list(APPEND CC_EXTERNAL_LIBS + v8_inspector + ) +endif() + +add_library(glslang STATIC IMPORTED GLOBAL) +set_target_properties(glslang PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libglslang.a +) +add_library(OGLCompiler STATIC IMPORTED GLOBAL) +set_target_properties(OGLCompiler PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libOGLCompiler.a +) +add_library(OSDependent STATIC IMPORTED GLOBAL) +set_target_properties(OSDependent PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libOSDependent.a +) +add_library(SPIRV STATIC IMPORTED GLOBAL) +set_target_properties(SPIRV PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libSPIRV.a +) +add_library(glslang-default-resource-limits STATIC IMPORTED GLOBAL) +set_target_properties(glslang-default-resource-limits PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libglslang-default-resource-limits.a +) +set(glslang_libs_name glslang OGLCompiler OSDependent SPIRV glslang-default-resource-limits) + + +############################# TBB ############################# +if(USE_JOB_SYSTEM_TBB) + add_library(tbb STATIC IMPORTED GLOBAL) + set_target_properties(tbb PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libtbb_static.a + ) + add_library(tbbmalloc STATIC IMPORTED GLOBAL) + set_target_properties(tbbmalloc PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libtbbmalloc_static.a + ) + add_library(tbbmalloc_proxy STATIC IMPORTED GLOBAL) + set_target_properties(tbbmalloc_proxy PROPERTIES + IMPORTED_LOCATION ${ohos_lib_dir}/libtbbmalloc_proxy_static.a + ) + set(tbb_libs_name tbbmalloc_proxy tbbmalloc tbb) + list(APPEND CC_EXTERNAL_LIBS + ${tbb_libs_name} + ) +endif() + +list(APPEND CC_EXTERNAL_LIBS + freetype + jpeg + png + webp + sqlite3 + ${se_libs_name} + ${glslang_libs_name} + OpenALSoft + mpg123 +) + +set(ZLIB z) +if(NOT USE_MODULES) + list(APPEND CC_EXTERNAL_LIBS ${ZLIB}) +endif() + + +if(USE_V8_DEBUGGER OR USE_WEBSOCKET_SERVER) + list(APPEND CC_EXTERNAL_LIBS + uv + ) +endif() + +list(APPEND CC_EXTERNAL_INCLUDES + ${platform_spec_path}/include + ${platform_spec_path}/include/v8 +) + +#TODO: remove in future version +link_directories(${platform_spec_path}/ext/usr/lib) +include_directories(${platform_spec_path}/ext/usr/include) diff --git a/sources/CMakeLists.txt b/sources/CMakeLists.txt index 3ce8042f..2a65ebf4 100644 --- a/sources/CMakeLists.txt +++ b/sources/CMakeLists.txt @@ -1,82 +1,89 @@ - - -set(CC_UNZIP_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/unzip/crypt.h - ${CMAKE_CURRENT_LIST_DIR}/unzip/ioapi.cpp - ${CMAKE_CURRENT_LIST_DIR}/unzip/ioapi.h - ${CMAKE_CURRENT_LIST_DIR}/unzip/ioapi_mem.cpp - ${CMAKE_CURRENT_LIST_DIR}/unzip/ioapi_mem.h - ${CMAKE_CURRENT_LIST_DIR}/unzip/unzip.cpp - ${CMAKE_CURRENT_LIST_DIR}/unzip/unzip.h -) - -set(CC_TINYDIR_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/tinyxml2/tinyxml2.cpp - ${CMAKE_CURRENT_LIST_DIR}/tinyxml2/tinyxml2.h - ${CMAKE_CURRENT_LIST_DIR}/tinydir/tinydir.h -) - -set(CC_UTILS_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/ConvertUTF/ConvertUTF.c - ${CMAKE_CURRENT_LIST_DIR}/ConvertUTF/ConvertUTF.h - ${CMAKE_CURRENT_LIST_DIR}/ConvertUTF/ConvertUTFWrapper.cpp - ${CMAKE_CURRENT_LIST_DIR}/xxtea/xxtea.cpp - ${CMAKE_CURRENT_LIST_DIR}/xxtea/xxtea.h -) - -set(CC_MURMURHASH2_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/MurmurHash2/MurmurHash2.cpp - ${CMAKE_CURRENT_LIST_DIR}/MurmurHash2/MurmurHash2.h -) - -set(CC_EXTERNAL_SOURCES - - ${CMAKE_CURRENT_LIST_DIR}/tommyds/tommy.c - ${CMAKE_CURRENT_LIST_DIR}/tommyds/tommy.h -) - -if(NOT USE_MODULES) - list(APPEND CC_EXTERNAL_SOURCES - ${CC_UNZIP_SOURCES} - ${CC_TINYDIR_SOURCES} - ${CC_UTILS_SOURCES} - ${CC_MURMURHASH2_SOURCES} - ) -endif() - -# add dependent boost libs -include(${CMAKE_CURRENT_LIST_DIR}/boost-source/boost.cmake) - -if(ANDROID OR OHOS) - - include(${CMAKE_CURRENT_LIST_DIR}/pvmp3dec/CMakeLists.txt) - include(${CMAKE_CURRENT_LIST_DIR}/tremolo/CMakeLists.txt) - include(${CMAKE_CURRENT_LIST_DIR}/Swappy/src/swappy/CMakeLists.txt) - - list(APPEND CC_EXTERNAL_LIBS - pvmp3dec - vorbisidec - swappy - ) - -elseif(WINDOWS) - set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/ConvertUTF/ConvertUTF.c PROPERTIES - LANGUAGE C - ) -elseif(APPLE) - if(USE_SOCKET) - include(${CMAKE_CURRENT_LIST_DIR}/SocketRocket/CMakeLists.txt) - endif() -endif() - -list(APPEND CC_EXTERNAL_INCLUDES - ${CMAKE_CURRENT_LIST_DIR} -) - -if(USE_PHYSICS_PHYSX) - list(APPEND CC_EXTERNAL_INCLUDES - ${CMAKE_CURRENT_LIST_DIR}/PhysX/PhysX/include - ${CMAKE_CURRENT_LIST_DIR}/PhysX/PhysX/source - ${CMAKE_CURRENT_LIST_DIR}/PhysX/PxShared/include - ) -endif() + + +set(CC_UNZIP_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/unzip/crypt.h + ${CMAKE_CURRENT_LIST_DIR}/unzip/ioapi.cpp + ${CMAKE_CURRENT_LIST_DIR}/unzip/ioapi.h + ${CMAKE_CURRENT_LIST_DIR}/unzip/ioapi_mem.cpp + ${CMAKE_CURRENT_LIST_DIR}/unzip/ioapi_mem.h + ${CMAKE_CURRENT_LIST_DIR}/unzip/unzip.cpp + ${CMAKE_CURRENT_LIST_DIR}/unzip/unzip.h +) + +set(CC_TINYDIR_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/tinyxml2/tinyxml2.cpp + ${CMAKE_CURRENT_LIST_DIR}/tinyxml2/tinyxml2.h + ${CMAKE_CURRENT_LIST_DIR}/tinydir/tinydir.h +) + +set(CC_UTILS_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/ConvertUTF/ConvertUTF.c + ${CMAKE_CURRENT_LIST_DIR}/ConvertUTF/ConvertUTF.h + ${CMAKE_CURRENT_LIST_DIR}/ConvertUTF/ConvertUTFWrapper.cpp + ${CMAKE_CURRENT_LIST_DIR}/xxtea/xxtea.cpp + ${CMAKE_CURRENT_LIST_DIR}/xxtea/xxtea.h +) + +set(CC_MURMURHASH2_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/MurmurHash2/MurmurHash2.cpp + ${CMAKE_CURRENT_LIST_DIR}/MurmurHash2/MurmurHash2.h +) + +set(CC_EXTERNAL_SOURCES + + ${CMAKE_CURRENT_LIST_DIR}/tommyds/tommy.c + ${CMAKE_CURRENT_LIST_DIR}/tommyds/tommy.h +) + +if(NOT USE_MODULES) + list(APPEND CC_EXTERNAL_SOURCES + ${CC_UNZIP_SOURCES} + ${CC_TINYDIR_SOURCES} + ${CC_UTILS_SOURCES} + ${CC_MURMURHASH2_SOURCES} + ) +endif() + +# add dependent boost libs +include(${CMAKE_CURRENT_LIST_DIR}/boost-source/boost.cmake) + +if(ANDROID OR OHOS) + + include(${CMAKE_CURRENT_LIST_DIR}/pvmp3dec/CMakeLists.txt) + include(${CMAKE_CURRENT_LIST_DIR}/tremolo/CMakeLists.txt) + include(${CMAKE_CURRENT_LIST_DIR}/Swappy/src/swappy/CMakeLists.txt) + + list(APPEND CC_EXTERNAL_LIBS + pvmp3dec + vorbisidec + swappy + ) + +elseif(WINDOWS) + set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/ConvertUTF/ConvertUTF.c PROPERTIES + LANGUAGE C + ) +elseif(APPLE) + if(USE_SOCKET) + include(${CMAKE_CURRENT_LIST_DIR}/SocketRocket/CMakeLists.txt) + endif() +endif() + +list(APPEND CC_EXTERNAL_INCLUDES + ${CMAKE_CURRENT_LIST_DIR} +) + +if(USE_PHYSICS_PHYSX) + list(APPEND CC_EXTERNAL_INCLUDES + ${CMAKE_CURRENT_LIST_DIR}/PhysX/PhysX/include + ${CMAKE_CURRENT_LIST_DIR}/PhysX/PhysX/source + ${CMAKE_CURRENT_LIST_DIR}/PhysX/PxShared/include + ) +endif() + +if(USE_NODE_NAPI) + add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/node_napi node_napi) + list(APPEND CC_EXTERNAL_LIBS + node_napi + ) +endif() diff --git a/sources/node_napi/CMakeLists.txt b/sources/node_napi/CMakeLists.txt new file mode 100644 index 00000000..ea125449 --- /dev/null +++ b/sources/node_napi/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.10) + +project(node_napi CXX) + +add_library(node_napi +js_native_api.h +js_native_api_types.h +js_native_api_v8.cc +js_native_api_v8.h +js_native_api_v8_internals.h +js_native_api_util.h +) +target_include_directories(node_napi PUBLIC ${CMAKE_CURRENT_LIST_DIR}) + +target_compile_definitions(node_napi +PUBLIC + NODE_WANT_INTERNALS=1 + NODE_MODULE_VERSION=93 + NAPI_VERSION=8 +) + +target_link_libraries(node_napi PUBLIC ${se_libs_name}) diff --git a/sources/node_napi/README.md b/sources/node_napi/README.md new file mode 100644 index 00000000..1fd75bd5 --- /dev/null +++ b/sources/node_napi/README.md @@ -0,0 +1 @@ +download from https://nodejs.org/download/release/v16.5.0/ \ No newline at end of file diff --git a/sources/node_napi/js_native_api.h b/sources/node_napi/js_native_api.h new file mode 100644 index 00000000..05ef41bd --- /dev/null +++ b/sources/node_napi/js_native_api.h @@ -0,0 +1,569 @@ +#ifndef SRC_JS_NATIVE_API_H_ +#define SRC_JS_NATIVE_API_H_ + +// This file needs to be compatible with C compilers. +#include // NOLINT(modernize-deprecated-headers) +#include // NOLINT(modernize-deprecated-headers) + +// Use INT_MAX, this should only be consumed by the pre-processor anyway. +#define NAPI_VERSION_EXPERIMENTAL 2147483647 +#ifndef NAPI_VERSION + #ifdef NAPI_EXPERIMENTAL + #define NAPI_VERSION NAPI_VERSION_EXPERIMENTAL + #else + // The baseline version for N-API. + // The NAPI_VERSION controls which version will be used by default when + // compilling a native addon. If the addon developer specifically wants to use + // functions available in a new version of N-API that is not yet ported in all + // LTS versions, they can set NAPI_VERSION knowing that they have specifically + // depended on that version. + #define NAPI_VERSION 8 + #endif +#endif + +#include "js_native_api_types.h" + +// If you need __declspec(dllimport), either include instead, or +// define NAPI_EXTERN as __declspec(dllimport) on the compiler's command line. +#ifndef NAPI_EXTERN + #ifdef _WIN32 + #define NAPI_EXTERN __declspec(dllexport) + #elif defined(__wasm32__) + #define NAPI_EXTERN __attribute__((visibility("default"))) \ + __attribute__((__import_module__("napi"))) + #else + #define NAPI_EXTERN __attribute__((visibility("default"))) + #endif +#endif + +#define NAPI_AUTO_LENGTH SIZE_MAX + +#ifdef __cplusplus + #define EXTERN_C_START extern "C" { + #define EXTERN_C_END } +#else + #define EXTERN_C_START + #define EXTERN_C_END +#endif + +EXTERN_C_START + +NAPI_EXTERN napi_status +napi_get_last_error_info(napi_env env, + const napi_extended_error_info** result); + +// Getters for defined singletons +NAPI_EXTERN napi_status napi_get_undefined(napi_env env, napi_value* result); +NAPI_EXTERN napi_status napi_get_null(napi_env env, napi_value* result); +NAPI_EXTERN napi_status napi_get_global(napi_env env, napi_value* result); +NAPI_EXTERN napi_status napi_get_boolean(napi_env env, + bool value, + napi_value* result); + +// Methods to create Primitive types/Objects +NAPI_EXTERN napi_status napi_create_object(napi_env env, napi_value* result); +NAPI_EXTERN napi_status napi_create_array(napi_env env, napi_value* result); +NAPI_EXTERN napi_status napi_create_array_with_length(napi_env env, + size_t length, + napi_value* result); +NAPI_EXTERN napi_status napi_create_double(napi_env env, + double value, + napi_value* result); +NAPI_EXTERN napi_status napi_create_int32(napi_env env, + int32_t value, + napi_value* result); +NAPI_EXTERN napi_status napi_create_uint32(napi_env env, + uint32_t value, + napi_value* result); +NAPI_EXTERN napi_status napi_create_int64(napi_env env, + int64_t value, + napi_value* result); +NAPI_EXTERN napi_status napi_create_string_latin1(napi_env env, + const char* str, + size_t length, + napi_value* result); +NAPI_EXTERN napi_status napi_create_string_utf8(napi_env env, + const char* str, + size_t length, + napi_value* result); +NAPI_EXTERN napi_status napi_create_string_utf16(napi_env env, + const char16_t* str, + size_t length, + napi_value* result); +NAPI_EXTERN napi_status napi_create_symbol(napi_env env, + napi_value description, + napi_value* result); +NAPI_EXTERN napi_status napi_create_function(napi_env env, + const char* utf8name, + size_t length, + napi_callback cb, + void* data, + napi_value* result); +NAPI_EXTERN napi_status napi_create_error(napi_env env, + napi_value code, + napi_value msg, + napi_value* result); +NAPI_EXTERN napi_status napi_create_type_error(napi_env env, + napi_value code, + napi_value msg, + napi_value* result); +NAPI_EXTERN napi_status napi_create_range_error(napi_env env, + napi_value code, + napi_value msg, + napi_value* result); + +// Methods to get the native napi_value from Primitive type +NAPI_EXTERN napi_status napi_typeof(napi_env env, + napi_value value, + napi_valuetype* result); +NAPI_EXTERN napi_status napi_get_value_double(napi_env env, + napi_value value, + double* result); +NAPI_EXTERN napi_status napi_get_value_int32(napi_env env, + napi_value value, + int32_t* result); +NAPI_EXTERN napi_status napi_get_value_uint32(napi_env env, + napi_value value, + uint32_t* result); +NAPI_EXTERN napi_status napi_get_value_int64(napi_env env, + napi_value value, + int64_t* result); +NAPI_EXTERN napi_status napi_get_value_bool(napi_env env, + napi_value value, + bool* result); + +// Copies LATIN-1 encoded bytes from a string into a buffer. +NAPI_EXTERN napi_status napi_get_value_string_latin1(napi_env env, + napi_value value, + char* buf, + size_t bufsize, + size_t* result); + +// Copies UTF-8 encoded bytes from a string into a buffer. +NAPI_EXTERN napi_status napi_get_value_string_utf8(napi_env env, + napi_value value, + char* buf, + size_t bufsize, + size_t* result); + +// Copies UTF-16 encoded bytes from a string into a buffer. +NAPI_EXTERN napi_status napi_get_value_string_utf16(napi_env env, + napi_value value, + char16_t* buf, + size_t bufsize, + size_t* result); + +// Methods to coerce values +// These APIs may execute user scripts +NAPI_EXTERN napi_status napi_coerce_to_bool(napi_env env, + napi_value value, + napi_value* result); +NAPI_EXTERN napi_status napi_coerce_to_number(napi_env env, + napi_value value, + napi_value* result); +NAPI_EXTERN napi_status napi_coerce_to_object(napi_env env, + napi_value value, + napi_value* result); +NAPI_EXTERN napi_status napi_coerce_to_string(napi_env env, + napi_value value, + napi_value* result); + +// Methods to work with Objects +NAPI_EXTERN napi_status napi_get_prototype(napi_env env, + napi_value object, + napi_value* result); +NAPI_EXTERN napi_status napi_get_property_names(napi_env env, + napi_value object, + napi_value* result); +NAPI_EXTERN napi_status napi_set_property(napi_env env, + napi_value object, + napi_value key, + napi_value value); +NAPI_EXTERN napi_status napi_has_property(napi_env env, + napi_value object, + napi_value key, + bool* result); +NAPI_EXTERN napi_status napi_get_property(napi_env env, + napi_value object, + napi_value key, + napi_value* result); +NAPI_EXTERN napi_status napi_delete_property(napi_env env, + napi_value object, + napi_value key, + bool* result); +NAPI_EXTERN napi_status napi_has_own_property(napi_env env, + napi_value object, + napi_value key, + bool* result); +NAPI_EXTERN napi_status napi_set_named_property(napi_env env, + napi_value object, + const char* utf8name, + napi_value value); +NAPI_EXTERN napi_status napi_has_named_property(napi_env env, + napi_value object, + const char* utf8name, + bool* result); +NAPI_EXTERN napi_status napi_get_named_property(napi_env env, + napi_value object, + const char* utf8name, + napi_value* result); +NAPI_EXTERN napi_status napi_set_element(napi_env env, + napi_value object, + uint32_t index, + napi_value value); +NAPI_EXTERN napi_status napi_has_element(napi_env env, + napi_value object, + uint32_t index, + bool* result); +NAPI_EXTERN napi_status napi_get_element(napi_env env, + napi_value object, + uint32_t index, + napi_value* result); +NAPI_EXTERN napi_status napi_delete_element(napi_env env, + napi_value object, + uint32_t index, + bool* result); +NAPI_EXTERN napi_status +napi_define_properties(napi_env env, + napi_value object, + size_t property_count, + const napi_property_descriptor* properties); + +// Methods to work with Arrays +NAPI_EXTERN napi_status napi_is_array(napi_env env, + napi_value value, + bool* result); +NAPI_EXTERN napi_status napi_get_array_length(napi_env env, + napi_value value, + uint32_t* result); + +// Methods to compare values +NAPI_EXTERN napi_status napi_strict_equals(napi_env env, + napi_value lhs, + napi_value rhs, + bool* result); + +// Methods to work with Functions +NAPI_EXTERN napi_status napi_call_function(napi_env env, + napi_value recv, + napi_value func, + size_t argc, + const napi_value* argv, + napi_value* result); +NAPI_EXTERN napi_status napi_new_instance(napi_env env, + napi_value constructor, + size_t argc, + const napi_value* argv, + napi_value* result); +NAPI_EXTERN napi_status napi_instanceof(napi_env env, + napi_value object, + napi_value constructor, + bool* result); + +// Methods to work with napi_callbacks + +// Gets all callback info in a single call. (Ugly, but faster.) +NAPI_EXTERN napi_status napi_get_cb_info( + napi_env env, // [in] NAPI environment handle + napi_callback_info cbinfo, // [in] Opaque callback-info handle + size_t* argc, // [in-out] Specifies the size of the provided argv array + // and receives the actual count of args. + napi_value* argv, // [out] Array of values + napi_value* this_arg, // [out] Receives the JS 'this' arg for the call + void** data); // [out] Receives the data pointer for the callback. + +NAPI_EXTERN napi_status napi_get_new_target(napi_env env, + napi_callback_info cbinfo, + napi_value* result); +NAPI_EXTERN napi_status +napi_define_class(napi_env env, + const char* utf8name, + size_t length, + napi_callback constructor, + void* data, + size_t property_count, + const napi_property_descriptor* properties, + napi_value* result); + +// Methods to work with external data objects +NAPI_EXTERN napi_status napi_wrap(napi_env env, + napi_value js_object, + void* native_object, + napi_finalize finalize_cb, + void* finalize_hint, + napi_ref* result); +NAPI_EXTERN napi_status napi_unwrap(napi_env env, + napi_value js_object, + void** result); +NAPI_EXTERN napi_status napi_remove_wrap(napi_env env, + napi_value js_object, + void** result); +NAPI_EXTERN napi_status napi_create_external(napi_env env, + void* data, + napi_finalize finalize_cb, + void* finalize_hint, + napi_value* result); +NAPI_EXTERN napi_status napi_get_value_external(napi_env env, + napi_value value, + void** result); + +// Methods to control object lifespan + +// Set initial_refcount to 0 for a weak reference, >0 for a strong reference. +NAPI_EXTERN napi_status napi_create_reference(napi_env env, + napi_value value, + uint32_t initial_refcount, + napi_ref* result); + +// Deletes a reference. The referenced value is released, and may +// be GC'd unless there are other references to it. +NAPI_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref); + +// Increments the reference count, optionally returning the resulting count. +// After this call the reference will be a strong reference because its +// refcount is >0, and the referenced object is effectively "pinned". +// Calling this when the refcount is 0 and the object is unavailable +// results in an error. +NAPI_EXTERN napi_status napi_reference_ref(napi_env env, + napi_ref ref, + uint32_t* result); + +NAPI_EXTERN napi_status napi_reference_count(napi_env env, + napi_ref ref, + uint32_t* result); + +// Decrements the reference count, optionally returning the resulting count. +// If the result is 0 the reference is now weak and the object may be GC'd +// at any time if there are no other references. Calling this when the +// refcount is already 0 results in an error. +NAPI_EXTERN napi_status napi_reference_unref(napi_env env, + napi_ref ref, + uint32_t* result); + +// Attempts to get a referenced value. If the reference is weak, +// the value might no longer be available, in that case the call +// is still successful but the result is NULL. +NAPI_EXTERN napi_status napi_get_reference_value(napi_env env, + napi_ref ref, + napi_value* result); + +NAPI_EXTERN napi_status napi_open_handle_scope(napi_env env, + napi_handle_scope* result); +NAPI_EXTERN napi_status napi_close_handle_scope(napi_env env, + napi_handle_scope scope); +NAPI_EXTERN napi_status +napi_open_escapable_handle_scope(napi_env env, + napi_escapable_handle_scope* result); +NAPI_EXTERN napi_status +napi_close_escapable_handle_scope(napi_env env, + napi_escapable_handle_scope scope); + +NAPI_EXTERN napi_status napi_escape_handle(napi_env env, + napi_escapable_handle_scope scope, + napi_value escapee, + napi_value* result); + +// Methods to support error handling +NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error); +NAPI_EXTERN napi_status napi_throw_error(napi_env env, + const char* code, + const char* msg); +NAPI_EXTERN napi_status napi_throw_type_error(napi_env env, + const char* code, + const char* msg); +NAPI_EXTERN napi_status napi_throw_range_error(napi_env env, + const char* code, + const char* msg); +NAPI_EXTERN napi_status napi_is_error(napi_env env, + napi_value value, + bool* result); + +// Methods to support catching exceptions +NAPI_EXTERN napi_status napi_is_exception_pending(napi_env env, bool* result); +NAPI_EXTERN napi_status napi_get_and_clear_last_exception(napi_env env, + napi_value* result); + +// Methods to work with array buffers and typed arrays +NAPI_EXTERN napi_status napi_is_arraybuffer(napi_env env, + napi_value value, + bool* result); +NAPI_EXTERN napi_status napi_create_arraybuffer(napi_env env, + size_t byte_length, + void** data, + napi_value* result); +NAPI_EXTERN napi_status + napi_create_external_arraybuffer(napi_env env, + void* external_data, + size_t byte_length, + napi_finalize finalize_cb, + void* finalize_hint, + napi_value* result); +NAPI_EXTERN napi_status napi_get_arraybuffer_info(napi_env env, + napi_value arraybuffer, + void** data, + size_t* byte_length); +NAPI_EXTERN napi_status napi_is_typedarray(napi_env env, + napi_value value, + bool* result); +NAPI_EXTERN napi_status napi_create_typedarray(napi_env env, + napi_typedarray_type type, + size_t length, + napi_value arraybuffer, + size_t byte_offset, + napi_value* result); +NAPI_EXTERN napi_status napi_get_typedarray_info(napi_env env, + napi_value typedarray, + napi_typedarray_type* type, + size_t* length, + void** data, + napi_value* arraybuffer, + size_t* byte_offset); + +NAPI_EXTERN napi_status napi_create_dataview(napi_env env, + size_t length, + napi_value arraybuffer, + size_t byte_offset, + napi_value* result); +NAPI_EXTERN napi_status napi_is_dataview(napi_env env, + napi_value value, + bool* result); +NAPI_EXTERN napi_status napi_get_dataview_info(napi_env env, + napi_value dataview, + size_t* bytelength, + void** data, + napi_value* arraybuffer, + size_t* byte_offset); + +// version management +NAPI_EXTERN napi_status napi_get_version(napi_env env, uint32_t* result); + +// Promises +NAPI_EXTERN napi_status napi_create_promise(napi_env env, + napi_deferred* deferred, + napi_value* promise); +NAPI_EXTERN napi_status napi_resolve_deferred(napi_env env, + napi_deferred deferred, + napi_value resolution); +NAPI_EXTERN napi_status napi_reject_deferred(napi_env env, + napi_deferred deferred, + napi_value rejection); +NAPI_EXTERN napi_status napi_is_promise(napi_env env, + napi_value value, + bool* is_promise); + +// Running a script +NAPI_EXTERN napi_status napi_run_script(napi_env env, + napi_value script, + napi_value* result); + +NAPI_EXTERN napi_status napi_run_script_with_filename(napi_env env, + napi_value script, const char*, + napi_value* result); + +// Memory management +NAPI_EXTERN napi_status napi_adjust_external_memory(napi_env env, + int64_t change_in_bytes, + int64_t* adjusted_value); + +#if NAPI_VERSION >= 5 + +// Dates +NAPI_EXTERN napi_status napi_create_date(napi_env env, + double time, + napi_value* result); + +NAPI_EXTERN napi_status napi_is_date(napi_env env, + napi_value value, + bool* is_date); + +NAPI_EXTERN napi_status napi_get_date_value(napi_env env, + napi_value value, + double* result); + +// Add finalizer for pointer +NAPI_EXTERN napi_status napi_add_finalizer(napi_env env, + napi_value js_object, + void* native_object, + napi_finalize finalize_cb, + void* finalize_hint, + napi_ref* result); + +#endif // NAPI_VERSION >= 5 + +#if NAPI_VERSION >= 6 + +// BigInt +NAPI_EXTERN napi_status napi_create_bigint_int64(napi_env env, + int64_t value, + napi_value* result); +NAPI_EXTERN napi_status napi_create_bigint_uint64(napi_env env, + uint64_t value, + napi_value* result); +NAPI_EXTERN napi_status napi_create_bigint_words(napi_env env, + int sign_bit, + size_t word_count, + const uint64_t* words, + napi_value* result); +NAPI_EXTERN napi_status napi_get_value_bigint_int64(napi_env env, + napi_value value, + int64_t* result, + bool* lossless); +NAPI_EXTERN napi_status napi_get_value_bigint_uint64(napi_env env, + napi_value value, + uint64_t* result, + bool* lossless); +NAPI_EXTERN napi_status napi_get_value_bigint_words(napi_env env, + napi_value value, + int* sign_bit, + size_t* word_count, + uint64_t* words); + +// Object +NAPI_EXTERN napi_status +napi_get_all_property_names(napi_env env, + napi_value object, + napi_key_collection_mode key_mode, + napi_key_filter key_filter, + napi_key_conversion key_conversion, + napi_value* result); + +// Instance data +NAPI_EXTERN napi_status napi_set_instance_data(napi_env env, + void* data, + napi_finalize finalize_cb, + void* finalize_hint); + +NAPI_EXTERN napi_status napi_get_instance_data(napi_env env, + void** data); +#endif // NAPI_VERSION >= 6 + +#if NAPI_VERSION >= 7 +// ArrayBuffer detaching +NAPI_EXTERN napi_status napi_detach_arraybuffer(napi_env env, + napi_value arraybuffer); + +NAPI_EXTERN napi_status napi_is_detached_arraybuffer(napi_env env, + napi_value value, + bool* result); +#endif // NAPI_VERSION >= 7 + +#if NAPI_VERSION >= 8 +// Type tagging +NAPI_EXTERN napi_status napi_type_tag_object(napi_env env, + napi_value value, + const napi_type_tag* type_tag); + +NAPI_EXTERN napi_status + napi_check_object_type_tag(napi_env env, + napi_value value, + const napi_type_tag* type_tag, + bool* result); +NAPI_EXTERN napi_status napi_object_freeze(napi_env env, + napi_value object); +NAPI_EXTERN napi_status napi_object_seal(napi_env env, + napi_value object); +#endif // NAPI_VERSION >= 8 + +EXTERN_C_END + +#endif // SRC_JS_NATIVE_API_H_ diff --git a/sources/node_napi/js_native_api_types.h b/sources/node_napi/js_native_api_types.h new file mode 100644 index 00000000..6aba0662 --- /dev/null +++ b/sources/node_napi/js_native_api_types.h @@ -0,0 +1,160 @@ +#ifndef SRC_JS_NATIVE_API_TYPES_H_ +#define SRC_JS_NATIVE_API_TYPES_H_ + +// This file needs to be compatible with C compilers. +// This is a public include file, and these includes have essentially +// became part of it's API. +#include // NOLINT(modernize-deprecated-headers) +#include // NOLINT(modernize-deprecated-headers) + +#if !defined __cplusplus || (defined(_MSC_VER) && _MSC_VER < 1900) + typedef uint16_t char16_t; +#endif + +// JSVM API types are all opaque pointers for ABI stability +// typedef undefined structs instead of void* for compile time type safety +typedef struct napi_env__* napi_env; +typedef struct napi_value__* napi_value; +typedef struct napi_ref__* napi_ref; +typedef struct napi_handle_scope__* napi_handle_scope; +typedef struct napi_escapable_handle_scope__* napi_escapable_handle_scope; +typedef struct napi_callback_info__* napi_callback_info; +typedef struct napi_deferred__* napi_deferred; + +typedef enum { + napi_default = 0, + napi_writable = 1 << 0, + napi_enumerable = 1 << 1, + napi_configurable = 1 << 2, + + // Used with napi_define_class to distinguish static properties + // from instance properties. Ignored by napi_define_properties. + napi_static = 1 << 10, + +#if NAPI_VERSION >= 8 + // Default for class methods. + napi_default_method = napi_writable | napi_configurable, + + // Default for object properties, like in JS obj[prop]. + napi_default_jsproperty = napi_writable | + napi_enumerable | + napi_configurable, +#endif // NAPI_VERSION >= 8 +} napi_property_attributes; + +typedef enum { + // ES6 types (corresponds to typeof) + napi_undefined, + napi_null, + napi_boolean, + napi_number, + napi_string, + napi_symbol, + napi_object, + napi_function, + napi_external, + napi_bigint, +} napi_valuetype; + +typedef enum { + napi_int8_array, + napi_uint8_array, + napi_uint8_clamped_array, + napi_int16_array, + napi_uint16_array, + napi_int32_array, + napi_uint32_array, + napi_float32_array, + napi_float64_array, + napi_bigint64_array, + napi_biguint64_array, +} napi_typedarray_type; + +typedef enum { + napi_ok, + napi_invalid_arg, + napi_object_expected, + napi_string_expected, + napi_name_expected, + napi_function_expected, + napi_number_expected, + napi_boolean_expected, + napi_array_expected, + napi_generic_failure, + napi_pending_exception, + napi_cancelled, + napi_escape_called_twice, + napi_handle_scope_mismatch, + napi_callback_scope_mismatch, + napi_queue_full, + napi_closing, + napi_bigint_expected, + napi_date_expected, + napi_arraybuffer_expected, + napi_detachable_arraybuffer_expected, + napi_would_deadlock // unused +} napi_status; +// Note: when adding a new enum value to `napi_status`, please also update +// * `const int last_status` in the definition of `napi_get_last_error_info()' +// in file js_native_api_v8.cc. +// * `const char* error_messages[]` in file js_native_api_v8.cc with a brief +// message explaining the error. +// * the definition of `napi_status` in doc/api/n-api.md to reflect the newly +// added value(s). + +typedef napi_value (*napi_callback)(napi_env env, + napi_callback_info info); +typedef void (*napi_finalize)(napi_env env, + void* finalize_data, + void* finalize_hint); + +typedef struct { + // One of utf8name or name should be NULL. + const char* utf8name; + napi_value name; + + napi_callback method; + napi_callback getter; + napi_callback setter; + napi_value value; + + napi_property_attributes attributes; + void* data; +} napi_property_descriptor; + +typedef struct { + const char* error_message; + void* engine_reserved; + uint32_t engine_error_code; + napi_status error_code; +} napi_extended_error_info; + +#if NAPI_VERSION >= 6 +typedef enum { + napi_key_include_prototypes, + napi_key_own_only +} napi_key_collection_mode; + +typedef enum { + napi_key_all_properties = 0, + napi_key_writable = 1, + napi_key_enumerable = 1 << 1, + napi_key_configurable = 1 << 2, + napi_key_skip_strings = 1 << 3, + napi_key_skip_symbols = 1 << 4 +} napi_key_filter; + +typedef enum { + napi_key_keep_numbers, + napi_key_numbers_to_strings +} napi_key_conversion; +#endif // NAPI_VERSION >= 6 + +#if NAPI_VERSION >= 8 +typedef struct { + uint64_t lower; + uint64_t upper; +} napi_type_tag; +#endif // NAPI_VERSION >= 8 + +#endif // SRC_JS_NATIVE_API_TYPES_H_ diff --git a/sources/node_napi/js_native_api_util.h b/sources/node_napi/js_native_api_util.h new file mode 100644 index 00000000..18d301d7 --- /dev/null +++ b/sources/node_napi/js_native_api_util.h @@ -0,0 +1,829 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +#pragma once + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + + #include "v8.h" + + #include + #include + #include + #include + #include + #include + + #include + #include // std::function + #include + #include + #include + #include + #include + + #ifdef __GNUC__ + #define MUST_USE_RESULT __attribute__((warn_unused_result)) + #else + #define MUST_USE_RESULT + #endif + +namespace nodec { + + // Maybe remove kPathSeparator when cpp17 is ready + #ifdef _WIN32 +constexpr char kPathSeparator = '\\'; + /* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */ + #define PATH_MAX_BYTES (MAX_PATH * 4) + #else +constexpr char kPathSeparator = '/'; + #define PATH_MAX_BYTES (PATH_MAX) + #endif + +// These should be used in our code as opposed to the native +// versions as they abstract out some platform and or +// compiler version specific functionality +// malloc(0) and realloc(ptr, 0) have implementation-defined behavior in +// that the standard allows them to either return a unique pointer or a +// nullptr for zero-sized allocation requests. Normalize by always using +// a nullptr. +template +inline T* UncheckedRealloc(T* pointer, size_t n); +template +inline T* UncheckedMalloc(size_t n); +template +inline T* UncheckedCalloc(size_t n); + +// Same things, but aborts immediately instead of returning nullptr when +// no memory is available. +template +inline T* Realloc(T* pointer, size_t n); +template +inline T* Malloc(size_t n); +template +inline T* Calloc(size_t n); + +inline char* Malloc(size_t n); +inline char* Calloc(size_t n); +inline char* UncheckedMalloc(size_t n); +inline char* UncheckedCalloc(size_t n); + +template +inline T MultiplyWithOverflowCheck(T a, T b); + +namespace per_process { +// Tells whether the per-process V8::Initialize() is called and +// if it is safe to call v8::Isolate::GetCurrent(). +extern bool v8_initialized; +} // namespace per_process + +// Used by the allocation functions when allocation fails. +// Thin wrapper around v8::Isolate::LowMemoryNotification() that checks +// whether V8 is initialized. +void LowMemoryNotification(); + +// The reason that Assert() takes a struct argument instead of individual +// const char*s is to ease instruction cache pressure in calls from CHECK. +struct AssertionInfo { + const char* file_line; // filename:line + const char* message; + const char* function; +}; +[[noreturn]] void Assert(const AssertionInfo& info); +[[noreturn]] void Abort(); +void DumpBacktrace(FILE* fp); + + // Windows 8+ does not like abort() in Release mode + #ifdef _WIN32 + #define ABORT_NO_BACKTRACE() _exit(134) + #else + #define ABORT_NO_BACKTRACE() abort() + #endif + + #define ABORT() nodec::Abort() + + //#define ERROR_AND_ABORT(expr) \ +// do { \ +// /* Make sure that this struct does not end up in inline code, but */ \ +// /* rather in a read-only data section when modifying this code. */ \ +// static const nodec::AssertionInfo args = { \ +// __FILE__ ":" STRINGIFY(__LINE__), #expr, PRETTY_FUNCTION_NAME \ +// }; \ +// nodec::Assert(args); \ +// } while (0) + #define ERROR_AND_ABORT(expr) \ + do { \ + auto r = expr; \ + assert(r); \ + } while (0) + + #ifdef __GNUC__ + #define LIKELY(expr) __builtin_expect(!!(expr), 1) + #define UNLIKELY(expr) __builtin_expect(!!(expr), 0) + #define PRETTY_FUNCTION_NAME __PRETTY_FUNCTION__ + #else + #define LIKELY(expr) expr + #define UNLIKELY(expr) expr + #define PRETTY_FUNCTION_NAME "" + #endif + + #define STRINGIFY_(x) #x + #define STRINGIFY(x) STRINGIFY_(x) + + #define CHECK(expr) \ + do { \ + if (UNLIKELY(!(expr))) { \ + ERROR_AND_ABORT(expr); \ + } \ + } while (0) + + #define CHECK_EQ(a, b) CHECK((a) == (b)) + #define CHECK_GE(a, b) CHECK((a) >= (b)) + #define CHECK_GT(a, b) CHECK((a) > (b)) + #define CHECK_LE(a, b) CHECK((a) <= (b)) + #define CHECK_LT(a, b) CHECK((a) < (b)) + #define CHECK_NE(a, b) CHECK((a) != (b)) + #define CHECK_NULL(val) CHECK((val) == nullptr) + #define CHECK_NOT_NULL(val) CHECK((val) != nullptr) + #define CHECK_IMPLIES(a, b) CHECK(!(a) || (b)) + + #ifdef DEBUG + #define DCHECK(expr) CHECK(expr) + #define DCHECK_EQ(a, b) CHECK((a) == (b)) + #define DCHECK_GE(a, b) CHECK((a) >= (b)) + #define DCHECK_GT(a, b) CHECK((a) > (b)) + #define DCHECK_LE(a, b) CHECK((a) <= (b)) + #define DCHECK_LT(a, b) CHECK((a) < (b)) + #define DCHECK_NE(a, b) CHECK((a) != (b)) + #define DCHECK_NULL(val) CHECK((val) == nullptr) + #define DCHECK_NOT_NULL(val) CHECK((val) != nullptr) + #define DCHECK_IMPLIES(a, b) CHECK(!(a) || (b)) + #else + #define DCHECK(expr) + #define DCHECK_EQ(a, b) + #define DCHECK_GE(a, b) + #define DCHECK_GT(a, b) + #define DCHECK_LE(a, b) + #define DCHECK_LT(a, b) + #define DCHECK_NE(a, b) + #define DCHECK_NULL(val) + #define DCHECK_NOT_NULL(val) + #define DCHECK_IMPLIES(a, b) + #endif + + #define UNREACHABLE(...) \ + ERROR_AND_ABORT("Unreachable code reached" __VA_OPT__(": ") __VA_ARGS__) + +// ECMA262 20.1.2.6 Number.MAX_SAFE_INTEGER (2^53-1) +constexpr int64_t kMaxSafeJsInteger = 9007199254740991; + +inline bool IsSafeJsInt(v8::Local v); + +// TAILQ-style intrusive list node. +template +class ListNode; + +// TAILQ-style intrusive list head. +template (T::*M)> +class ListHead; + +template +class ListNode { +public: + inline ListNode(); + inline ~ListNode(); + inline void Remove(); + inline bool IsEmpty() const; + + ListNode(const ListNode&) = delete; + ListNode& operator=(const ListNode&) = delete; + +private: + template (U::*M)> + friend class ListHead; + friend int GenDebugSymbols(); + ListNode* prev_; + ListNode* next_; +}; + +template (T::*M)> +class ListHead { +public: + class Iterator { + public: + inline T* operator*() const; + inline const Iterator& operator++(); + inline bool operator!=(const Iterator& that) const; + + private: + friend class ListHead; + inline explicit Iterator(ListNode* node); + ListNode* node_; + }; + + inline ListHead() = default; + inline ~ListHead(); + inline void PushBack(T* element); + inline void PushFront(T* element); + inline bool IsEmpty() const; + inline T* PopFront(); + inline Iterator begin() const; + inline Iterator end() const; + + ListHead(const ListHead&) = delete; + ListHead& operator=(const ListHead&) = delete; + +private: + friend int GenDebugSymbols(); + ListNode head_; +}; + +// The helper is for doing safe downcasts from base types to derived types. +template +class ContainerOfHelper { +public: + inline ContainerOfHelper(Inner Outer::*field, Inner* pointer); + template + inline operator TypeName*() const; + +private: + Outer* const pointer_; +}; + +// Calculate the address of the outer (i.e. embedding) struct from +// the interior pointer to a data member. +template +constexpr ContainerOfHelper ContainerOf(Inner Outer::*field, + Inner* pointer); + +// Convenience wrapper around v8::String::NewFromOneByte(). +inline v8::Local OneByteString(v8::Isolate* isolate, + const char* data, + int length = -1); + +// For the people that compile with -funsigned-char. +inline v8::Local OneByteString(v8::Isolate* isolate, + const signed char* data, + int length = -1); + +inline v8::Local OneByteString(v8::Isolate* isolate, + const unsigned char* data, + int length = -1); + +// Used to be a macro, hence the uppercase name. +template +inline v8::Local FIXED_ONE_BYTE_STRING( + v8::Isolate* isolate, + const char (&data)[N]) { + return OneByteString(isolate, data, N - 1); +} + +template +inline v8::Local FIXED_ONE_BYTE_STRING( + v8::Isolate* isolate, + const std::array& arr) { + return OneByteString(isolate, arr.data(), N - 1); +} + +// Swaps bytes in place. nbytes is the number of bytes to swap and must be a +// multiple of the word size (checked by function). +inline void SwapBytes16(char* data, size_t nbytes); +inline void SwapBytes32(char* data, size_t nbytes); +inline void SwapBytes64(char* data, size_t nbytes); + +// tolower() is locale-sensitive. Use ToLower() instead. +inline char ToLower(char c); +inline std::string ToLower(const std::string& in); + +// toupper() is locale-sensitive. Use ToUpper() instead. +inline char ToUpper(char c); +inline std::string ToUpper(const std::string& in); + +// strcasecmp() is locale-sensitive. Use StringEqualNoCase() instead. +inline bool StringEqualNoCase(const char* a, const char* b); + +// strncasecmp() is locale-sensitive. Use StringEqualNoCaseN() instead. +inline bool StringEqualNoCaseN(const char* a, const char* b, size_t length); + +template +constexpr size_t arraysize(const T (&)[N]) { + return N; +} + +template +constexpr size_t strsize(const T (&)[N]) { + return N - 1; +} + +// Allocates an array of member type T. For up to kStackStorageSize items, +// the stack is used, otherwise malloc(). +template +class MaybeStackBuffer { +public: + const T* out() const { + return buf_; + } + + T* out() { + return buf_; + } + + // operator* for compatibility with `v8::String::(Utf8)Value` + T* operator*() { + return buf_; + } + + const T* operator*() const { + return buf_; + } + + T& operator[](size_t index) { + CHECK_LT(index, length()); + return buf_[index]; + } + + const T& operator[](size_t index) const { + CHECK_LT(index, length()); + return buf_[index]; + } + + size_t length() const { + return length_; + } + + // Current maximum capacity of the buffer with which SetLength() can be used + // without first calling AllocateSufficientStorage(). + size_t capacity() const { + return capacity_; + } + + // Make sure enough space for `storage` entries is available. + // This method can be called multiple times throughout the lifetime of the + // buffer, but once this has been called Invalidate() cannot be used. + // Content of the buffer in the range [0, length()) is preserved. + void AllocateSufficientStorage(size_t storage) { + CHECK(!IsInvalidated()); + if (storage > capacity()) { + bool was_allocated = IsAllocated(); + T* allocated_ptr = was_allocated ? buf_ : nullptr; + buf_ = Realloc(allocated_ptr, storage); + capacity_ = storage; + if (!was_allocated && length_ > 0) + memcpy(buf_, buf_st_, length_ * sizeof(buf_[0])); + } + + length_ = storage; + } + + void SetLength(size_t length) { + // capacity() returns how much memory is actually available. + CHECK_LE(length, capacity()); + length_ = length; + } + + void SetLengthAndZeroTerminate(size_t length) { + // capacity() returns how much memory is actually available. + CHECK_LE(length + 1, capacity()); + SetLength(length); + + // T() is 0 for integer types, nullptr for pointers, etc. + buf_[length] = T(); + } + + // Make dereferencing this object return nullptr. + // This method can be called multiple times throughout the lifetime of the + // buffer, but once this has been called AllocateSufficientStorage() cannot + // be used. + void Invalidate() { + CHECK(!IsAllocated()); + capacity_ = 0; + length_ = 0; + buf_ = nullptr; + } + + // If the buffer is stored in the heap rather than on the stack. + bool IsAllocated() const { + return !IsInvalidated() && buf_ != buf_st_; + } + + // If Invalidate() has been called. + bool IsInvalidated() const { + return buf_ == nullptr; + } + + // Release ownership of the malloc'd buffer. + // Note: This does not free the buffer. + void Release() { + CHECK(IsAllocated()); + buf_ = buf_st_; + length_ = 0; + capacity_ = arraysize(buf_st_); + } + + MaybeStackBuffer() + : length_(0), capacity_(arraysize(buf_st_)), buf_(buf_st_) { + // Default to a zero-length, null-terminated buffer. + buf_[0] = T(); + } + + explicit MaybeStackBuffer(size_t storage) : MaybeStackBuffer() { + AllocateSufficientStorage(storage); + } + + ~MaybeStackBuffer() { + if (IsAllocated()) + free(buf_); + } + +private: + size_t length_; + // capacity of the malloc'ed buf_ + size_t capacity_; + T* buf_; + T buf_st_[kStackStorageSize]; +}; + +// Provides access to an ArrayBufferView's storage, either the original, +// or for small data, a copy of it. This object's lifetime is bound to the +// original ArrayBufferView's lifetime. +template +class ArrayBufferViewContents { +public: + ArrayBufferViewContents() = default; + + explicit inline ArrayBufferViewContents(v8::Local value); + explicit inline ArrayBufferViewContents(v8::Local value); + explicit inline ArrayBufferViewContents(v8::Local abv); + inline void Read(v8::Local abv); + + inline const T* data() const { return data_; } + inline size_t length() const { return length_; } + +private: + T stack_storage_[kStackStorageSize]; + T* data_ = nullptr; + size_t length_ = 0; +}; + +class Utf8Value : public MaybeStackBuffer { +public: + explicit Utf8Value(v8::Isolate* isolate, v8::Local value); + + inline std::string ToString() const { return std::string(out(), length()); } + + inline bool operator==(const char* a) const { + return strcmp(out(), a) == 0; + } +}; + +class TwoByteValue : public MaybeStackBuffer { +public: + explicit TwoByteValue(v8::Isolate* isolate, v8::Local value); +}; + +class BufferValue : public MaybeStackBuffer { +public: + explicit BufferValue(v8::Isolate* isolate, v8::Local value); + + inline std::string ToString() const { return std::string(out(), length()); } +}; + + #define SPREAD_BUFFER_ARG(val, name) \ + CHECK((val)->IsArrayBufferView()); \ + v8::Local name = (val).As(); \ + std::shared_ptr name##_bs = \ + name->Buffer()->GetBackingStore(); \ + const size_t name##_offset = name->ByteOffset(); \ + const size_t name##_length = name->ByteLength(); \ + char* const name##_data = \ + static_cast(name##_bs->Data()) + name##_offset; \ + if (name##_length > 0) \ + CHECK_NE(name##_data, nullptr); + +// Use this when a variable or parameter is unused in order to explicitly +// silence a compiler warning about that. +template +inline void USE(T&&) {} + +template +struct OnScopeLeaveImpl { + Fn fn_; + bool active_; + + explicit OnScopeLeaveImpl(Fn&& fn) : fn_(std::move(fn)), active_(true) {} + ~OnScopeLeaveImpl() { + if (active_) fn_(); + } + + OnScopeLeaveImpl(const OnScopeLeaveImpl& other) = delete; + OnScopeLeaveImpl& operator=(const OnScopeLeaveImpl& other) = delete; + OnScopeLeaveImpl(OnScopeLeaveImpl&& other) + : fn_(std::move(other.fn_)), active_(other.active_) { + other.active_ = false; + } + OnScopeLeaveImpl& operator=(OnScopeLeaveImpl&& other) { + if (this == &other) return *this; + this->~OnScopeLeave(); + new (this) OnScopeLeaveImpl(std::move(other)); + return *this; + } +}; + +// Run a function when exiting the current scope. Used like this: +// auto on_scope_leave = OnScopeLeave([&] { +// // ... run some code ... +// }); +template +inline MUST_USE_RESULT OnScopeLeaveImpl OnScopeLeave(Fn&& fn) { + return OnScopeLeaveImpl{std::move(fn)}; +} + +// Simple RAII wrapper for contiguous data that uses malloc()/free(). +template +struct MallocedBuffer { + T* data; + size_t size; + + T* release() { + T* ret = data; + data = nullptr; + return ret; + } + + void Truncate(size_t new_size) { + CHECK(new_size <= size); + size = new_size; + } + + void Realloc(size_t new_size) { + Truncate(new_size); + data = UncheckedRealloc(data, new_size); + } + + inline bool is_empty() const { return data == nullptr; } + + MallocedBuffer() : data(nullptr), size(0) {} + explicit MallocedBuffer(size_t size) : data(Malloc(size)), size(size) {} + MallocedBuffer(T* data, size_t size) : data(data), size(size) {} + MallocedBuffer(MallocedBuffer&& other) : data(other.data), size(other.size) { + other.data = nullptr; + } + MallocedBuffer& operator=(MallocedBuffer&& other) { + this->~MallocedBuffer(); + return *new (this) MallocedBuffer(std::move(other)); + } + ~MallocedBuffer() { + free(data); + } + MallocedBuffer(const MallocedBuffer&) = delete; + MallocedBuffer& operator=(const MallocedBuffer&) = delete; +}; + +template +class NonCopyableMaybe { +public: + NonCopyableMaybe() : empty_(true) {} + explicit NonCopyableMaybe(T&& value) + : empty_(false), + value_(std::move(value)) {} + + bool IsEmpty() const { + return empty_; + } + + const T* get() const { + return empty_ ? nullptr : &value_; + } + + const T* operator->() const { + CHECK(!empty_); + return &value_; + } + + T&& Release() { + CHECK_EQ(empty_, false); + empty_ = true; + return std::move(value_); + } + +private: + bool empty_; + T value_; +}; + +// Test whether some value can be called with (). +template +struct is_callable : std::is_function {}; + +template +struct is_callable::value>::type> : std::true_type {}; + +template +struct FunctionDeleter { + void operator()(T* pointer) const { function(pointer); } + typedef std::unique_ptr Pointer; +}; + +template +using DeleteFnPtr = typename FunctionDeleter::Pointer; + +std::vector SplitString(const std::string& in, char delim); + +inline v8::MaybeLocal ToV8Value(v8::Local context, + const std::string& str, + v8::Isolate* isolate = nullptr); +template ::is_specialized, bool>::type> +inline v8::MaybeLocal ToV8Value(v8::Local context, + const T& number, + v8::Isolate* isolate = nullptr); +template +inline v8::MaybeLocal ToV8Value(v8::Local context, + const std::vector& vec, + v8::Isolate* isolate = nullptr); +template +inline v8::MaybeLocal ToV8Value(v8::Local context, + const std::unordered_map& map, + v8::Isolate* isolate = nullptr); + + // These macros expects a `Isolate* isolate` and a `Local context` + // to be in the scope. + #define READONLY_PROPERTY(obj, name, value) \ + do { \ + obj->DefineOwnProperty( \ + context, FIXED_ONE_BYTE_STRING(isolate, name), value, v8::ReadOnly) \ + .Check(); \ + } while (0) + + #define READONLY_DONT_ENUM_PROPERTY(obj, name, var) \ + do { \ + obj->DefineOwnProperty( \ + context, \ + OneByteString(isolate, name), \ + var, \ + static_cast(v8::ReadOnly | v8::DontEnum)) \ + .Check(); \ + } while (0) + + #define READONLY_FALSE_PROPERTY(obj, name) \ + READONLY_PROPERTY(obj, name, v8::False(isolate)) + + #define READONLY_TRUE_PROPERTY(obj, name) \ + READONLY_PROPERTY(obj, name, v8::True(isolate)) + + #define READONLY_STRING_PROPERTY(obj, name, str) \ + READONLY_PROPERTY(obj, name, ToV8Value(context, str).ToLocalChecked()) + + // Variation on NODE_DEFINE_CONSTANT that sets a String value. + #define NODE_DEFINE_STRING_CONSTANT(target, name, constant) \ + do { \ + v8::Isolate* isolate = target->GetIsolate(); \ + v8::Local constant_name = \ + v8::String::NewFromUtf8(isolate, name).ToLocalChecked(); \ + v8::Local constant_value = \ + v8::String::NewFromUtf8(isolate, constant).ToLocalChecked(); \ + v8::PropertyAttribute constant_attributes = \ + static_cast(v8::ReadOnly | v8::DontDelete); \ + target \ + ->DefineOwnProperty(isolate->GetCurrentContext(), \ + constant_name, \ + constant_value, \ + constant_attributes) \ + .Check(); \ + } while (0) + +enum Endianness { + kLittleEndian, // _Not_ LITTLE_ENDIAN, clashes with endian.h. + kBigEndian +}; + +inline enum Endianness GetEndianness() { + // Constant-folded by the compiler. + const union { + uint8_t u8[2]; + uint16_t u16; + } u = {{1, 0}}; + return u.u16 == 1 ? kLittleEndian : kBigEndian; +} + +inline bool IsLittleEndian() { + return GetEndianness() == kLittleEndian; +} + +inline bool IsBigEndian() { + return GetEndianness() == kBigEndian; +} + +// Round up a to the next highest multiple of b. +template +constexpr T RoundUp(T a, T b) { + return a % b != 0 ? a + b - (a % b) : a; +} + +// Align ptr to an `alignment`-bytes boundary. +template +constexpr T* AlignUp(T* ptr, U alignment) { + return reinterpret_cast( + RoundUp(reinterpret_cast(ptr), alignment)); +} + +class SlicedArguments : public MaybeStackBuffer> { +public: + inline explicit SlicedArguments( + const v8::FunctionCallbackInfo& args, size_t start = 0); +}; + +// Convert a v8::PersistentBase, e.g. v8::Global, to a Local, with an extra +// optimization for strong persistent handles. +class PersistentToLocal { +public: + // If persistent.IsWeak() == false, then do not call persistent.Reset() + // while the returned Local is still in scope, it will destroy the + // reference to the object. + template + static inline v8::Local Default( + v8::Isolate* isolate, + const v8::PersistentBase& persistent) { + if (persistent.IsWeak()) { + return PersistentToLocal::Weak(isolate, persistent); + } else { + return PersistentToLocal::Strong(persistent); + } + } + + // Unchecked conversion from a non-weak Persistent to Local, + // use with care! + // + // Do not call persistent.Reset() while the returned Local is still in + // scope, it will destroy the reference to the object. + template + static inline v8::Local Strong( + const v8::PersistentBase& persistent) { + DCHECK(!persistent.IsWeak()); + return *reinterpret_cast*>( + const_cast*>(&persistent)); + } + + template + static inline v8::Local Weak( + v8::Isolate* isolate, + const v8::PersistentBase& persistent) { + return v8::Local::New(isolate, persistent); + } +}; + +// Can be used as a key for std::unordered_map when lookup performance is more +// important than size and the keys are statically used to avoid redundant hash +// computations. +class FastStringKey { +public: + constexpr explicit FastStringKey(const char* name); + + struct Hash { + constexpr size_t operator()(const FastStringKey& key) const; + }; + constexpr bool operator==(const FastStringKey& other) const; + + constexpr const char* c_str() const; + +private: + static constexpr size_t HashImpl(const char* str); + + const char* name_; + size_t cached_hash_; +}; + +// Like std::static_pointer_cast but for unique_ptr with the default deleter. +template +std::unique_ptr static_unique_pointer_cast(std::unique_ptr&& ptr) { + return std::unique_ptr(static_cast(ptr.release())); +} + + #define MAYBE_FIELD_PTR(ptr, field) ptr == nullptr ? nullptr : &(ptr->field) + +// Returns a non-zero code if it fails to open or read the file, +// aborts if it fails to close the file. +int ReadFileSync(std::string* result, const char* path); +} // namespace nodec + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + diff --git a/sources/node_napi/js_native_api_v8.cc b/sources/node_napi/js_native_api_v8.cc new file mode 100644 index 00000000..a4eaa504 --- /dev/null +++ b/sources/node_napi/js_native_api_v8.cc @@ -0,0 +1,3477 @@ +#include +#include // INT_MAX +#include +#define NAPI_EXPERIMENTAL +#include "js_native_api.h" +#include "js_native_api_v8.h" +//#include "util-inl.h" + +#define CHECK_MAYBE_NOTHING(env, maybe, status) \ + RETURN_STATUS_IF_FALSE((env), !((maybe).IsNothing()), (status)) + +#define CHECK_MAYBE_NOTHING_WITH_PREAMBLE(env, maybe, status) \ + RETURN_STATUS_IF_FALSE_WITH_PREAMBLE((env), !((maybe).IsNothing()), (status)) + +#define CHECK_TO_NUMBER(env, context, result, src) \ + CHECK_TO_TYPE((env), Number, (context), (result), (src), napi_number_expected) + +// n-api defines NAPI_AUTO_LENGHTH as the indicator that a string +// is null terminated. For V8 the equivalent is -1. The assert +// validates that our cast of NAPI_AUTO_LENGTH results in -1 as +// needed by V8. +#define CHECK_NEW_FROM_UTF8_LEN(env, result, str, len) \ + do { \ + static_assert(static_cast(NAPI_AUTO_LENGTH) == -1, \ + "Casting NAPI_AUTO_LENGTH to int must result in -1"); \ + RETURN_STATUS_IF_FALSE((env), \ + (len == NAPI_AUTO_LENGTH) || len <= INT_MAX, \ + napi_invalid_arg); \ + RETURN_STATUS_IF_FALSE((env), \ + (str) != nullptr, \ + napi_invalid_arg); \ + auto str_maybe = v8::String::NewFromUtf8( \ + (env)->isolate, (str), v8::NewStringType::kInternalized, \ + static_cast(len)); \ + CHECK_MAYBE_EMPTY((env), str_maybe, napi_generic_failure); \ + (result) = str_maybe.ToLocalChecked(); \ + } while (0) + +#define CHECK_NEW_FROM_UTF8(env, result, str) \ + CHECK_NEW_FROM_UTF8_LEN((env), (result), (str), NAPI_AUTO_LENGTH) + +#define CREATE_TYPED_ARRAY( \ + env, type, size_of_element, buffer, byte_offset, length, out) \ + do { \ + if ((size_of_element) > 1) { \ + THROW_RANGE_ERROR_IF_FALSE( \ + (env), (byte_offset) % (size_of_element) == 0, \ + "ERR_NAPI_INVALID_TYPEDARRAY_ALIGNMENT", \ + "start offset of " #type " should be a multiple of " #size_of_element); \ + } \ + THROW_RANGE_ERROR_IF_FALSE((env), (length) * (size_of_element) + (byte_offset) <= buffer->ByteLength(), \ + "ERR_NAPI_INVALID_TYPEDARRAY_LENGTH", \ + "Invalid typed array length"); \ + (out) = v8::type::New((buffer), (byte_offset), (length)); \ + } while (0) + +namespace { +enum ContextEmbedderIndex { + kEnvironment = 62, + kEnvironmentTag = 63, +}; +#define PRIVATE_KEY_LIST(V) \ + V(napi_type_tag, "nodec:napi:type_tag") \ + V(napi_wrapper, "nodec:napi:wrapper") + +class PrivateEnv { +public: + PrivateEnv(v8::Local ctx); + +#define V(FIELD_NAME, STRING_VALUE) \ + inline v8::Local FIELD_NAME() { \ + return FIELD_NAME##_.Get(isolate); \ + } + PRIVATE_KEY_LIST(V) +#undef V + + static PrivateEnv* fetch(v8::Local ctx); + +private: + v8::Persistent context; + v8::Isolate* isolate; +#define V(FIELD_NAME, STRING_VALUE) \ + v8::Eternal FIELD_NAME##_; + + PRIVATE_KEY_LIST(V) +#undef V +}; + +PrivateEnv::PrivateEnv(v8::Local ctx) { + isolate = ctx->GetIsolate(); + context.Reset(isolate, ctx); + //context.SetWeak(); +#define V(FIELD, STRING) \ + FIELD##_.Set(isolate, v8::Private::New(isolate, \ + v8::String::NewFromOneByte( \ + isolate, \ + reinterpret_cast(STRING), \ + v8::NewStringType::kInternalized) \ + .ToLocalChecked())); + PRIVATE_KEY_LIST(V) +} + +int gEnvironmentTag = 0; + +PrivateEnv* PrivateEnv::fetch(v8::Local ctx) { + PrivateEnv* env{nullptr}; + //assert(!privateEnvs.empty()); + void* t = ctx->GetAlignedPointerFromEmbedderData(kEnvironmentTag); + void* p = ctx->GetAlignedPointerFromEmbedderData(kEnvironment); + if (t != &gEnvironmentTag) { + auto* e = new PrivateEnv(ctx); + ctx->SetAlignedPointerInEmbedderData(kEnvironment, e); + ctx->SetAlignedPointerInEmbedderData(kEnvironmentTag, &gEnvironmentTag); + env = e; + } else { + env = reinterpret_cast(p); + } + assert(env); + return env; +} + +#define NAPI_PRIVATE_KEY(context, prop) \ + PrivateEnv::fetch(context)->napi_##prop() + +} // namespace + +namespace v8impl { + +namespace { + +inline static napi_status +V8NameFromPropertyDescriptor(napi_env env, + const napi_property_descriptor* p, + v8::Local* result) { + if (p->utf8name != nullptr) { + CHECK_NEW_FROM_UTF8(env, *result, p->utf8name); + } else { + v8::Local property_value = + v8impl::V8LocalValueFromJsValue(p->name); + + RETURN_STATUS_IF_FALSE(env, property_value->IsName(), napi_name_expected); + *result = property_value.As(); + } + + return napi_ok; +} + +// convert from n-api property attributes to v8::PropertyAttribute +inline static v8::PropertyAttribute V8PropertyAttributesFromDescriptor( + const napi_property_descriptor* descriptor) { + unsigned int attribute_flags = v8::PropertyAttribute::None; + + // The napi_writable attribute is ignored for accessor descriptors, but + // V8 would throw `TypeError`s on assignment with nonexistence of a setter. + if ((descriptor->getter == nullptr && descriptor->setter == nullptr) && + (descriptor->attributes & napi_writable) == 0) { + attribute_flags |= v8::PropertyAttribute::ReadOnly; + } + + if ((descriptor->attributes & napi_enumerable) == 0) { + attribute_flags |= v8::PropertyAttribute::DontEnum; + } + if ((descriptor->attributes & napi_configurable) == 0) { + attribute_flags |= v8::PropertyAttribute::DontDelete; + } + + return static_cast(attribute_flags); +} + +inline static napi_deferred +JsDeferredFromNodePersistent(v8impl::Persistent* local) { + return reinterpret_cast(local); +} + +inline static v8impl::Persistent* +NodePersistentFromJsDeferred(napi_deferred local) { + return reinterpret_cast*>(local); +} + +class HandleScopeWrapper { +public: + explicit HandleScopeWrapper(v8::Isolate* isolate) : scope(isolate) {} + +private: + v8::HandleScope scope; +}; + +// In node v0.10 version of v8, there is no EscapableHandleScope and the +// node v0.10 port use HandleScope::Close(Local v) to mimic the behavior +// of a EscapableHandleScope::Escape(Local v), but it is not the same +// semantics. This is an example of where the api abstraction fail to work +// across different versions. +class EscapableHandleScopeWrapper { +public: + explicit EscapableHandleScopeWrapper(v8::Isolate* isolate) + : scope(isolate), escape_called_(false) {} + bool escape_called() const { + return escape_called_; + } + template + v8::Local Escape(v8::Local handle) { + escape_called_ = true; + return scope.Escape(handle); + } + +private: + v8::EscapableHandleScope scope; + bool escape_called_; +}; + +inline static napi_handle_scope +JsHandleScopeFromV8HandleScope(HandleScopeWrapper* s) { + return reinterpret_cast(s); +} + +inline static HandleScopeWrapper* +V8HandleScopeFromJsHandleScope(napi_handle_scope s) { + return reinterpret_cast(s); +} + +inline static napi_escapable_handle_scope +JsEscapableHandleScopeFromV8EscapableHandleScope( + EscapableHandleScopeWrapper* s) { + return reinterpret_cast(s); +} + +inline static EscapableHandleScopeWrapper* +V8EscapableHandleScopeFromJsEscapableHandleScope( + napi_escapable_handle_scope s) { + return reinterpret_cast(s); +} + +inline static napi_status ConcludeDeferred(napi_env env, + napi_deferred deferred, + napi_value result, + bool is_resolved) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, result); + + v8::Local context = env->context(); + v8impl::Persistent* deferred_ref = + NodePersistentFromJsDeferred(deferred); + v8::Local v8_deferred = + v8::Local::New(env->isolate, *deferred_ref); + + auto v8_resolver = v8::Local::Cast(v8_deferred); + + v8::Maybe success = is_resolved ? v8_resolver->Resolve(context, v8impl::V8LocalValueFromJsValue(result)) : v8_resolver->Reject(context, v8impl::V8LocalValueFromJsValue(result)); + + delete deferred_ref; + + RETURN_STATUS_IF_FALSE(env, success.FromMaybe(false), napi_generic_failure); + + return GET_RETURN_STATUS(env); +} + +enum UnwrapAction { + KeepWrap, + RemoveWrap +}; + +inline static napi_status Unwrap(napi_env env, + napi_value js_object, + void** result, + UnwrapAction action) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, js_object); + if (action == KeepWrap) { + CHECK_ARG(env, result); + } + + v8::Local context = env->context(); + + v8::Local value = v8impl::V8LocalValueFromJsValue(js_object); + RETURN_STATUS_IF_FALSE(env, value->IsObject(), napi_invalid_arg); + v8::Local obj = value.As(); + + auto val = obj->GetPrivate(context, NAPI_PRIVATE_KEY(context, wrapper)) + .ToLocalChecked(); + RETURN_STATUS_IF_FALSE(env, val->IsExternal(), napi_invalid_arg); + Reference* reference = + static_cast(val.As()->Value()); + + if (result) { + *result = reference->Data(); + } + + if (action == RemoveWrap) { + CHECK(obj->DeletePrivate(context, NAPI_PRIVATE_KEY(context, wrapper)) + .FromJust()); + Reference::Delete(reference); + } + + return GET_RETURN_STATUS(env); +} + +//=== Function napi_callback wrapper ================================= + +// Use this data structure to associate callback data with each N-API function +// exposed to JavaScript. The structure is stored in a v8::External which gets +// passed into our callback wrapper. This reduces the performance impact of +// calling through N-API. +// Ref: benchmark/misc/function_call +// Discussion (incl. perf. data): https://github.com/nodejs/node/pull/21072 +class CallbackBundle { +public: + // Creates an object to be made available to the static function callback + // wrapper, used to retrieve the native callback function and data pointer. + static inline v8::Local + New(napi_env env, napi_callback cb, void* data) { + CallbackBundle* bundle = new CallbackBundle(); + bundle->cb = cb; + bundle->cb_data = data; + bundle->env = env; + + v8::Local cbdata = v8::External::New(env->isolate, bundle); + Reference::New(env, cbdata, 0, true, Delete, bundle, nullptr); + return cbdata; + } + napi_env env; // Necessary to invoke C++ NAPI callback + void* cb_data; // The user provided callback data + napi_callback cb; + +private: + static void Delete(napi_env env, void* data, void* hint) { + CallbackBundle* bundle = static_cast(data); + delete bundle; + } +}; + +// Base class extended by classes that wrap V8 function and property callback +// info. +class CallbackWrapper { +public: + inline CallbackWrapper(napi_value this_arg, size_t args_length, void* data) + : _this(this_arg), _args_length(args_length), _data(data) {} + + virtual napi_value GetNewTarget() = 0; + virtual void Args(napi_value* buffer, size_t bufferlength) = 0; + virtual void SetReturnValue(napi_value value) = 0; + + napi_value This() { return _this; } + + size_t ArgsLength() { return _args_length; } + + void* Data() { return _data; } + +protected: + const napi_value _this; + const size_t _args_length; + void* _data; +}; + +class CallbackWrapperBase : public CallbackWrapper { +public: + inline CallbackWrapperBase(const v8::FunctionCallbackInfo& cbinfo, + const size_t args_length) + : CallbackWrapper(JsValueFromV8LocalValue(cbinfo.This()), + args_length, + nullptr), + _cbinfo(cbinfo) { + _bundle = reinterpret_cast( + v8::Local::Cast(cbinfo.Data())->Value()); + _data = _bundle->cb_data; + } + +protected: + inline void InvokeCallback() { + napi_callback_info cbinfo_wrapper = reinterpret_cast( + static_cast(this)); + + // All other pointers we need are stored in `_bundle` + napi_env env = _bundle->env; + napi_callback cb = _bundle->cb; + + napi_value result; + env->CallIntoModule([&](napi_env env) { + result = cb(env, cbinfo_wrapper); + }); + + if (result != nullptr) { + this->SetReturnValue(result); + } + } + + const v8::FunctionCallbackInfo& _cbinfo; + CallbackBundle* _bundle; +}; + +class FunctionCallbackWrapper +: public CallbackWrapperBase { +public: + static void Invoke(const v8::FunctionCallbackInfo& info) { + FunctionCallbackWrapper cbwrapper(info); + cbwrapper.InvokeCallback(); + } + + static inline napi_status NewFunction(napi_env env, + napi_callback cb, + void* cb_data, + v8::Local* result) { + v8::Local cbdata = v8impl::CallbackBundle::New(env, cb, cb_data); + RETURN_STATUS_IF_FALSE(env, !cbdata.IsEmpty(), napi_generic_failure); + + v8::MaybeLocal maybe_function = + v8::Function::New(env->context(), Invoke, cbdata); + CHECK_MAYBE_EMPTY(env, maybe_function, napi_generic_failure); + + *result = maybe_function.ToLocalChecked(); + return napi_clear_last_error(env); + } + + static inline napi_status NewTemplate(napi_env env, + napi_callback cb, + void* cb_data, + v8::Local* result, + v8::Local sig = v8::Local()) { + v8::Local cbdata = v8impl::CallbackBundle::New(env, cb, cb_data); + RETURN_STATUS_IF_FALSE(env, !cbdata.IsEmpty(), napi_generic_failure); + + *result = v8::FunctionTemplate::New(env->isolate, Invoke, cbdata, sig); + return napi_clear_last_error(env); + } + + explicit FunctionCallbackWrapper( + const v8::FunctionCallbackInfo& cbinfo) + : CallbackWrapperBase(cbinfo, cbinfo.Length()) {} + + napi_value GetNewTarget() override { + if (_cbinfo.IsConstructCall()) { + return v8impl::JsValueFromV8LocalValue(_cbinfo.NewTarget()); + } else { + return nullptr; + } + } + + /*virtual*/ + void Args(napi_value* buffer, size_t buffer_length) override { + size_t i = 0; + size_t min = std::min(buffer_length, _args_length); + + for (; i < min; i += 1) { + buffer[i] = v8impl::JsValueFromV8LocalValue(_cbinfo[i]); + } + + if (i < buffer_length) { + napi_value undefined = + v8impl::JsValueFromV8LocalValue(v8::Undefined(_cbinfo.GetIsolate())); + for (; i < buffer_length; i += 1) { + buffer[i] = undefined; + } + } + } + + /*virtual*/ + void SetReturnValue(napi_value value) override { + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + _cbinfo.GetReturnValue().Set(val); + } +}; + +enum WrapType { + retrievable, + anonymous +}; + +template +inline napi_status Wrap(napi_env env, + napi_value js_object, + void* native_object, + napi_finalize finalize_cb, + void* finalize_hint, + napi_ref* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, js_object); + + v8::Local context = env->context(); + + v8::Local value = v8impl::V8LocalValueFromJsValue(js_object); + RETURN_STATUS_IF_FALSE(env, value->IsObject(), napi_invalid_arg); + v8::Local obj = value.As(); + + if (wrap_type == retrievable) { + // If we've already wrapped this object, we error out. + RETURN_STATUS_IF_FALSE(env, + !obj->HasPrivate(context, NAPI_PRIVATE_KEY(context, wrapper)) + .FromJust(), + napi_invalid_arg); + } else if (wrap_type == anonymous) { + // If no finalize callback is provided, we error out. + CHECK_ARG(env, finalize_cb); + } + + v8impl::Reference* reference = nullptr; + if (result != nullptr) { + // The returned reference should be deleted via napi_delete_reference() + // ONLY in response to the finalize callback invocation. (If it is deleted + // before then, then the finalize callback will never be invoked.) + // Therefore a finalize callback is required when returning a reference. + CHECK_ARG(env, finalize_cb); + reference = v8impl::Reference::New( + env, obj, 0, false, finalize_cb, native_object, finalize_hint); + *result = reinterpret_cast(reference); + } else { + // Create a self-deleting reference. + reference = v8impl::Reference::New(env, obj, 0, true, finalize_cb, + native_object, finalize_cb == nullptr ? nullptr : finalize_hint); + } + + if (wrap_type == retrievable) { + CHECK(obj->SetPrivate(context, NAPI_PRIVATE_KEY(context, wrapper), + v8::External::New(env->isolate, reference)) + .FromJust()); + } + + return GET_RETURN_STATUS(env); +} + +} // end of anonymous namespace + +// Wrapper around v8impl::Persistent that implements reference counting. +RefBase::RefBase(napi_env env, + uint32_t initial_refcount, + bool delete_self, + napi_finalize finalize_callback, + void* finalize_data, + void* finalize_hint) +: Finalizer(env, finalize_callback, finalize_data, finalize_hint), + _refcount(initial_refcount), + _delete_self(delete_self) { + Link(finalize_callback == nullptr ? &env->reflist : &env->finalizing_reflist); +} + +RefBase* RefBase::New(napi_env env, + uint32_t initial_refcount, + bool delete_self, + napi_finalize finalize_callback, + void* finalize_data, + void* finalize_hint) { + return new RefBase(env, + initial_refcount, + delete_self, + finalize_callback, + finalize_data, + finalize_hint); +} + +RefBase::~RefBase() { + Unlink(); +} + +void* RefBase::Data() { + return _finalize_data; +} + +// Delete is called in 2 ways. Either from the finalizer or +// from one of Unwrap or napi_delete_reference. +// +// When it is called from Unwrap or napi_delete_reference we only +// want to do the delete if the finalizer has already run or +// cannot have been queued to run (ie the reference count is > 0), +// otherwise we may crash when the finalizer does run. +// If the finalizer may have been queued and has not already run +// delay the delete until the finalizer runs by not doing the delete +// and setting _delete_self to true so that the finalizer will +// delete it when it runs. +// +// The second way this is called is from +// the finalizer and _delete_self is set. In this case we +// know we need to do the deletion so just do it. +void RefBase::Delete(RefBase* reference) { + if ((reference->RefCount() != 0) || (reference->_delete_self) || + (reference->_finalize_ran)) { + delete reference; + } else { + // defer until finalizer runs as + // it may already be queued + reference->_delete_self = true; + } +} + +uint32_t RefBase::Ref() { + return ++_refcount; +} + +uint32_t RefBase::Unref() { + if (_refcount == 0) { + return 0; + } + return --_refcount; +} + +uint32_t RefBase::RefCount() { + return _refcount; +} + +void RefBase::Finalize(bool is_env_teardown) { + // In addition to being called during environment teardown, this method is + // also the entry point for the garbage collector. During environment + // teardown we have to remove the garbage collector's reference to this + // method so that, if, as part of the user's callback, JS gets executed, + // resulting in a garbage collection pass, this method is not re-entered as + // part of that pass, because that'll cause a double free (as seen in + // https://github.com/nodejs/node/issues/37236). + // + // Since this class does not have access to the V8 persistent reference, + // this method is overridden in the `Reference` class below. Therein the + // weak callback is removed, ensuring that the garbage collector does not + // re-enter this method, and the method chains up to continue the process of + // environment-teardown-induced finalization. + + // During environment teardown we have to convert a strong reference to + // a weak reference to force the deferring behavior if the user's finalizer + // happens to delete this reference so that the code in this function that + // follows the call to the user's finalizer may safely access variables from + // this instance. + if (is_env_teardown && RefCount() > 0) _refcount = 0; + + if (_finalize_callback != nullptr) { + // This ensures that we never call the finalizer twice. + napi_finalize fini = _finalize_callback; + _finalize_callback = nullptr; + _env->CallFinalizer(fini, _finalize_data, _finalize_hint); + } + + // this is safe because if a request to delete the reference + // is made in the finalize_callback it will defer deletion + // to this block and set _delete_self to true + if (_delete_self || is_env_teardown) { + Delete(this); + } else { + _finalize_ran = true; + } +} + +template +Reference::Reference(napi_env env, v8::Local value, Args&&... args) +: RefBase(env, std::forward(args)...), + _persistent(env->isolate, value), + _secondPassParameter(new SecondPassCallParameterRef(this)), + _secondPassScheduled(false) { + if (RefCount() == 0) { + SetWeak(); + } +} + +Reference* Reference::New(napi_env env, + v8::Local value, + uint32_t initial_refcount, + bool delete_self, + napi_finalize finalize_callback, + void* finalize_data, + void* finalize_hint) { + return new Reference(env, + value, + initial_refcount, + delete_self, + finalize_callback, + finalize_data, + finalize_hint); +} + +Reference::~Reference() { + // If the second pass callback is scheduled, it will delete the + // parameter passed to it, otherwise it will never be scheduled + // and we need to delete it here. + if (!_secondPassScheduled) { + delete _secondPassParameter; + } +} + +uint32_t Reference::Ref() { + uint32_t refcount = RefBase::Ref(); + if (refcount == 1) { + ClearWeak(); + } + return refcount; +} + +uint32_t Reference::Unref() { + uint32_t old_refcount = RefCount(); + uint32_t refcount = RefBase::Unref(); + if (old_refcount == 1 && refcount == 0) { + SetWeak(); + } + return refcount; +} + +v8::Local Reference::Get() { + if (_persistent.IsEmpty()) { + return v8::Local(); + } else { + return v8::Local::New(_env->isolate, _persistent); + } +} + +void Reference::Finalize(bool is_env_teardown) { + if (is_env_teardown) env_teardown_finalize_started_ = true; + if (!is_env_teardown && env_teardown_finalize_started_) return; + + // During env teardown, `~napi_env()` alone is responsible for finalizing. + // Thus, we don't want any stray gc passes to trigger a second call to + // `RefBase::Finalize()`. ClearWeak will ensure that even if the + // gc is in progress no Finalization will be run for this Reference + // by the gc. + if (is_env_teardown) { + ClearWeak(); + } + + // Chain up to perform the rest of the finalization. + RefBase::Finalize(is_env_teardown); +} + +// ClearWeak is marking the Reference so that the gc should not +// collect it, but it is possible that a second pass callback +// may have been scheduled already if we are in shutdown. We clear +// the secondPassParameter so that even if it has been +// scheduled no Finalization will be run. +void Reference::ClearWeak() { + if (!_persistent.IsEmpty()) { + _persistent.ClearWeak(); + } + if (_secondPassParameter != nullptr) { + *_secondPassParameter = nullptr; + } +} + +// Mark the reference as weak and eligible for collection +// by the gc. +void Reference::SetWeak() { + if (_secondPassParameter == nullptr) { + // This means that the Reference has already been processed + // by the second pass callback, so its already been Finalized, do + // nothing + return; + } + _persistent.SetWeak( +#if 1 + _secondPassParameter, FinalizeCallback, v8::WeakCallbackType::kParameter); +#else + _secondPassParameter, FinalizeCallback, v8::WeakCallbackType::kFinalizer); +#endif + *_secondPassParameter = this; +} + +// The N-API finalizer callback may make calls into the engine. V8's heap is +// not in a consistent state during the weak callback, and therefore it does +// not support calls back into it. However, it provides a mechanism for adding +// a finalizer which may make calls back into the engine by allowing us to +// attach such a second-pass finalizer from the first pass finalizer. Thus, +// we do that here to ensure that the N-API finalizer callback is free to call +// into the engine. +void Reference::FinalizeCallback( + const v8::WeakCallbackInfo& data) { + SecondPassCallParameterRef* parameter = data.GetParameter(); + Reference* reference = *parameter; + if (reference == nullptr) { + return; + } + + // The reference must be reset during the first pass. + reference->_persistent.Reset(); + // Mark the parameter not delete-able until the second pass callback is + // invoked. + reference->_secondPassScheduled = true; + + // data.SetSecondPassCallback(SecondPassCallback); + SecondPassCallback(data); +} + +// Second pass callbacks are scheduled with platform tasks. At env teardown, +// the tasks may have already be scheduled and we are unable to cancel the +// second pass callback task. We have to make sure that parameter is kept +// alive until the second pass callback is been invoked. In order to do +// this and still allow our code to Finalize/delete the Reference during +// shutdown we have to use a separately allocated parameter instead +// of a parameter within the Reference object itself. This is what +// is stored in _secondPassParameter and it is allocated in the +// constructor for the Reference. +void Reference::SecondPassCallback( + const v8::WeakCallbackInfo& data) { + SecondPassCallParameterRef* parameter = data.GetParameter(); + Reference* reference = *parameter; + delete parameter; + if (reference == nullptr) { + // the reference itself has already been deleted so nothing to do + return; + } + reference->_secondPassParameter = nullptr; + reference->Finalize(); +} + +} // end of namespace v8impl + +// Warning: Keep in-sync with napi_status enum +static const char* error_messages[] = { + nullptr, + "Invalid argument", + "An object was expected", + "A string was expected", + "A string or symbol was expected", + "A function was expected", + "A number was expected", + "A boolean was expected", + "An array was expected", + "Unknown failure", + "An exception is pending", + "The async work item was cancelled", + "napi_escape_handle already called on scope", + "Invalid handle scope usage", + "Invalid callback scope usage", + "Thread-safe function queue is full", + "Thread-safe function handle is closing", + "A bigint was expected", + "A date was expected", + "An arraybuffer was expected", + "A detachable arraybuffer was expected", + "Main thread would deadlock", +}; + +napi_status napi_get_last_error_info(napi_env env, + const napi_extended_error_info** result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + + // The value of the constant below must be updated to reference the last + // message in the `napi_status` enum each time a new error message is added. + // We don't have a napi_status_last as this would result in an ABI + // change each time a message was added. + const int last_status = napi_would_deadlock; + + static_assert( + NAPI_ARRAYSIZE(error_messages) == last_status + 1, + "Count of error messages must match count of error values"); + CHECK_LE(env->last_error.error_code, last_status); + + // Wait until someone requests the last error information to fetch the error + // message string + env->last_error.error_message = + error_messages[env->last_error.error_code]; + + *result = &(env->last_error); + return napi_ok; +} + +napi_status napi_create_function(napi_env env, + const char* utf8name, + size_t length, + napi_callback cb, + void* callback_data, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, result); + CHECK_ARG(env, cb); + + v8::Local return_value; + v8::EscapableHandleScope scope(env->isolate); + v8::Local fn; + STATUS_CALL(v8impl::FunctionCallbackWrapper::NewFunction( + env, cb, callback_data, &fn)); + return_value = scope.Escape(fn); + + if (utf8name != nullptr) { + v8::Local name_string; + CHECK_NEW_FROM_UTF8_LEN(env, name_string, utf8name, length); + return_value->SetName(name_string); + } + + *result = v8impl::JsValueFromV8LocalValue(return_value); + + return GET_RETURN_STATUS(env); +} + +napi_status napi_define_class(napi_env env, + const char* utf8name, + size_t length, + napi_callback constructor, + void* callback_data, + size_t property_count, + const napi_property_descriptor* properties, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, result); + CHECK_ARG(env, constructor); + + if (property_count > 0) { + CHECK_ARG(env, properties); + } + + v8::Isolate* isolate = env->isolate; + + v8::EscapableHandleScope scope(isolate); + v8::Local tpl; + STATUS_CALL(v8impl::FunctionCallbackWrapper::NewTemplate( + env, constructor, callback_data, &tpl)); + + v8::Local name_string; + CHECK_NEW_FROM_UTF8_LEN(env, name_string, utf8name, length); + tpl->SetClassName(name_string); + + size_t static_property_count = 0; + for (size_t i = 0; i < property_count; i++) { + const napi_property_descriptor* p = properties + i; + + if ((p->attributes & napi_static) != 0) { + // Static properties are handled separately below. + static_property_count++; + continue; + } + + v8::Local property_name; + STATUS_CALL(v8impl::V8NameFromPropertyDescriptor(env, p, &property_name)); + + v8::PropertyAttribute attributes = + v8impl::V8PropertyAttributesFromDescriptor(p); + + // This code is similar to that in napi_define_properties(); the + // difference is it applies to a template instead of an object, + // and preferred PropertyAttribute for lack of PropertyDescriptor + // support on ObjectTemplate. + if (p->getter != nullptr || p->setter != nullptr) { + v8::Local getter_tpl; + v8::Local setter_tpl; + if (p->getter != nullptr) { + STATUS_CALL(v8impl::FunctionCallbackWrapper::NewTemplate( + env, p->getter, p->data, &getter_tpl)); + } + if (p->setter != nullptr) { + STATUS_CALL(v8impl::FunctionCallbackWrapper::NewTemplate( + env, p->setter, p->data, &setter_tpl)); + } + + tpl->PrototypeTemplate()->SetAccessorProperty( + property_name, + getter_tpl, + setter_tpl, + attributes, + v8::AccessControl::DEFAULT); + } else if (p->method != nullptr) { + v8::Local t; + STATUS_CALL(v8impl::FunctionCallbackWrapper::NewTemplate( + env, p->method, p->data, &t, v8::Signature::New(isolate, tpl))); + + tpl->PrototypeTemplate()->Set(property_name, t, attributes); + } else { + v8::Local value = v8impl::V8LocalValueFromJsValue(p->value); + tpl->PrototypeTemplate()->Set(property_name, value, attributes); + } + } + + v8::Local context = env->context(); + *result = v8impl::JsValueFromV8LocalValue( + scope.Escape(tpl->GetFunction(context).ToLocalChecked())); + + if (static_property_count > 0) { + std::vector static_descriptors; + static_descriptors.reserve(static_property_count); + + for (size_t i = 0; i < property_count; i++) { + const napi_property_descriptor* p = properties + i; + if ((p->attributes & napi_static) != 0) { + static_descriptors.push_back(*p); + } + } + + STATUS_CALL(napi_define_properties(env, + *result, + static_descriptors.size(), + static_descriptors.data())); + } + + return GET_RETURN_STATUS(env); +} + +v8::Isolate* napi_env_isolate(napi_env env) { + return env->isolate; +} + +napi_status +napi_define_class_with_parent(napi_env env, + const char* utf8name, + size_t length, + napi_callback constructor, + void* callback_data, + v8::Local& parent_tpl, + size_t property_count, + const napi_property_descriptor* properties, + napi_value* result, + v8::UniquePersistent& result_tpl) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, result); + CHECK_ARG(env, constructor); + + if (property_count > 0) { + CHECK_ARG(env, properties); + } + + v8::Isolate* isolate = env->isolate; + + v8::EscapableHandleScope scope(isolate); + v8::Local tpl; + STATUS_CALL(v8impl::FunctionCallbackWrapper::NewTemplate( + env, constructor, callback_data, &tpl)); + + v8::Local name_string; + CHECK_NEW_FROM_UTF8_LEN(env, name_string, utf8name, length); + tpl->SetClassName(name_string); + + if (!parent_tpl.IsEmpty()) { + tpl->Inherit(parent_tpl); + } + size_t static_property_count = 0; + for (size_t i = 0; i < property_count; i++) { + const napi_property_descriptor* p = properties + i; + + if ((p->attributes & napi_static) != 0) { + // Static properties are handled separately below. + static_property_count++; + continue; + } + + v8::Local property_name; + STATUS_CALL(v8impl::V8NameFromPropertyDescriptor(env, p, &property_name)); + + v8::PropertyAttribute attributes = + v8impl::V8PropertyAttributesFromDescriptor(p); + + // This code is similar to that in napi_define_properties(); the + // difference is it applies to a template instead of an object, + // and preferred PropertyAttribute for lack of PropertyDescriptor + // support on ObjectTemplate. + if (p->getter != nullptr || p->setter != nullptr) { + v8::Local getter_tpl; + v8::Local setter_tpl; + if (p->getter != nullptr) { + STATUS_CALL(v8impl::FunctionCallbackWrapper::NewTemplate( + env, p->getter, p->data, &getter_tpl)); + } + if (p->setter != nullptr) { + STATUS_CALL(v8impl::FunctionCallbackWrapper::NewTemplate( + env, p->setter, p->data, &setter_tpl)); + } + + tpl->PrototypeTemplate()->SetAccessorProperty( + property_name, + getter_tpl, + setter_tpl, + attributes, + v8::AccessControl::DEFAULT); + } else if (p->method != nullptr) { + v8::Local t; + STATUS_CALL(v8impl::FunctionCallbackWrapper::NewTemplate( + env, p->method, p->data, &t, v8::Signature::New(isolate, tpl))); + + tpl->PrototypeTemplate()->Set(property_name, t, attributes); + } else { + v8::Local value = v8impl::V8LocalValueFromJsValue(p->value); + tpl->PrototypeTemplate()->Set(property_name, value, attributes); + } + } + + v8::Local context = env->context(); + *result = v8impl::JsValueFromV8LocalValue( + scope.Escape(tpl->GetFunction(context).ToLocalChecked())); + result_tpl.Reset(env->isolate, tpl); + + if (static_property_count > 0) { + std::vector static_descriptors; + static_descriptors.reserve(static_property_count); + + for (size_t i = 0; i < property_count; i++) { + const napi_property_descriptor* p = properties + i; + if ((p->attributes & napi_static) != 0) { + static_descriptors.push_back(*p); + } + } + + STATUS_CALL(napi_define_properties(env, + *result, + static_descriptors.size(), + static_descriptors.data())); + } + + return GET_RETURN_STATUS(env); +} + +napi_status napi_get_property_names(napi_env env, + napi_value object, + napi_value* result) { + return napi_get_all_property_names( + env, + object, + napi_key_include_prototypes, + static_cast(napi_key_enumerable | + napi_key_skip_symbols), + napi_key_numbers_to_strings, + result); +} + +napi_status napi_get_all_property_names(napi_env env, + napi_value object, + napi_key_collection_mode key_mode, + napi_key_filter key_filter, + napi_key_conversion key_conversion, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, result); + + v8::Local context = env->context(); + v8::Local obj; + CHECK_TO_OBJECT(env, context, obj, object); + + v8::PropertyFilter filter = v8::PropertyFilter::ALL_PROPERTIES; + if (key_filter & napi_key_writable) { + filter = + static_cast(filter | + v8::PropertyFilter::ONLY_WRITABLE); + } + if (key_filter & napi_key_enumerable) { + filter = + static_cast(filter | + v8::PropertyFilter::ONLY_ENUMERABLE); + } + if (key_filter & napi_key_configurable) { + filter = + static_cast(filter | + v8::PropertyFilter::ONLY_WRITABLE); + } + if (key_filter & napi_key_skip_strings) { + filter = + static_cast(filter | + v8::PropertyFilter::SKIP_STRINGS); + } + if (key_filter & napi_key_skip_symbols) { + filter = + static_cast(filter | + v8::PropertyFilter::SKIP_SYMBOLS); + } + v8::KeyCollectionMode collection_mode; + v8::KeyConversionMode conversion_mode; + + switch (key_mode) { + case napi_key_include_prototypes: + collection_mode = v8::KeyCollectionMode::kIncludePrototypes; + break; + case napi_key_own_only: + collection_mode = v8::KeyCollectionMode::kOwnOnly; + break; + default: + return napi_set_last_error(env, napi_invalid_arg); + } + + switch (key_conversion) { + case napi_key_keep_numbers: + conversion_mode = v8::KeyConversionMode::kKeepNumbers; + break; + case napi_key_numbers_to_strings: + conversion_mode = v8::KeyConversionMode::kConvertToString; + break; + default: + return napi_set_last_error(env, napi_invalid_arg); + } + + v8::MaybeLocal maybe_all_propertynames = + obj->GetPropertyNames(context, + collection_mode, + filter, + v8::IndexFilter::kIncludeIndices, + conversion_mode); + + CHECK_MAYBE_EMPTY_WITH_PREAMBLE( + env, maybe_all_propertynames, napi_generic_failure); + + *result = + v8impl::JsValueFromV8LocalValue(maybe_all_propertynames.ToLocalChecked()); + return GET_RETURN_STATUS(env); +} + +napi_status napi_set_property(napi_env env, + napi_value object, + napi_value key, + napi_value value) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, key); + CHECK_ARG(env, value); + + v8::Local context = env->context(); + v8::Local obj; + + CHECK_TO_OBJECT(env, context, obj, object); + + v8::Local k = v8impl::V8LocalValueFromJsValue(key); + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + + v8::Maybe set_maybe = obj->Set(context, k, val); + + RETURN_STATUS_IF_FALSE(env, set_maybe.FromMaybe(false), napi_generic_failure); + return GET_RETURN_STATUS(env); +} + +napi_status napi_has_property(napi_env env, + napi_value object, + napi_value key, + bool* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, result); + CHECK_ARG(env, key); + + v8::Local context = env->context(); + v8::Local obj; + + CHECK_TO_OBJECT(env, context, obj, object); + + v8::Local k = v8impl::V8LocalValueFromJsValue(key); + v8::Maybe has_maybe = obj->Has(context, k); + + CHECK_MAYBE_NOTHING(env, has_maybe, napi_generic_failure); + + *result = has_maybe.FromMaybe(false); + return GET_RETURN_STATUS(env); +} + +napi_status napi_get_property(napi_env env, + napi_value object, + napi_value key, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, key); + CHECK_ARG(env, result); + + v8::Local context = env->context(); + v8::Local k = v8impl::V8LocalValueFromJsValue(key); + v8::Local obj; + + CHECK_TO_OBJECT(env, context, obj, object); + + auto get_maybe = obj->Get(context, k); + + CHECK_MAYBE_EMPTY(env, get_maybe, napi_generic_failure); + + v8::Local val = get_maybe.ToLocalChecked(); + *result = v8impl::JsValueFromV8LocalValue(val); + return GET_RETURN_STATUS(env); +} + +napi_status napi_delete_property(napi_env env, + napi_value object, + napi_value key, + bool* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, key); + + v8::Local context = env->context(); + v8::Local k = v8impl::V8LocalValueFromJsValue(key); + v8::Local obj; + + CHECK_TO_OBJECT(env, context, obj, object); + v8::Maybe delete_maybe = obj->Delete(context, k); + CHECK_MAYBE_NOTHING(env, delete_maybe, napi_generic_failure); + + if (result != nullptr) + *result = delete_maybe.FromMaybe(false); + + return GET_RETURN_STATUS(env); +} + +napi_status napi_has_own_property(napi_env env, + napi_value object, + napi_value key, + bool* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, key); + CHECK_ARG(env, result); + + v8::Local context = env->context(); + v8::Local obj; + + CHECK_TO_OBJECT(env, context, obj, object); + v8::Local k = v8impl::V8LocalValueFromJsValue(key); + RETURN_STATUS_IF_FALSE(env, k->IsName(), napi_name_expected); + v8::Maybe has_maybe = obj->HasOwnProperty(context, k.As()); + CHECK_MAYBE_NOTHING(env, has_maybe, napi_generic_failure); + *result = has_maybe.FromMaybe(false); + + return GET_RETURN_STATUS(env); +} + +napi_status napi_set_named_property(napi_env env, + napi_value object, + const char* utf8name, + napi_value value) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, value); + + v8::Local context = env->context(); + v8::Local obj; + + CHECK_TO_OBJECT(env, context, obj, object); + + v8::Local key; + CHECK_NEW_FROM_UTF8(env, key, utf8name); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + + v8::Maybe set_maybe = obj->Set(context, key, val); + + RETURN_STATUS_IF_FALSE(env, set_maybe.FromMaybe(false), napi_generic_failure); + return GET_RETURN_STATUS(env); +} + +napi_status napi_has_named_property(napi_env env, + napi_value object, + const char* utf8name, + bool* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, result); + + v8::Local context = env->context(); + v8::Local obj; + + CHECK_TO_OBJECT(env, context, obj, object); + + v8::Local key; + CHECK_NEW_FROM_UTF8(env, key, utf8name); + + v8::Maybe has_maybe = obj->Has(context, key); + + CHECK_MAYBE_NOTHING(env, has_maybe, napi_generic_failure); + + *result = has_maybe.FromMaybe(false); + return GET_RETURN_STATUS(env); +} + +napi_status napi_get_named_property(napi_env env, + napi_value object, + const char* utf8name, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, result); + + v8::Local context = env->context(); + + v8::Local key; + CHECK_NEW_FROM_UTF8(env, key, utf8name); + + v8::Local obj; + + CHECK_TO_OBJECT(env, context, obj, object); + + auto get_maybe = obj->Get(context, key); + + CHECK_MAYBE_EMPTY(env, get_maybe, napi_generic_failure); + + v8::Local val = get_maybe.ToLocalChecked(); + *result = v8impl::JsValueFromV8LocalValue(val); + return GET_RETURN_STATUS(env); +} + +napi_status napi_set_element(napi_env env, + napi_value object, + uint32_t index, + napi_value value) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, value); + + v8::Local context = env->context(); + v8::Local obj; + + CHECK_TO_OBJECT(env, context, obj, object); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + auto set_maybe = obj->Set(context, index, val); + + RETURN_STATUS_IF_FALSE(env, set_maybe.FromMaybe(false), napi_generic_failure); + + return GET_RETURN_STATUS(env); +} + +napi_status napi_has_element(napi_env env, + napi_value object, + uint32_t index, + bool* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, result); + + v8::Local context = env->context(); + v8::Local obj; + + CHECK_TO_OBJECT(env, context, obj, object); + + v8::Maybe has_maybe = obj->Has(context, index); + + CHECK_MAYBE_NOTHING(env, has_maybe, napi_generic_failure); + + *result = has_maybe.FromMaybe(false); + return GET_RETURN_STATUS(env); +} + +napi_status napi_get_element(napi_env env, + napi_value object, + uint32_t index, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, result); + + v8::Local context = env->context(); + v8::Local obj; + + CHECK_TO_OBJECT(env, context, obj, object); + + auto get_maybe = obj->Get(context, index); + + CHECK_MAYBE_EMPTY(env, get_maybe, napi_generic_failure); + + *result = v8impl::JsValueFromV8LocalValue(get_maybe.ToLocalChecked()); + return GET_RETURN_STATUS(env); +} + +napi_status napi_delete_element(napi_env env, + napi_value object, + uint32_t index, + bool* result) { + NAPI_PREAMBLE(env); + + v8::Local context = env->context(); + v8::Local obj; + + CHECK_TO_OBJECT(env, context, obj, object); + v8::Maybe delete_maybe = obj->Delete(context, index); + CHECK_MAYBE_NOTHING(env, delete_maybe, napi_generic_failure); + + if (result != nullptr) + *result = delete_maybe.FromMaybe(false); + + return GET_RETURN_STATUS(env); +} + +napi_status napi_define_properties(napi_env env, + napi_value object, + size_t property_count, + const napi_property_descriptor* properties) { + NAPI_PREAMBLE(env); + if (property_count > 0) { + CHECK_ARG(env, properties); + } + + v8::Local context = env->context(); + + v8::Local obj; + CHECK_TO_OBJECT(env, context, obj, object); + + for (size_t i = 0; i < property_count; i++) { + const napi_property_descriptor* p = &properties[i]; + + v8::Local property_name; + STATUS_CALL(v8impl::V8NameFromPropertyDescriptor(env, p, &property_name)); + + if (p->getter != nullptr || p->setter != nullptr) { + v8::Local local_getter; + v8::Local local_setter; + + if (p->getter != nullptr) { + STATUS_CALL(v8impl::FunctionCallbackWrapper::NewFunction( + env, p->getter, p->data, &local_getter)); + } + if (p->setter != nullptr) { + STATUS_CALL(v8impl::FunctionCallbackWrapper::NewFunction( + env, p->setter, p->data, &local_setter)); + } + + v8::PropertyDescriptor descriptor(local_getter, local_setter); + descriptor.set_enumerable((p->attributes & napi_enumerable) != 0); + descriptor.set_configurable((p->attributes & napi_configurable) != 0); + + auto define_maybe = obj->DefineProperty(context, + property_name, + descriptor); + + if (!define_maybe.FromMaybe(false)) { + return napi_set_last_error(env, napi_invalid_arg); + } + } else if (p->method != nullptr) { + v8::Local method; + STATUS_CALL(v8impl::FunctionCallbackWrapper::NewFunction( + env, p->method, p->data, &method)); + v8::PropertyDescriptor descriptor(method, + (p->attributes & napi_writable) != 0); + descriptor.set_enumerable((p->attributes & napi_enumerable) != 0); + descriptor.set_configurable((p->attributes & napi_configurable) != 0); + + auto define_maybe = obj->DefineProperty(context, + property_name, + descriptor); + + if (!define_maybe.FromMaybe(false)) { + return napi_set_last_error(env, napi_generic_failure); + } + } else { + v8::Local value = v8impl::V8LocalValueFromJsValue(p->value); + + v8::PropertyDescriptor descriptor(value, + (p->attributes & napi_writable) != 0); + descriptor.set_enumerable((p->attributes & napi_enumerable) != 0); + descriptor.set_configurable((p->attributes & napi_configurable) != 0); + + auto define_maybe = + obj->DefineProperty(context, property_name, descriptor); + + if (!define_maybe.FromMaybe(false)) { + return napi_set_last_error(env, napi_invalid_arg); + } + } + } + + return GET_RETURN_STATUS(env); +} + +napi_status napi_object_freeze(napi_env env, + napi_value object) { + NAPI_PREAMBLE(env); + + v8::Local context = env->context(); + v8::Local obj; + + CHECK_TO_OBJECT(env, context, obj, object); + + v8::Maybe set_frozen = + obj->SetIntegrityLevel(context, v8::IntegrityLevel::kFrozen); + + RETURN_STATUS_IF_FALSE_WITH_PREAMBLE(env, + set_frozen.FromMaybe(false), napi_generic_failure); + + return GET_RETURN_STATUS(env); +} + +napi_status napi_object_seal(napi_env env, + napi_value object) { + NAPI_PREAMBLE(env); + + v8::Local context = env->context(); + v8::Local obj; + + CHECK_TO_OBJECT(env, context, obj, object); + + v8::Maybe set_sealed = + obj->SetIntegrityLevel(context, v8::IntegrityLevel::kSealed); + + RETURN_STATUS_IF_FALSE_WITH_PREAMBLE(env, + set_sealed.FromMaybe(false), napi_generic_failure); + + return GET_RETURN_STATUS(env); +} + +napi_status napi_is_array(napi_env env, napi_value value, bool* result) { + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + + *result = val->IsArray(); + return napi_clear_last_error(env); +} + +napi_status napi_get_array_length(napi_env env, + napi_value value, + uint32_t* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + RETURN_STATUS_IF_FALSE(env, val->IsArray(), napi_array_expected); + + v8::Local arr = val.As(); + *result = arr->Length(); + + return GET_RETURN_STATUS(env); +} + +napi_status napi_strict_equals(napi_env env, + napi_value lhs, + napi_value rhs, + bool* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, lhs); + CHECK_ARG(env, rhs); + CHECK_ARG(env, result); + + v8::Local a = v8impl::V8LocalValueFromJsValue(lhs); + v8::Local b = v8impl::V8LocalValueFromJsValue(rhs); + + *result = a->StrictEquals(b); + return GET_RETURN_STATUS(env); +} + +napi_status napi_get_prototype(napi_env env, + napi_value object, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, result); + + v8::Local context = env->context(); + + v8::Local obj; + CHECK_TO_OBJECT(env, context, obj, object); + + v8::Local val = obj->GetPrototype(); + *result = v8impl::JsValueFromV8LocalValue(val); + return GET_RETURN_STATUS(env); +} + +napi_status napi_create_object(napi_env env, napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + + *result = v8impl::JsValueFromV8LocalValue( + v8::Object::New(env->isolate)); + + return napi_clear_last_error(env); +} + +napi_status napi_create_array(napi_env env, napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + + *result = v8impl::JsValueFromV8LocalValue( + v8::Array::New(env->isolate)); + + return napi_clear_last_error(env); +} + +napi_status napi_create_array_with_length(napi_env env, + size_t length, + napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + + *result = v8impl::JsValueFromV8LocalValue( + v8::Array::New(env->isolate, length)); + + return napi_clear_last_error(env); +} + +napi_status napi_create_string_latin1(napi_env env, + const char* str, + size_t length, + napi_value* result) { + CHECK_ENV(env); + if (length > 0) + CHECK_ARG(env, str); + CHECK_ARG(env, result); + RETURN_STATUS_IF_FALSE(env, + (length == NAPI_AUTO_LENGTH) || length <= INT_MAX, + napi_invalid_arg); + + auto isolate = env->isolate; + auto str_maybe = + v8::String::NewFromOneByte(isolate, + reinterpret_cast(str), + v8::NewStringType::kNormal, + length); + CHECK_MAYBE_EMPTY(env, str_maybe, napi_generic_failure); + + *result = v8impl::JsValueFromV8LocalValue(str_maybe.ToLocalChecked()); + return napi_clear_last_error(env); +} + +napi_status napi_create_string_utf8(napi_env env, + const char* str, + size_t length, + napi_value* result) { + CHECK_ENV(env); + if (length > 0) + CHECK_ARG(env, str); + CHECK_ARG(env, result); + RETURN_STATUS_IF_FALSE(env, + (length == NAPI_AUTO_LENGTH) || length <= INT_MAX, + napi_invalid_arg); + + auto isolate = env->isolate; + auto str_maybe = + v8::String::NewFromUtf8(isolate, + str, + v8::NewStringType::kNormal, + static_cast(length)); + CHECK_MAYBE_EMPTY(env, str_maybe, napi_generic_failure); + *result = v8impl::JsValueFromV8LocalValue(str_maybe.ToLocalChecked()); + + //TODO: remove later + //if (length != NAPI_AUTO_LENGTH) { + // int newLength = str_maybe.ToLocalChecked()->Utf8Length(env->isolate); + // CHECK_EQ(newLength, length); + //} + + return napi_clear_last_error(env); +} + +napi_status napi_create_string_utf16(napi_env env, + const char16_t* str, + size_t length, + napi_value* result) { + CHECK_ENV(env); + if (length > 0) + CHECK_ARG(env, str); + CHECK_ARG(env, result); + RETURN_STATUS_IF_FALSE(env, + (length == NAPI_AUTO_LENGTH) || length <= INT_MAX, + napi_invalid_arg); + + auto isolate = env->isolate; + auto str_maybe = + v8::String::NewFromTwoByte(isolate, + reinterpret_cast(str), + v8::NewStringType::kNormal, + length); + CHECK_MAYBE_EMPTY(env, str_maybe, napi_generic_failure); + + *result = v8impl::JsValueFromV8LocalValue(str_maybe.ToLocalChecked()); + return napi_clear_last_error(env); +} + +napi_status napi_create_double(napi_env env, + double value, + napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + + *result = v8impl::JsValueFromV8LocalValue( + v8::Number::New(env->isolate, value)); + + return napi_clear_last_error(env); +} + +napi_status napi_create_int32(napi_env env, + int32_t value, + napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + + *result = v8impl::JsValueFromV8LocalValue( + v8::Integer::New(env->isolate, value)); + + return napi_clear_last_error(env); +} + +napi_status napi_create_uint32(napi_env env, + uint32_t value, + napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + + *result = v8impl::JsValueFromV8LocalValue( + v8::Integer::NewFromUnsigned(env->isolate, value)); + + return napi_clear_last_error(env); +} + +napi_status napi_create_int64(napi_env env, + int64_t value, + napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + + *result = v8impl::JsValueFromV8LocalValue( + v8::Number::New(env->isolate, static_cast(value))); + + return napi_clear_last_error(env); +} + +napi_status napi_create_bigint_int64(napi_env env, + int64_t value, + napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + + *result = v8impl::JsValueFromV8LocalValue( + v8::BigInt::New(env->isolate, value)); + + return napi_clear_last_error(env); +} + +napi_status napi_create_bigint_uint64(napi_env env, + uint64_t value, + napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + + *result = v8impl::JsValueFromV8LocalValue( + v8::BigInt::NewFromUnsigned(env->isolate, value)); + + return napi_clear_last_error(env); +} + +napi_status napi_create_bigint_words(napi_env env, + int sign_bit, + size_t word_count, + const uint64_t* words, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, words); + CHECK_ARG(env, result); + + v8::Local context = env->context(); + + RETURN_STATUS_IF_FALSE( + env, word_count <= INT_MAX, napi_invalid_arg); + + v8::MaybeLocal b = v8::BigInt::NewFromWords( + context, sign_bit, word_count, words); + + CHECK_MAYBE_EMPTY_WITH_PREAMBLE(env, b, napi_generic_failure); + + *result = v8impl::JsValueFromV8LocalValue(b.ToLocalChecked()); + return GET_RETURN_STATUS(env); +} + +napi_status napi_get_boolean(napi_env env, bool value, napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + + v8::Isolate* isolate = env->isolate; + + if (value) { + *result = v8impl::JsValueFromV8LocalValue(v8::True(isolate)); + } else { + *result = v8impl::JsValueFromV8LocalValue(v8::False(isolate)); + } + + return napi_clear_last_error(env); +} + +napi_status napi_create_symbol(napi_env env, + napi_value description, + napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + + v8::Isolate* isolate = env->isolate; + + if (description == nullptr) { + *result = v8impl::JsValueFromV8LocalValue(v8::Symbol::New(isolate)); + } else { + v8::Local desc = v8impl::V8LocalValueFromJsValue(description); + RETURN_STATUS_IF_FALSE(env, desc->IsString(), napi_string_expected); + + *result = v8impl::JsValueFromV8LocalValue( + v8::Symbol::New(isolate, desc.As())); + } + + return napi_clear_last_error(env); +} + +static inline napi_status set_error_code(napi_env env, + v8::Local error, + napi_value code, + const char* code_cstring) { + if ((code != nullptr) || (code_cstring != nullptr)) { + v8::Local context = env->context(); + v8::Local err_object = error.As(); + + v8::Local code_value = v8impl::V8LocalValueFromJsValue(code); + if (code != nullptr) { + code_value = v8impl::V8LocalValueFromJsValue(code); + RETURN_STATUS_IF_FALSE(env, code_value->IsString(), napi_string_expected); + } else { + CHECK_NEW_FROM_UTF8(env, code_value, code_cstring); + } + + v8::Local code_key; + CHECK_NEW_FROM_UTF8(env, code_key, "code"); + + v8::Maybe set_maybe = err_object->Set(context, code_key, code_value); + RETURN_STATUS_IF_FALSE(env, + set_maybe.FromMaybe(false), + napi_generic_failure); + } + return napi_ok; +} + +napi_status napi_create_error(napi_env env, + napi_value code, + napi_value msg, + napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, msg); + CHECK_ARG(env, result); + + v8::Local message_value = v8impl::V8LocalValueFromJsValue(msg); + RETURN_STATUS_IF_FALSE(env, message_value->IsString(), napi_string_expected); + + v8::Local error_obj = + v8::Exception::Error(message_value.As()); + STATUS_CALL(set_error_code(env, error_obj, code, nullptr)); + + *result = v8impl::JsValueFromV8LocalValue(error_obj); + + return napi_clear_last_error(env); +} + +napi_status napi_create_type_error(napi_env env, + napi_value code, + napi_value msg, + napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, msg); + CHECK_ARG(env, result); + + v8::Local message_value = v8impl::V8LocalValueFromJsValue(msg); + RETURN_STATUS_IF_FALSE(env, message_value->IsString(), napi_string_expected); + + v8::Local error_obj = + v8::Exception::TypeError(message_value.As()); + STATUS_CALL(set_error_code(env, error_obj, code, nullptr)); + + *result = v8impl::JsValueFromV8LocalValue(error_obj); + + return napi_clear_last_error(env); +} + +napi_status napi_create_range_error(napi_env env, + napi_value code, + napi_value msg, + napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, msg); + CHECK_ARG(env, result); + + v8::Local message_value = v8impl::V8LocalValueFromJsValue(msg); + RETURN_STATUS_IF_FALSE(env, message_value->IsString(), napi_string_expected); + + v8::Local error_obj = + v8::Exception::RangeError(message_value.As()); + STATUS_CALL(set_error_code(env, error_obj, code, nullptr)); + + *result = v8impl::JsValueFromV8LocalValue(error_obj); + + return napi_clear_last_error(env); +} + +napi_status napi_typeof(napi_env env, + napi_value value, + napi_valuetype* result) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Local v = v8impl::V8LocalValueFromJsValue(value); + + if (v->IsNumber()) { + *result = napi_number; + } else if (v->IsBigInt()) { + *result = napi_bigint; + } else if (v->IsString()) { + *result = napi_string; + } else if (v->IsFunction()) { + // This test has to come before IsObject because IsFunction + // implies IsObject + *result = napi_function; + } else if (v->IsExternal()) { + // This test has to come before IsObject because IsExternal + // implies IsObject + *result = napi_external; + } else if (v->IsObject()) { + *result = napi_object; + } else if (v->IsBoolean()) { + *result = napi_boolean; + } else if (v->IsUndefined()) { + *result = napi_undefined; + } else if (v->IsSymbol()) { + *result = napi_symbol; + } else if (v->IsNull()) { + *result = napi_null; + } else { + // Should not get here unless V8 has added some new kind of value. + return napi_set_last_error(env, napi_invalid_arg); + } + + return napi_clear_last_error(env); +} + +napi_status napi_get_undefined(napi_env env, napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + + *result = v8impl::JsValueFromV8LocalValue( + v8::Undefined(env->isolate)); + + return napi_clear_last_error(env); +} + +napi_status napi_get_null(napi_env env, napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + + *result = v8impl::JsValueFromV8LocalValue( + v8::Null(env->isolate)); + + return napi_clear_last_error(env); +} + +// Gets all callback info in a single call. (Ugly, but faster.) +napi_status napi_get_cb_info( + napi_env env, // [in] NAPI environment handle + napi_callback_info cbinfo, // [in] Opaque callback-info handle + size_t* argc, // [in-out] Specifies the size of the provided argv array + // and receives the actual count of args. + napi_value* argv, // [out] Array of values + napi_value* this_arg, // [out] Receives the JS 'this' arg for the call + void** data) { // [out] Receives the data pointer for the callback. + CHECK_ENV(env); + CHECK_ARG(env, cbinfo); + + v8impl::CallbackWrapper* info = + reinterpret_cast(cbinfo); + + if (argv != nullptr) { + CHECK_ARG(env, argc); + info->Args(argv, *argc); + } + if (argc != nullptr) { + *argc = info->ArgsLength(); + } + if (this_arg != nullptr) { + *this_arg = info->This(); + } + if (data != nullptr) { + *data = info->Data(); + } + + return napi_clear_last_error(env); +} + +napi_status napi_get_new_target(napi_env env, + napi_callback_info cbinfo, + napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, cbinfo); + CHECK_ARG(env, result); + + v8impl::CallbackWrapper* info = + reinterpret_cast(cbinfo); + + *result = info->GetNewTarget(); + return napi_clear_last_error(env); +} + +napi_status napi_call_function(napi_env env, + napi_value recv, + napi_value func, + size_t argc, + const napi_value* argv, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, recv); + if (argc > 0) { + CHECK_ARG(env, argv); + } + + v8::Local context = env->context(); + + v8::Local v8recv = v8impl::V8LocalValueFromJsValue(recv); + + v8::Local v8func; + CHECK_TO_FUNCTION(env, v8func, func); + + auto maybe = v8func->Call(context, v8recv, argc, + reinterpret_cast*>(const_cast(argv))); + + if (try_catch.HasCaught()) { + return napi_set_last_error(env, napi_pending_exception); + } else { + if (result != nullptr) { + CHECK_MAYBE_EMPTY(env, maybe, napi_generic_failure); + *result = v8impl::JsValueFromV8LocalValue(maybe.ToLocalChecked()); + } + return napi_clear_last_error(env); + } +} + +napi_status napi_get_global(napi_env env, napi_value* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + + *result = v8impl::JsValueFromV8LocalValue(env->context()->Global()); + + return napi_clear_last_error(env); +} + +napi_status napi_throw(napi_env env, napi_value error) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, error); + + v8::Isolate* isolate = env->isolate; + + isolate->ThrowException(v8impl::V8LocalValueFromJsValue(error)); + // any VM calls after this point and before returning + // to the javascript invoker will fail + return napi_clear_last_error(env); +} + +napi_status napi_throw_error(napi_env env, + const char* code, + const char* msg) { + NAPI_PREAMBLE(env); + + v8::Isolate* isolate = env->isolate; + v8::Local str; + CHECK_NEW_FROM_UTF8(env, str, msg); + + v8::Local error_obj = v8::Exception::Error(str); + STATUS_CALL(set_error_code(env, error_obj, nullptr, code)); + + isolate->ThrowException(error_obj); + // any VM calls after this point and before returning + // to the javascript invoker will fail + return napi_clear_last_error(env); +} + +napi_status napi_throw_type_error(napi_env env, + const char* code, + const char* msg) { + NAPI_PREAMBLE(env); + + v8::Isolate* isolate = env->isolate; + v8::Local str; + CHECK_NEW_FROM_UTF8(env, str, msg); + + v8::Local error_obj = v8::Exception::TypeError(str); + STATUS_CALL(set_error_code(env, error_obj, nullptr, code)); + + isolate->ThrowException(error_obj); + // any VM calls after this point and before returning + // to the javascript invoker will fail + return napi_clear_last_error(env); +} + +napi_status napi_throw_range_error(napi_env env, + const char* code, + const char* msg) { + NAPI_PREAMBLE(env); + + v8::Isolate* isolate = env->isolate; + v8::Local str; + CHECK_NEW_FROM_UTF8(env, str, msg); + + v8::Local error_obj = v8::Exception::RangeError(str); + STATUS_CALL(set_error_code(env, error_obj, nullptr, code)); + + isolate->ThrowException(error_obj); + // any VM calls after this point and before returning + // to the javascript invoker will fail + return napi_clear_last_error(env); +} + +napi_status napi_is_error(napi_env env, napi_value value, bool* result) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot + // throw JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + *result = val->IsNativeError(); + + return napi_clear_last_error(env); +} + +napi_status napi_get_value_double(napi_env env, + napi_value value, + double* result) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + RETURN_STATUS_IF_FALSE(env, val->IsNumber(), napi_number_expected); + + *result = val.As()->Value(); + + return napi_clear_last_error(env); +} + +napi_status napi_get_value_int32(napi_env env, + napi_value value, + int32_t* result) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + + if (val->IsInt32()) { + *result = val.As()->Value(); + } else { + RETURN_STATUS_IF_FALSE(env, val->IsNumber(), napi_number_expected); + + // Empty context: https://github.com/nodejs/node/issues/14379 + v8::Local context; + *result = val->Int32Value(context).FromJust(); + } + + return napi_clear_last_error(env); +} + +napi_status napi_get_value_uint32(napi_env env, + napi_value value, + uint32_t* result) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + + if (val->IsUint32()) { + *result = val.As()->Value(); + } else { + RETURN_STATUS_IF_FALSE(env, val->IsNumber(), napi_number_expected); + + // Empty context: https://github.com/nodejs/node/issues/14379 + v8::Local context; + *result = val->Uint32Value(context).FromJust(); + } + + return napi_clear_last_error(env); +} + +napi_status napi_get_value_int64(napi_env env, + napi_value value, + int64_t* result) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + + // This is still a fast path very likely to be taken. + if (val->IsInt32()) { + *result = val.As()->Value(); + return napi_clear_last_error(env); + } + + RETURN_STATUS_IF_FALSE(env, val->IsNumber(), napi_number_expected); + + // v8::Value::IntegerValue() converts NaN, +Inf, and -Inf to INT64_MIN, + // inconsistent with v8::Value::Int32Value() which converts those values to 0. + // Special-case all non-finite values to match that behavior. + double doubleValue = val.As()->Value(); + if (std::isfinite(doubleValue)) { + // Empty context: https://github.com/nodejs/node/issues/14379 + v8::Local context; + *result = val->IntegerValue(context).FromJust(); + } else { + *result = 0; + } + + return napi_clear_last_error(env); +} + +napi_status napi_get_value_bigint_int64(napi_env env, + napi_value value, + int64_t* result, + bool* lossless) { + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + CHECK_ARG(env, lossless); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + + RETURN_STATUS_IF_FALSE(env, val->IsBigInt(), napi_bigint_expected); + + *result = val.As()->Int64Value(lossless); + + return napi_clear_last_error(env); +} + +napi_status napi_get_value_bigint_uint64(napi_env env, + napi_value value, + uint64_t* result, + bool* lossless) { + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + CHECK_ARG(env, lossless); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + + RETURN_STATUS_IF_FALSE(env, val->IsBigInt(), napi_bigint_expected); + + *result = val.As()->Uint64Value(lossless); + + return napi_clear_last_error(env); +} + +napi_status napi_get_value_bigint_words(napi_env env, + napi_value value, + int* sign_bit, + size_t* word_count, + uint64_t* words) { + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, word_count); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + + RETURN_STATUS_IF_FALSE(env, val->IsBigInt(), napi_bigint_expected); + + v8::Local big = val.As(); + + int word_count_int = *word_count; + + if (sign_bit == nullptr && words == nullptr) { + word_count_int = big->WordCount(); + } else { + CHECK_ARG(env, sign_bit); + CHECK_ARG(env, words); + big->ToWordsArray(sign_bit, &word_count_int, words); + } + + *word_count = word_count_int; + + return napi_clear_last_error(env); +} + +napi_status napi_get_value_bool(napi_env env, napi_value value, bool* result) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + RETURN_STATUS_IF_FALSE(env, val->IsBoolean(), napi_boolean_expected); + + *result = val.As()->Value(); + + return napi_clear_last_error(env); +} + +// Copies a JavaScript string into a LATIN-1 string buffer. The result is the +// number of bytes (excluding the null terminator) copied into buf. +// A sufficient buffer size should be greater than the length of string, +// reserving space for null terminator. +// If bufsize is insufficient, the string will be truncated and null terminated. +// If buf is NULL, this method returns the length of the string (in bytes) +// via the result parameter. +// The result argument is optional unless buf is NULL. +napi_status napi_get_value_string_latin1(napi_env env, + napi_value value, + char* buf, + size_t bufsize, + size_t* result) { + CHECK_ENV(env); + CHECK_ARG(env, value); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + RETURN_STATUS_IF_FALSE(env, val->IsString(), napi_string_expected); + + if (!buf) { + CHECK_ARG(env, result); + *result = val.As()->Length(); + } else if (bufsize != 0) { + int copied = + val.As()->WriteOneByte(env->isolate, + reinterpret_cast(buf), + 0, + bufsize - 1, + v8::String::NO_NULL_TERMINATION); + + buf[copied] = '\0'; + if (result != nullptr) { + *result = copied; + } + } else if (result != nullptr) { + *result = 0; + } + + return napi_clear_last_error(env); +} + +// Copies a JavaScript string into a UTF-8 string buffer. The result is the +// number of bytes (excluding the null terminator) copied into buf. +// A sufficient buffer size should be greater than the length of string, +// reserving space for null terminator. +// If bufsize is insufficient, the string will be truncated and null terminated. +// If buf is NULL, this method returns the length of the string (in bytes) +// via the result parameter. +// The result argument is optional unless buf is NULL. +napi_status napi_get_value_string_utf8(napi_env env, + napi_value value, + char* buf, + size_t bufsize, + size_t* result) { + CHECK_ENV(env); + CHECK_ARG(env, value); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + RETURN_STATUS_IF_FALSE(env, val->IsString(), napi_string_expected); + + if (!buf) { + CHECK_ARG(env, result); + *result = val.As()->Utf8Length(env->isolate); + } else if (bufsize != 0) { + int copied = val.As()->WriteUtf8( + env->isolate, + buf, + bufsize - 1, + nullptr, + v8::String::REPLACE_INVALID_UTF8 | v8::String::NO_NULL_TERMINATION); + + buf[copied] = '\0'; + if (result != nullptr) { + *result = copied; + } + } else if (result != nullptr) { + *result = 0; + } + + return napi_clear_last_error(env); +} + +// Copies a JavaScript string into a UTF-16 string buffer. The result is the +// number of 2-byte code units (excluding the null terminator) copied into buf. +// A sufficient buffer size should be greater than the length of string, +// reserving space for null terminator. +// If bufsize is insufficient, the string will be truncated and null terminated. +// If buf is NULL, this method returns the length of the string (in 2-byte +// code units) via the result parameter. +// The result argument is optional unless buf is NULL. +napi_status napi_get_value_string_utf16(napi_env env, + napi_value value, + char16_t* buf, + size_t bufsize, + size_t* result) { + CHECK_ENV(env); + CHECK_ARG(env, value); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + RETURN_STATUS_IF_FALSE(env, val->IsString(), napi_string_expected); + + if (!buf) { + CHECK_ARG(env, result); + // V8 assumes UTF-16 length is the same as the number of characters. + *result = val.As()->Length(); + } else if (bufsize != 0) { + int copied = val.As()->Write(env->isolate, + reinterpret_cast(buf), + 0, + bufsize - 1, + v8::String::NO_NULL_TERMINATION); + + buf[copied] = '\0'; + if (result != nullptr) { + *result = copied; + } + } else if (result != nullptr) { + *result = 0; + } + + return napi_clear_last_error(env); +} + +napi_status napi_coerce_to_bool(napi_env env, + napi_value value, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Isolate* isolate = env->isolate; + v8::Local b = + v8impl::V8LocalValueFromJsValue(value)->ToBoolean(isolate); + *result = v8impl::JsValueFromV8LocalValue(b); + return GET_RETURN_STATUS(env); +} + +#define GEN_COERCE_FUNCTION(UpperCaseName, MixedCaseName, LowerCaseName) \ + napi_status napi_coerce_to_##LowerCaseName(napi_env env, \ + napi_value value, \ + napi_value* result) { \ + NAPI_PREAMBLE(env); \ + CHECK_ARG(env, value); \ + CHECK_ARG(env, result); \ + \ + v8::Local context = env->context(); \ + v8::Local str; \ + \ + CHECK_TO_##UpperCaseName(env, context, str, value); \ + \ + *result = v8impl::JsValueFromV8LocalValue(str); \ + return GET_RETURN_STATUS(env); \ + } + +GEN_COERCE_FUNCTION(NUMBER, Number, number) +GEN_COERCE_FUNCTION(OBJECT, Object, object) +GEN_COERCE_FUNCTION(STRING, String, string) + +#undef GEN_COERCE_FUNCTION + +napi_status napi_wrap(napi_env env, + napi_value js_object, + void* native_object, + napi_finalize finalize_cb, + void* finalize_hint, + napi_ref* result) { + return v8impl::Wrap(env, + js_object, + native_object, + finalize_cb, + finalize_hint, + result); +} + +napi_status napi_unwrap(napi_env env, napi_value obj, void** result) { + return v8impl::Unwrap(env, obj, result, v8impl::KeepWrap); +} + +napi_status napi_remove_wrap(napi_env env, napi_value obj, void** result) { + return v8impl::Unwrap(env, obj, result, v8impl::RemoveWrap); +} + +napi_status napi_create_external(napi_env env, + void* data, + napi_finalize finalize_cb, + void* finalize_hint, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, result); + + v8::Isolate* isolate = env->isolate; + + v8::Local external_value = v8::External::New(isolate, data); + + // The Reference object will delete itself after invoking the finalizer + // callback. + v8impl::Reference::New(env, + external_value, + 0, + true, + finalize_cb, + data, + finalize_hint); + + *result = v8impl::JsValueFromV8LocalValue(external_value); + + return napi_clear_last_error(env); +} + +NAPI_EXTERN napi_status napi_type_tag_object(napi_env env, + napi_value object, + const napi_type_tag* type_tag) { + NAPI_PREAMBLE(env); + v8::Local context = env->context(); + v8::Local obj; + CHECK_TO_OBJECT_WITH_PREAMBLE(env, context, obj, object); + CHECK_ARG_WITH_PREAMBLE(env, type_tag); + + auto key = NAPI_PRIVATE_KEY(context, type_tag); + auto maybe_has = obj->HasPrivate(context, key); + CHECK_MAYBE_NOTHING_WITH_PREAMBLE(env, maybe_has, napi_generic_failure); + RETURN_STATUS_IF_FALSE_WITH_PREAMBLE(env, + !maybe_has.FromJust(), + napi_invalid_arg); + + auto tag = v8::BigInt::NewFromWords(context, + 0, + 2, + reinterpret_cast(type_tag)); + CHECK_MAYBE_EMPTY_WITH_PREAMBLE(env, tag, napi_generic_failure); + + auto maybe_set = obj->SetPrivate(context, key, tag.ToLocalChecked()); + CHECK_MAYBE_NOTHING_WITH_PREAMBLE(env, maybe_set, napi_generic_failure); + RETURN_STATUS_IF_FALSE_WITH_PREAMBLE(env, + maybe_set.FromJust(), + napi_generic_failure); + + return GET_RETURN_STATUS(env); +} + +NAPI_EXTERN napi_status +napi_check_object_type_tag(napi_env env, + napi_value object, + const napi_type_tag* type_tag, + bool* result) { + NAPI_PREAMBLE(env); + v8::Local context = env->context(); + v8::Local obj; + CHECK_TO_OBJECT_WITH_PREAMBLE(env, context, obj, object); + CHECK_ARG_WITH_PREAMBLE(env, type_tag); + CHECK_ARG_WITH_PREAMBLE(env, result); + + auto maybe_value = obj->GetPrivate(context, + NAPI_PRIVATE_KEY(context, type_tag)); + CHECK_MAYBE_EMPTY_WITH_PREAMBLE(env, maybe_value, napi_generic_failure); + v8::Local val = maybe_value.ToLocalChecked(); + + // We consider the type check to have failed unless we reach the line below + // where we set whether the type check succeeded or not based on the + // comparison of the two type tags. + *result = false; + if (val->IsBigInt()) { + int sign; + int size = 2; + napi_type_tag tag; + val.As()->ToWordsArray(&sign, + &size, + reinterpret_cast(&tag)); + if (size == 2 && sign == 0) + *result = (tag.lower == type_tag->lower && tag.upper == type_tag->upper); + } + + return GET_RETURN_STATUS(env); +} + +napi_status napi_get_value_external(napi_env env, + napi_value value, + void** result) { + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + RETURN_STATUS_IF_FALSE(env, val->IsExternal(), napi_invalid_arg); + + v8::Local external_value = val.As(); + *result = external_value->Value(); + + return napi_clear_last_error(env); +} + +// Set initial_refcount to 0 for a weak reference, >0 for a strong reference. +napi_status napi_create_reference(napi_env env, + napi_value value, + uint32_t initial_refcount, + napi_ref* result) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Local v8_value = v8impl::V8LocalValueFromJsValue(value); + + if (!(v8_value->IsObject() || v8_value->IsFunction())) { + return napi_set_last_error(env, napi_object_expected); + } + + v8impl::Reference* reference = + v8impl::Reference::New(env, v8_value, initial_refcount, false); + + *result = reinterpret_cast(reference); + return napi_clear_last_error(env); +} + +// Deletes a reference. The referenced value is released, and may be GC'd unless +// there are other references to it. +napi_status napi_delete_reference(napi_env env, napi_ref ref) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, ref); + + v8impl::Reference::Delete(reinterpret_cast(ref)); + + return napi_clear_last_error(env); +} + +// Increments the reference count, optionally returning the resulting count. +// After this call the reference will be a strong reference because its +// refcount is >0, and the referenced object is effectively "pinned". +// Calling this when the refcount is 0 and the object is unavailable +// results in an error. +napi_status napi_reference_ref(napi_env env, napi_ref ref, uint32_t* result) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, ref); + + v8impl::Reference* reference = reinterpret_cast(ref); + uint32_t count = reference->Ref(); + + if (result != nullptr) { + *result = count; + } + + return napi_clear_last_error(env); +} + +napi_status napi_reference_count(napi_env env, napi_ref ref, uint32_t* result) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, ref); + + v8impl::Reference* reference = reinterpret_cast(ref); + + if (result != nullptr) { + *result = reference->RefCount(); + } + + return napi_clear_last_error(env); +} + +// Decrements the reference count, optionally returning the resulting count. If +// the result is 0 the reference is now weak and the object may be GC'd at any +// time if there are no other references. Calling this when the refcount is +// already 0 results in an error. +napi_status napi_reference_unref(napi_env env, napi_ref ref, uint32_t* result) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, ref); + + v8impl::Reference* reference = reinterpret_cast(ref); + + if (reference->RefCount() == 0) { + return napi_set_last_error(env, napi_generic_failure); + } + + uint32_t count = reference->Unref(); + + if (result != nullptr) { + *result = count; + } + + return napi_clear_last_error(env); +} + +// Attempts to get a referenced value. If the reference is weak, the value might +// no longer be available, in that case the call is still successful but the +// result is NULL. +napi_status napi_get_reference_value(napi_env env, + napi_ref ref, + napi_value* result) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, ref); + CHECK_ARG(env, result); + + v8impl::Reference* reference = reinterpret_cast(ref); + *result = v8impl::JsValueFromV8LocalValue(reference->Get()); + + return napi_clear_last_error(env); +} + +napi_status napi_open_handle_scope(napi_env env, napi_handle_scope* result) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, result); + + *result = v8impl::JsHandleScopeFromV8HandleScope( + new v8impl::HandleScopeWrapper(env->isolate)); + env->open_handle_scopes++; + return napi_clear_last_error(env); +} + +napi_status napi_close_handle_scope(napi_env env, napi_handle_scope scope) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, scope); + if (env->open_handle_scopes == 0) { + return napi_handle_scope_mismatch; + } + + env->open_handle_scopes--; + delete v8impl::V8HandleScopeFromJsHandleScope(scope); + return napi_clear_last_error(env); +} + +napi_status napi_open_escapable_handle_scope( + napi_env env, + napi_escapable_handle_scope* result) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, result); + + *result = v8impl::JsEscapableHandleScopeFromV8EscapableHandleScope( + new v8impl::EscapableHandleScopeWrapper(env->isolate)); + env->open_handle_scopes++; + return napi_clear_last_error(env); +} + +napi_status napi_close_escapable_handle_scope( + napi_env env, + napi_escapable_handle_scope scope) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, scope); + if (env->open_handle_scopes == 0) { + return napi_handle_scope_mismatch; + } + + delete v8impl::V8EscapableHandleScopeFromJsEscapableHandleScope(scope); + env->open_handle_scopes--; + return napi_clear_last_error(env); +} + +napi_status napi_escape_handle(napi_env env, + napi_escapable_handle_scope scope, + napi_value escapee, + napi_value* result) { + // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, scope); + CHECK_ARG(env, escapee); + CHECK_ARG(env, result); + + v8impl::EscapableHandleScopeWrapper* s = + v8impl::V8EscapableHandleScopeFromJsEscapableHandleScope(scope); + if (!s->escape_called()) { + *result = v8impl::JsValueFromV8LocalValue( + s->Escape(v8impl::V8LocalValueFromJsValue(escapee))); + return napi_clear_last_error(env); + } + return napi_set_last_error(env, napi_escape_called_twice); +} + +napi_status napi_new_instance(napi_env env, + napi_value constructor, + size_t argc, + const napi_value* argv, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, constructor); + if (argc > 0) { + CHECK_ARG(env, argv); + } + CHECK_ARG(env, result); + + v8::Local context = env->context(); + + v8::Local ctor; + CHECK_TO_FUNCTION(env, ctor, constructor); + + auto maybe = ctor->NewInstance(context, argc, + reinterpret_cast*>(const_cast(argv))); + + CHECK_MAYBE_EMPTY(env, maybe, napi_pending_exception); + + *result = v8impl::JsValueFromV8LocalValue(maybe.ToLocalChecked()); + return GET_RETURN_STATUS(env); +} + +napi_status napi_instanceof(napi_env env, + napi_value object, + napi_value constructor, + bool* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, object); + CHECK_ARG(env, result); + + *result = false; + + v8::Local ctor; + v8::Local context = env->context(); + + CHECK_TO_OBJECT(env, context, ctor, constructor); + + if (!ctor->IsFunction()) { + napi_throw_type_error(env, + "ERR_NAPI_CONS_FUNCTION", + "Constructor must be a function"); + + return napi_set_last_error(env, napi_function_expected); + } + + napi_status status = napi_generic_failure; + + v8::Local val = v8impl::V8LocalValueFromJsValue(object); + auto maybe_result = val->InstanceOf(context, ctor); + CHECK_MAYBE_NOTHING(env, maybe_result, status); + *result = maybe_result.FromJust(); + return GET_RETURN_STATUS(env); +} + +// Methods to support catching exceptions +napi_status napi_is_exception_pending(napi_env env, bool* result) { + // NAPI_PREAMBLE is not used here: this function must execute when there is a + // pending exception. + CHECK_ENV(env); + CHECK_ARG(env, result); + + *result = !env->last_exception.IsEmpty(); + return napi_clear_last_error(env); +} + +napi_status napi_get_and_clear_last_exception(napi_env env, + napi_value* result) { + // NAPI_PREAMBLE is not used here: this function must execute when there is a + // pending exception. + CHECK_ENV(env); + CHECK_ARG(env, result); + + if (env->last_exception.IsEmpty()) { + return napi_get_undefined(env, result); + } else { + *result = v8impl::JsValueFromV8LocalValue( + v8::Local::New(env->isolate, env->last_exception)); + env->last_exception.Reset(); + } + + return napi_clear_last_error(env); +} + +napi_status napi_is_arraybuffer(napi_env env, napi_value value, bool* result) { + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + *result = val->IsArrayBuffer(); + + return napi_clear_last_error(env); +} + +napi_status napi_create_arraybuffer(napi_env env, + size_t byte_length, + void** data, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, result); + + v8::Isolate* isolate = env->isolate; + v8::Local buffer = + v8::ArrayBuffer::New(isolate, byte_length); + + // Optionally return a pointer to the buffer's data, to avoid another call to + // retrieve it. + if (data != nullptr) { + *data = buffer->GetBackingStore()->Data(); + } + + *result = v8impl::JsValueFromV8LocalValue(buffer); + return GET_RETURN_STATUS(env); +} + +//napi_status napi_create_external_arraybuffer(napi_env env, +// void* external_data, +// size_t byte_length, +// napi_finalize finalize_cb, +// void* finalize_hint, +// napi_value* result) { +// // The API contract here is that the cleanup function runs on the JS thread, +// // and is able to use napi_env. Implementing that properly is hard, so use the +// // `Buffer` variant for easier implementation. +// napi_value buffer; +// STATUS_CALL(napi_create_external_buffer( +// env, +// byte_length, +// external_data, +// finalize_cb, +// finalize_hint, +// &buffer)); +// return napi_get_typedarray_info( +// env, +// buffer, +// nullptr, +// nullptr, +// nullptr, +// result, +// nullptr); +//} + +napi_status napi_get_arraybuffer_info(napi_env env, + napi_value arraybuffer, + void** data, + size_t* byte_length) { + CHECK_ENV(env); + CHECK_ARG(env, arraybuffer); + + v8::Local value = v8impl::V8LocalValueFromJsValue(arraybuffer); + RETURN_STATUS_IF_FALSE(env, value->IsArrayBuffer(), napi_invalid_arg); + + std::shared_ptr backing_store = + value.As()->GetBackingStore(); + + if (data != nullptr) { + *data = backing_store->Data(); + } + + if (byte_length != nullptr) { + *byte_length = backing_store->ByteLength(); + } + + return napi_clear_last_error(env); +} + +napi_status napi_is_typedarray(napi_env env, napi_value value, bool* result) { + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + *result = val->IsTypedArray(); + + return napi_clear_last_error(env); +} + +napi_status napi_create_typedarray(napi_env env, + napi_typedarray_type type, + size_t length, + napi_value arraybuffer, + size_t byte_offset, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, arraybuffer); + CHECK_ARG(env, result); + + v8::Local value = v8impl::V8LocalValueFromJsValue(arraybuffer); + RETURN_STATUS_IF_FALSE(env, value->IsArrayBuffer(), napi_invalid_arg); + + v8::Local buffer = value.As(); + v8::Local typedArray; + + switch (type) { + case napi_int8_array: + CREATE_TYPED_ARRAY( + env, Int8Array, 1, buffer, byte_offset, length, typedArray); + break; + case napi_uint8_array: + CREATE_TYPED_ARRAY( + env, Uint8Array, 1, buffer, byte_offset, length, typedArray); + break; + case napi_uint8_clamped_array: + CREATE_TYPED_ARRAY( + env, Uint8ClampedArray, 1, buffer, byte_offset, length, typedArray); + break; + case napi_int16_array: + CREATE_TYPED_ARRAY( + env, Int16Array, 2, buffer, byte_offset, length, typedArray); + break; + case napi_uint16_array: + CREATE_TYPED_ARRAY( + env, Uint16Array, 2, buffer, byte_offset, length, typedArray); + break; + case napi_int32_array: + CREATE_TYPED_ARRAY( + env, Int32Array, 4, buffer, byte_offset, length, typedArray); + break; + case napi_uint32_array: + CREATE_TYPED_ARRAY( + env, Uint32Array, 4, buffer, byte_offset, length, typedArray); + break; + case napi_float32_array: + CREATE_TYPED_ARRAY( + env, Float32Array, 4, buffer, byte_offset, length, typedArray); + break; + case napi_float64_array: + CREATE_TYPED_ARRAY( + env, Float64Array, 8, buffer, byte_offset, length, typedArray); + break; + case napi_bigint64_array: + CREATE_TYPED_ARRAY( + env, BigInt64Array, 8, buffer, byte_offset, length, typedArray); + break; + case napi_biguint64_array: + CREATE_TYPED_ARRAY( + env, BigUint64Array, 8, buffer, byte_offset, length, typedArray); + break; + default: + return napi_set_last_error(env, napi_invalid_arg); + } + + *result = v8impl::JsValueFromV8LocalValue(typedArray); + return GET_RETURN_STATUS(env); +} + +napi_status napi_get_typedarray_info(napi_env env, + napi_value typedarray, + napi_typedarray_type* type, + size_t* length, + void** data, + napi_value* arraybuffer, + size_t* byte_offset) { + CHECK_ENV(env); + CHECK_ARG(env, typedarray); + + v8::Local value = v8impl::V8LocalValueFromJsValue(typedarray); + RETURN_STATUS_IF_FALSE(env, value->IsTypedArray(), napi_invalid_arg); + + v8::Local array = value.As(); + + if (type != nullptr) { + if (value->IsInt8Array()) { + *type = napi_int8_array; + } else if (value->IsUint8Array()) { + *type = napi_uint8_array; + } else if (value->IsUint8ClampedArray()) { + *type = napi_uint8_clamped_array; + } else if (value->IsInt16Array()) { + *type = napi_int16_array; + } else if (value->IsUint16Array()) { + *type = napi_uint16_array; + } else if (value->IsInt32Array()) { + *type = napi_int32_array; + } else if (value->IsUint32Array()) { + *type = napi_uint32_array; + } else if (value->IsFloat32Array()) { + *type = napi_float32_array; + } else if (value->IsFloat64Array()) { + *type = napi_float64_array; + } else if (value->IsBigInt64Array()) { + *type = napi_bigint64_array; + } else if (value->IsBigUint64Array()) { + *type = napi_biguint64_array; + } + } + + if (length != nullptr) { + *length = array->Length(); + } + + v8::Local buffer; + if (data != nullptr || arraybuffer != nullptr) { + // Calling Buffer() may have the side effect of allocating the buffer, + // so only do this when it’s needed. + buffer = array->Buffer(); + } + + if (data != nullptr) { + *data = static_cast(buffer->GetBackingStore()->Data()) + + array->ByteOffset(); + } + + if (arraybuffer != nullptr) { + *arraybuffer = v8impl::JsValueFromV8LocalValue(buffer); + } + + if (byte_offset != nullptr) { + *byte_offset = array->ByteOffset(); + } + + return napi_clear_last_error(env); +} + +napi_status napi_create_dataview(napi_env env, + size_t byte_length, + napi_value arraybuffer, + size_t byte_offset, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, arraybuffer); + CHECK_ARG(env, result); + + v8::Local value = v8impl::V8LocalValueFromJsValue(arraybuffer); + RETURN_STATUS_IF_FALSE(env, value->IsArrayBuffer(), napi_invalid_arg); + + v8::Local buffer = value.As(); + if (byte_length + byte_offset > buffer->ByteLength()) { + napi_throw_range_error( + env, + "ERR_NAPI_INVALID_DATAVIEW_ARGS", + "byte_offset + byte_length should be less than or " + "equal to the size in bytes of the array passed in"); + return napi_set_last_error(env, napi_pending_exception); + } + v8::Local DataView = v8::DataView::New(buffer, byte_offset, + byte_length); + + *result = v8impl::JsValueFromV8LocalValue(DataView); + return GET_RETURN_STATUS(env); +} + +napi_status napi_is_dataview(napi_env env, napi_value value, bool* result) { + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + *result = val->IsDataView(); + + return napi_clear_last_error(env); +} + +napi_status napi_get_dataview_info(napi_env env, + napi_value dataview, + size_t* byte_length, + void** data, + napi_value* arraybuffer, + size_t* byte_offset) { + CHECK_ENV(env); + CHECK_ARG(env, dataview); + + v8::Local value = v8impl::V8LocalValueFromJsValue(dataview); + RETURN_STATUS_IF_FALSE(env, value->IsDataView(), napi_invalid_arg); + + v8::Local array = value.As(); + + if (byte_length != nullptr) { + *byte_length = array->ByteLength(); + } + + v8::Local buffer; + if (data != nullptr || arraybuffer != nullptr) { + // Calling Buffer() may have the side effect of allocating the buffer, + // so only do this when it’s needed. + buffer = array->Buffer(); + } + + if (data != nullptr) { + *data = static_cast(buffer->GetBackingStore()->Data()) + + array->ByteOffset(); + } + + if (arraybuffer != nullptr) { + *arraybuffer = v8impl::JsValueFromV8LocalValue(buffer); + } + + if (byte_offset != nullptr) { + *byte_offset = array->ByteOffset(); + } + + return napi_clear_last_error(env); +} + +napi_status napi_get_version(napi_env env, uint32_t* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + *result = NAPI_VERSION; + return napi_clear_last_error(env); +} + +napi_status napi_create_promise(napi_env env, + napi_deferred* deferred, + napi_value* promise) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, deferred); + CHECK_ARG(env, promise); + + auto maybe = v8::Promise::Resolver::New(env->context()); + CHECK_MAYBE_EMPTY(env, maybe, napi_generic_failure); + + auto v8_resolver = maybe.ToLocalChecked(); + auto v8_deferred = new v8impl::Persistent(); + v8_deferred->Reset(env->isolate, v8_resolver); + + *deferred = v8impl::JsDeferredFromNodePersistent(v8_deferred); + *promise = v8impl::JsValueFromV8LocalValue(v8_resolver->GetPromise()); + return GET_RETURN_STATUS(env); +} + +napi_status napi_resolve_deferred(napi_env env, + napi_deferred deferred, + napi_value resolution) { + return v8impl::ConcludeDeferred(env, deferred, resolution, true); +} + +napi_status napi_reject_deferred(napi_env env, + napi_deferred deferred, + napi_value resolution) { + return v8impl::ConcludeDeferred(env, deferred, resolution, false); +} + +napi_status napi_is_promise(napi_env env, + napi_value value, + bool* is_promise) { + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, is_promise); + + *is_promise = v8impl::V8LocalValueFromJsValue(value)->IsPromise(); + + return napi_clear_last_error(env); +} + +napi_status napi_create_date(napi_env env, + double time, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, result); + + v8::MaybeLocal maybe_date = v8::Date::New(env->context(), time); + CHECK_MAYBE_EMPTY(env, maybe_date, napi_generic_failure); + + *result = v8impl::JsValueFromV8LocalValue(maybe_date.ToLocalChecked()); + + return GET_RETURN_STATUS(env); +} + +napi_status napi_is_date(napi_env env, + napi_value value, + bool* is_date) { + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, is_date); + + *is_date = v8impl::V8LocalValueFromJsValue(value)->IsDate(); + + return napi_clear_last_error(env); +} + +napi_status napi_get_date_value(napi_env env, + napi_value value, + double* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + RETURN_STATUS_IF_FALSE(env, val->IsDate(), napi_date_expected); + + v8::Local date = val.As(); + *result = date->ValueOf(); + + return GET_RETURN_STATUS(env); +} + +napi_status napi_run_script(napi_env env, + napi_value script, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, script); + CHECK_ARG(env, result); + + v8::Local v8_script = v8impl::V8LocalValueFromJsValue(script); + + if (!v8_script->IsString()) { + return napi_set_last_error(env, napi_string_expected); + } + + v8::Local context = env->context(); + + auto maybe_script = v8::Script::Compile(context, + v8::Local::Cast(v8_script)); + CHECK_MAYBE_EMPTY(env, maybe_script, napi_generic_failure); + + auto script_result = + maybe_script.ToLocalChecked()->Run(context); + CHECK_MAYBE_EMPTY(env, script_result, napi_generic_failure); + + *result = v8impl::JsValueFromV8LocalValue(script_result.ToLocalChecked()); + return GET_RETURN_STATUS(env); +} + +napi_status napi_run_script_with_filename(napi_env env, + napi_value script, + const char* filename, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, script); + CHECK_ARG(env, result); + + v8::Local v8_script = v8impl::V8LocalValueFromJsValue(script); + + if (!v8_script->IsString()) { + return napi_set_last_error(env, napi_string_expected); + } + + v8::Local context = env->context(); + v8::MaybeLocal originStr = v8::String::NewFromUtf8(env->isolate, filename == nullptr ? "(no filename)" : filename, v8::NewStringType::kNormal); + if (originStr.IsEmpty()) { + return napi_invalid_arg; + } + v8::ScriptOrigin origin(env->isolate, originStr.ToLocalChecked()); + + auto maybe_script = v8::Script::Compile(context, + v8::Local::Cast(v8_script), + &origin); + CHECK_MAYBE_EMPTY(env, maybe_script, napi_generic_failure); + + auto script_result = + maybe_script.ToLocalChecked()->Run(context); + CHECK_MAYBE_EMPTY(env, script_result, napi_generic_failure); + + *result = v8impl::JsValueFromV8LocalValue(script_result.ToLocalChecked()); + return GET_RETURN_STATUS(env); +} + +napi_status napi_add_finalizer(napi_env env, + napi_value js_object, + void* native_object, + napi_finalize finalize_cb, + void* finalize_hint, + napi_ref* result) { + return v8impl::Wrap(env, + js_object, + native_object, + finalize_cb, + finalize_hint, + result); +} + +napi_status napi_adjust_external_memory(napi_env env, + int64_t change_in_bytes, + int64_t* adjusted_value) { + CHECK_ENV(env); + CHECK_ARG(env, adjusted_value); + + *adjusted_value = env->isolate->AdjustAmountOfExternalAllocatedMemory( + change_in_bytes); + + return napi_clear_last_error(env); +} + +napi_status napi_set_instance_data(napi_env env, + void* data, + napi_finalize finalize_cb, + void* finalize_hint) { + CHECK_ENV(env); + + v8impl::RefBase* old_data = static_cast(env->instance_data); + if (old_data != nullptr) { + // Our contract so far has been to not finalize any old data there may be. + // So we simply delete it. + v8impl::RefBase::Delete(old_data); + } + + env->instance_data = v8impl::RefBase::New(env, + 0, + true, + finalize_cb, + data, + finalize_hint); + + return napi_clear_last_error(env); +} + +napi_status napi_get_instance_data(napi_env env, + void** data) { + CHECK_ENV(env); + CHECK_ARG(env, data); + + v8impl::RefBase* idata = static_cast(env->instance_data); + + *data = (idata == nullptr ? nullptr : idata->Data()); + + return napi_clear_last_error(env); +} + +napi_status napi_detach_arraybuffer(napi_env env, napi_value arraybuffer) { + CHECK_ENV(env); + CHECK_ARG(env, arraybuffer); + + v8::Local value = v8impl::V8LocalValueFromJsValue(arraybuffer); + RETURN_STATUS_IF_FALSE( + env, value->IsArrayBuffer(), napi_arraybuffer_expected); + + v8::Local it = value.As(); + RETURN_STATUS_IF_FALSE( + env, it->IsDetachable(), napi_detachable_arraybuffer_expected); + + it->Detach(); + + return napi_clear_last_error(env); +} + +napi_status napi_is_detached_arraybuffer(napi_env env, + napi_value arraybuffer, + bool* result) { + CHECK_ENV(env); + CHECK_ARG(env, arraybuffer); + CHECK_ARG(env, result); + + v8::Local value = v8impl::V8LocalValueFromJsValue(arraybuffer); + + *result = value->IsArrayBuffer() && + value.As()->GetBackingStore()->Data() == nullptr; + + return napi_clear_last_error(env); +} diff --git a/sources/node_napi/js_native_api_v8.h b/sources/node_napi/js_native_api_v8.h new file mode 100644 index 00000000..db3230b7 --- /dev/null +++ b/sources/node_napi/js_native_api_v8.h @@ -0,0 +1,453 @@ +#ifndef SRC_JS_NATIVE_API_V8_H_ +#define SRC_JS_NATIVE_API_V8_H_ + +// This file needs to be compatible with C compilers. +#include // NOLINT(modernize-deprecated-headers) +#include "js_native_api_util.h" +#include "js_native_api_types.h" +#include "js_native_api_v8_internals.h" + +static napi_status napi_clear_last_error(napi_env env); + +namespace v8impl { + +class RefTracker { + public: + RefTracker() {} + virtual ~RefTracker() {} + virtual void Finalize(bool isEnvTeardown) {} + + typedef RefTracker RefList; + + inline void Link(RefList* list) { + prev_ = list; + next_ = list->next_; + if (next_ != nullptr) { + next_->prev_ = this; + } + list->next_ = this; + } + + inline void Unlink() { + if (prev_ != nullptr) { + prev_->next_ = next_; + } + if (next_ != nullptr) { + next_->prev_ = prev_; + } + prev_ = nullptr; + next_ = nullptr; + } + + static void FinalizeAll(RefList* list) { + while (list->next_ != nullptr) { + list->next_->Finalize(true); + } + } + + private: + RefList* next_ = nullptr; + RefList* prev_ = nullptr; +}; + +} // end of namespace v8impl + +struct napi_env__ { + explicit napi_env__(v8::Local context) + : isolate(context->GetIsolate()), + context_persistent(isolate, context) { + CHECK_EQ(isolate, context->GetIsolate()); + } + virtual ~napi_env__() { + // First we must finalize those references that have `napi_finalizer` + // callbacks. The reason is that addons might store other references which + // they delete during their `napi_finalizer` callbacks. If we deleted such + // references here first, they would be doubly deleted when the + // `napi_finalizer` deleted them subsequently. + v8impl::RefTracker::FinalizeAll(&finalizing_reflist); + v8impl::RefTracker::FinalizeAll(&reflist); + } + v8::Isolate* const isolate; // Shortcut for context()->GetIsolate() + v8impl::Persistent context_persistent; + + inline v8::Local context() const { + return v8impl::PersistentToLocal::Strong(context_persistent); + } + + inline void Ref() { refs++; } + inline void Unref() { if ( --refs == 0) delete this; } + + virtual bool can_call_into_js() const { return true; } + virtual v8::Maybe mark_arraybuffer_as_untransferable( + v8::Local ab) const { + return v8::Just(true); + } + + static inline void + HandleThrow(napi_env env, v8::Local value) { + env->isolate->ThrowException(value); + } + + template + inline void CallIntoModule(T&& call, U&& handle_exception = HandleThrow) { + int open_handle_scopes_before = open_handle_scopes; + int open_callback_scopes_before = open_callback_scopes; + napi_clear_last_error(this); + call(this); + CHECK_EQ(open_handle_scopes, open_handle_scopes_before); + CHECK_EQ(open_callback_scopes, open_callback_scopes_before); + if (!last_exception.IsEmpty()) { + handle_exception(this, last_exception.Get(this->isolate)); + last_exception.Reset(); + } + } + + virtual void CallFinalizer(napi_finalize cb, void* data, void* hint) { + v8::HandleScope handle_scope(isolate); + CallIntoModule([&](napi_env env) { + cb(env, data, hint); + }); + } + + v8impl::Persistent last_exception; + + // We store references in two different lists, depending on whether they have + // `napi_finalizer` callbacks, because we must first finalize the ones that + // have such a callback. See `~napi_env__()` above for details. + v8impl::RefTracker::RefList reflist; + v8impl::RefTracker::RefList finalizing_reflist; + napi_extended_error_info last_error; + int open_handle_scopes = 0; + int open_callback_scopes = 0; + int refs = 1; + void* instance_data = nullptr; +}; + +// This class is used to keep a napi_env live in a way that +// is exception safe versus calling Ref/Unref directly +class EnvRefHolder { + public: + explicit EnvRefHolder(napi_env env) : _env(env) { + _env->Ref(); + } + + explicit EnvRefHolder(const EnvRefHolder& other): _env(other.env()) { + _env->Ref(); + } + + EnvRefHolder(EnvRefHolder&& other) { + _env = other._env; + other._env = nullptr; + } + + ~EnvRefHolder() { + if (_env != nullptr) { + _env->Unref(); + } + } + + napi_env env(void) const { + return _env; + } + + private: + napi_env _env; +}; + +static inline napi_status napi_clear_last_error(napi_env env) { + env->last_error.error_code = napi_ok; + + // TODO(boingoing): Should this be a callback? + env->last_error.engine_error_code = 0; + env->last_error.engine_reserved = nullptr; + return napi_ok; +} + +static inline +napi_status napi_set_last_error(napi_env env, napi_status error_code, + uint32_t engine_error_code = 0, + void* engine_reserved = nullptr) { + env->last_error.error_code = error_code; + env->last_error.engine_error_code = engine_error_code; + env->last_error.engine_reserved = engine_reserved; + return error_code; +} + +#define RETURN_STATUS_IF_FALSE(env, condition, status) \ + do { \ + if (!(condition)) { \ + return napi_set_last_error((env), (status)); \ + } \ + } while (0) + +#define RETURN_STATUS_IF_FALSE_WITH_PREAMBLE(env, condition, status) \ + do { \ + if (!(condition)) { \ + return napi_set_last_error( \ + (env), try_catch.HasCaught() ? napi_pending_exception : (status)); \ + } \ + } while (0) + +#define CHECK_ENV(env) \ + do { \ + if ((env) == nullptr) { \ + return napi_invalid_arg; \ + } \ + } while (0) + +#define CHECK_ARG(env, arg) \ + RETURN_STATUS_IF_FALSE((env), ((arg) != nullptr), napi_invalid_arg) + +#define CHECK_ARG_WITH_PREAMBLE(env, arg) \ + RETURN_STATUS_IF_FALSE_WITH_PREAMBLE((env), \ + ((arg) != nullptr), \ + napi_invalid_arg) + +#define CHECK_MAYBE_EMPTY(env, maybe, status) \ + RETURN_STATUS_IF_FALSE((env), !((maybe).IsEmpty()), (status)) + +#define CHECK_MAYBE_EMPTY_WITH_PREAMBLE(env, maybe, status) \ + RETURN_STATUS_IF_FALSE_WITH_PREAMBLE((env), !((maybe).IsEmpty()), (status)) + +// NAPI_PREAMBLE is not wrapped in do..while: try_catch must have function scope +#define NAPI_PREAMBLE(env) \ + CHECK_ENV((env)); \ + RETURN_STATUS_IF_FALSE((env), \ + (env)->last_exception.IsEmpty() && (env)->can_call_into_js(), \ + napi_pending_exception); \ + napi_clear_last_error((env)); \ + v8impl::TryCatch try_catch((env)) + +#define CHECK_TO_TYPE(env, type, context, result, src, status) \ + do { \ + CHECK_ARG((env), (src)); \ + auto maybe = v8impl::V8LocalValueFromJsValue((src))->To##type((context)); \ + CHECK_MAYBE_EMPTY((env), maybe, (status)); \ + (result) = maybe.ToLocalChecked(); \ + } while (0) + +#define CHECK_TO_TYPE_WITH_PREAMBLE(env, type, context, result, src, status) \ + do { \ + CHECK_ARG_WITH_PREAMBLE((env), (src)); \ + auto maybe = v8impl::V8LocalValueFromJsValue((src))->To##type((context)); \ + CHECK_MAYBE_EMPTY_WITH_PREAMBLE((env), maybe, (status)); \ + (result) = maybe.ToLocalChecked(); \ + } while (0) + +#define CHECK_TO_FUNCTION(env, result, src) \ + do { \ + CHECK_ARG((env), (src)); \ + v8::Local v8value = v8impl::V8LocalValueFromJsValue((src)); \ + RETURN_STATUS_IF_FALSE((env), v8value->IsFunction(), napi_invalid_arg); \ + (result) = v8value.As(); \ + } while (0) + +#define CHECK_TO_OBJECT(env, context, result, src) \ + CHECK_TO_TYPE((env), Object, (context), (result), (src), napi_object_expected) + +#define CHECK_TO_OBJECT_WITH_PREAMBLE(env, context, result, src) \ + CHECK_TO_TYPE_WITH_PREAMBLE((env), \ + Object, \ + (context), \ + (result), \ + (src), \ + napi_object_expected) + +#define CHECK_TO_STRING(env, context, result, src) \ + CHECK_TO_TYPE((env), String, (context), (result), (src), napi_string_expected) + +#define GET_RETURN_STATUS(env) \ + (!try_catch.HasCaught() ? napi_ok \ + : napi_set_last_error((env), napi_pending_exception)) + +#define THROW_RANGE_ERROR_IF_FALSE(env, condition, error, message) \ + do { \ + if (!(condition)) { \ + napi_throw_range_error((env), (error), (message)); \ + return napi_set_last_error((env), napi_generic_failure); \ + } \ + } while (0) + +#define RETURN_STATUS_IF_FALSE_WITH_PREAMBLE(env, condition, status) \ + do { \ + if (!(condition)) { \ + return napi_set_last_error( \ + (env), try_catch.HasCaught() ? napi_pending_exception : (status)); \ + } \ + } while (0) + +#define CHECK_MAYBE_EMPTY_WITH_PREAMBLE(env, maybe, status) \ + RETURN_STATUS_IF_FALSE_WITH_PREAMBLE((env), !((maybe).IsEmpty()), (status)) + +namespace v8impl { + +//=== Conversion between V8 Handles and napi_value ======================== + +// This asserts v8::Local<> will always be implemented with a single +// pointer field so that we can pass it around as a void*. +static_assert(sizeof(v8::Local) == sizeof(napi_value), + "Cannot convert between v8::Local and napi_value"); + +inline napi_value JsValueFromV8LocalValue(v8::Local local) { + return reinterpret_cast(*local); +} + +inline v8::Local V8LocalValueFromJsValue(napi_value v) { + v8::Local local; + memcpy(static_cast(&local), &v, sizeof(v)); + return local; +} + +// Adapter for napi_finalize callbacks. +class Finalizer { + public: + // Some Finalizers are run during shutdown when the napi_env is destroyed, + // and some need to keep an explicit reference to the napi_env because they + // are run independently. + enum EnvReferenceMode { + kNoEnvReference, + kKeepEnvReference + }; + + protected: + Finalizer(napi_env env, + napi_finalize finalize_callback, + void* finalize_data, + void* finalize_hint, + EnvReferenceMode refmode = kNoEnvReference) + : _env(env), + _finalize_callback(finalize_callback), + _finalize_data(finalize_data), + _finalize_hint(finalize_hint), + _has_env_reference(refmode == kKeepEnvReference) { + if (_has_env_reference) + _env->Ref(); + } + + ~Finalizer() { + if (_has_env_reference) + _env->Unref(); + } + + public: + static Finalizer* New(napi_env env, + napi_finalize finalize_callback = nullptr, + void* finalize_data = nullptr, + void* finalize_hint = nullptr, + EnvReferenceMode refmode = kNoEnvReference) { + return new Finalizer( + env, finalize_callback, finalize_data, finalize_hint, refmode); + } + + static void Delete(Finalizer* finalizer) { + delete finalizer; + } + + protected: + napi_env _env; + napi_finalize _finalize_callback; + void* _finalize_data; + void* _finalize_hint; + bool _finalize_ran = false; + bool _has_env_reference = false; +}; + +class TryCatch : public v8::TryCatch { + public: + explicit TryCatch(napi_env env) + : v8::TryCatch(env->isolate), _env(env) {} + + ~TryCatch() { + if (HasCaught()) { + _env->last_exception.Reset(_env->isolate, Exception()); + } + } + + private: + napi_env _env; +}; + +// Wrapper around v8impl::Persistent that implements reference counting. +class RefBase : protected Finalizer, RefTracker { + protected: + RefBase(napi_env env, + uint32_t initial_refcount, + bool delete_self, + napi_finalize finalize_callback, + void* finalize_data, + void* finalize_hint); + + public: + static RefBase* New(napi_env env, + uint32_t initial_refcount, + bool delete_self, + napi_finalize finalize_callback, + void* finalize_data, + void* finalize_hint); + + static inline void Delete(RefBase* reference); + + virtual ~RefBase(); + void* Data(); + uint32_t Ref(); + uint32_t Unref(); + uint32_t RefCount(); + + protected: + void Finalize(bool is_env_teardown = false) override; + + private: + uint32_t _refcount; + bool _delete_self; +}; + +class Reference : public RefBase { + using SecondPassCallParameterRef = Reference*; + + protected: + template + Reference(napi_env env, v8::Local value, Args&&... args); + + public: + static Reference* New(napi_env env, + v8::Local value, + uint32_t initial_refcount, + bool delete_self, + napi_finalize finalize_callback = nullptr, + void* finalize_data = nullptr, + void* finalize_hint = nullptr); + + virtual ~Reference(); + uint32_t Ref(); + uint32_t Unref(); + v8::Local Get(); + + protected: + void Finalize(bool is_env_teardown = false) override; + + private: + void ClearWeak(); + void SetWeak(); + + static void FinalizeCallback( + const v8::WeakCallbackInfo& data); + static void SecondPassCallback( + const v8::WeakCallbackInfo& data); + + bool env_teardown_finalize_started_ = false; + v8impl::Persistent _persistent; + SecondPassCallParameterRef* _secondPassParameter; + bool _secondPassScheduled; + + //FRIEND_TEST(JsNativeApiV8Test, Reference); +}; + +} // end of namespace v8impl + +#define STATUS_CALL(call) \ + do { \ + napi_status status = (call); \ + if (status != napi_ok) return status; \ + } while (0) + +#endif // SRC_JS_NATIVE_API_V8_H_ diff --git a/sources/node_napi/js_native_api_v8_internals.h b/sources/node_napi/js_native_api_v8_internals.h new file mode 100644 index 00000000..7410a5f8 --- /dev/null +++ b/sources/node_napi/js_native_api_v8_internals.h @@ -0,0 +1,43 @@ +#ifndef SRC_JS_NATIVE_API_V8_INTERNALS_H_ +#define SRC_JS_NATIVE_API_V8_INTERNALS_H_ + +// The V8 implementation of N-API, including `js_native_api_v8.h` uses certain +// idioms which require definition here. For example, it uses a variant of +// persistent references which need not be reset in the constructor. It is the +// responsibility of this file to define these idioms. Optionally, this file +// may also define `NAPI_VERSION` and set it to the version of N-API to be +// exposed. + +// In the case of the Node.js implementation of N-API some of the idioms are +// imported directly from Node.js by including `node_internals.h` below. Others +// are bridged to remove references to the `node` namespace. `node_version.h`, +// included below, defines `NAPI_VERSION`. + +#define NODE_MODULE_VERSION 93 +// The NAPI_VERSION provided by this version of the runtime. This is the version +// which the Node binary being built supports. +//#include "node_version.h" +//#include "env.h" +//#include "node_internals.h" +//#include "gtest/gtest_prod.h" +#include "js_native_api_util.h" + +#define NAPI_ARRAYSIZE(array) \ + nodec::arraysize((array)) + +//#define NAPI_FIXED_ONE_BYTE_STRING(isolate, string) \ +// nodec::FIXED_ONE_BYTE_STRING((isolate), (string)) + +//#define NAPI_PRIVATE_KEY(context, suffix) \ +// (nodec::Environment::GetCurrent((context))->napi_ ## suffix()) + +namespace v8impl { + +template +using Persistent = v8::Global; + +using PersistentToLocal = nodec::PersistentToLocal; + +} // end of namespace v8impl + +#endif // SRC_JS_NATIVE_API_V8_INTERNALS_H_ diff --git a/win32/CMakeLists.txt b/win32/CMakeLists.txt index 39efe5ed..3d43a9d9 100644 --- a/win32/CMakeLists.txt +++ b/win32/CMakeLists.txt @@ -1,275 +1,275 @@ -add_library(dbgcore SHARED IMPORTED GLOBAL) - -set_target_properties(dbgcore PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/dbgcore.dll -) - -add_library(dbghelp SHARED IMPORTED GLOBAL) - -set_target_properties(dbghelp PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/dbghelp.dll -) - -add_library(dbgeng SHARED IMPORTED GLOBAL) - -set_target_properties(dbgeng PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/dbgeng.dll -) - -add_library(freetype STATIC IMPORTED GLOBAL) - -set_target_properties(freetype PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/freetype.lib -) - -add_library(glew32 SHARED IMPORTED GLOBAL) - -set_target_properties(glew32 PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glew32.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/glew32.lib -) - -add_library(iconv SHARED IMPORTED GLOBAL) - -set_target_properties(iconv PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/iconv.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libiconv.lib -) - - -add_library(crypto STATIC IMPORTED GLOBAL) - -set_target_properties(crypto PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcrypto.lib - #IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libcrypto.lib - #IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcrypto-1_1.dll -) - - -add_library(curl SHARED IMPORTED GLOBAL) - -set_target_properties(curl PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcurl.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libcurl.lib -) - -add_library(jpeg STATIC IMPORTED GLOBAL) - -set_target_properties(jpeg PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libjpeg.lib -) - -add_library(mpg123 SHARED IMPORTED GLOBAL) - -set_target_properties(mpg123 PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libmpg123.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libmpg123.lib -) - -add_library(ogg SHARED IMPORTED GLOBAL) - -set_target_properties(ogg PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libogg.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libogg.lib -) - -add_library(png SHARED IMPORTED GLOBAL) - -set_target_properties(png PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libpng16.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libpng16.lib -) - - -add_library(ssl STATIC IMPORTED GLOBAL) - -set_target_properties(ssl PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libssl.lib - #IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libssl-1_1.dll -) - -add_library(uv STATIC IMPORTED GLOBAL) - -set_target_properties(uv PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libuv.lib - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/uv -) - - -add_library(vorbis SHARED IMPORTED GLOBAL) - -set_target_properties(vorbis PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libvorbis.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libvorbis.lib -) - -add_library(vorbisfile SHARED IMPORTED GLOBAL) - -set_target_properties(vorbisfile PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libvorbisfile.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libvorbisfile.lib -) - -add_library(webp STATIC IMPORTED GLOBAL) - -set_target_properties(webp PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libwebp.lib -) - -add_library(zlib STATIC IMPORTED GLOBAL) - -set_target_properties(zlib PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libzlib.lib - #IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/zlib1.dll - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/zlib -) - -add_library(websockets SHARED IMPORTED GLOBAL) - -set_target_properties(websockets PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/websockets.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/websockets.lib -) - - -add_library(OpenAL32 SHARED IMPORTED GLOBAL) - -set_target_properties(OpenAL32 PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/OpenAL32.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/OpenAL32.lib - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/OpenalSoft -) - -add_library(sqlite3 SHARED IMPORTED GLOBAL) - -set_target_properties(sqlite3 PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/sqlite3.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/sqlite3.lib -) - - -add_library(SDL2 SHARED IMPORTED GLOBAL) -set_target_properties(SDL2 PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/SDL2.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/SDL2.lib -) - -add_library(SDL2Main SHARED IMPORTED GLOBAL) -set_target_properties(SDL2Main PROPERTIES - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/SDL2Main.lib -) - -add_library(tcmalloc SHARED IMPORTED GLOBAL) -set_target_properties(tcmalloc PROPERTIES - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libtcmalloc_minimal.lib -) - -set(se_libs_name) - -if(USE_SE_V8) - - add_library(v8 SHARED IMPORTED GLOBAL) - set_target_properties(v8 PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/v8.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/v8.dll.lib - ) - - add_library(v8_libbase SHARED IMPORTED GLOBAL) - set_target_properties(v8_libbase PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/v8_libbase.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/v8_libbase.dll.lib - ) - - add_library(v8_libplatform SHARED IMPORTED GLOBAL) - set_target_properties(v8_libplatform PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/v8_libplatform.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/v8_libplatform.dll.lib - ) - - target_link_libraries(v8 INTERFACE v8_libbase v8_libplatform) - - set_target_properties(v8 PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/v8 - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/v8 - ) - - set(se_libs_name v8) -else() - message(FATAL_ERROR "Only V8 is supported!") -endif() - -############################# glslang ############################# - -set(glslang_libs_name glslang glslang-default-resource-limits MachineIndependent OGLCompiler OSDependent SPIRV SPIRV-Tools-opt SPIRV-Tools GenericCodeGen) -foreach(gl IN LISTS glslang_libs_name) - add_library(${gl} STATIC IMPORTED GLOBAL) - set_target_properties(${gl} PROPERTIES - IMPORTED_LOCATION_DEBUG ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/${gl}d.lib - IMPORTED_LOCATION_RELEASE ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/${gl}.lib - ) -endforeach() - -############################# TBB ############################# - -add_library(tbb SHARED IMPORTED GLOBAL) -set_target_properties(tbb PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/tbb.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/tbb.lib -) -set(tbb_libs_name tbb) - -list(APPEND CC_EXTERNAL_PRIVATE_DEFINITIONS __TBB_LIB_NAME=tbb) - -######################## PhysX ############################## - -if(USE_PHYSICS_PHYSX) - set(PhysXSDK PhysX PhysXCommon PhysXFoundation PhysXExtensions PhysXCooking PhysXCharacterKinematic PhysXVehicle PhysXPvdSDK) - foreach(PX IN LISTS PhysXSDK) - add_library(${PX} STATIC IMPORTED GLOBAL) - set_target_properties(${PX} PROPERTIES - IMPORTED_LOCATION_DEBUG ${CMAKE_CURRENT_LIST_DIR}/libs/PhysX/debug/${PX}_static_32.lib - IMPORTED_LOCATION_RELEASE ${CMAKE_CURRENT_LIST_DIR}/libs/PhysX/release/${PX}_static_32.lib - ) - endforeach() -else() - set(PhysXSDK) -endif() - -list(APPEND CC_EXTERNAL_LIBS - freetype - glew32 - iconv - crypto - curl - jpeg - mpg123 - ogg - png - ssl - uv - vorbis - vorbisfile - webp - OpenAL32 - sqlite3 - websockets - SDL2 - SDL2Main - tcmalloc - ${glslang_libs_name} - ${tbb_libs_name} - ${PhysXSDK} -) - - -set(ZLIB zlib) -if(NOT USE_MODULES) - list(APPEND CC_EXTERNAL_LIBS ${ZLIB} - ${se_libs_name} - ) -endif() - - -list(APPEND CC_EXTERNAL_INCLUDES - ${CMAKE_CURRENT_LIST_DIR}/include -) +add_library(dbgcore SHARED IMPORTED GLOBAL) + +set_target_properties(dbgcore PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/dbgcore.dll +) + +add_library(dbghelp SHARED IMPORTED GLOBAL) + +set_target_properties(dbghelp PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/dbghelp.dll +) + +add_library(dbgeng SHARED IMPORTED GLOBAL) + +set_target_properties(dbgeng PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/dbgeng.dll +) + +add_library(freetype STATIC IMPORTED GLOBAL) + +set_target_properties(freetype PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/freetype.lib +) + +add_library(glew32 SHARED IMPORTED GLOBAL) + +set_target_properties(glew32 PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glew32.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/glew32.lib +) + +add_library(iconv SHARED IMPORTED GLOBAL) + +set_target_properties(iconv PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/iconv.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libiconv.lib +) + + +add_library(crypto STATIC IMPORTED GLOBAL) + +set_target_properties(crypto PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcrypto.lib + #IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libcrypto.lib + #IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcrypto-1_1.dll +) + + +add_library(curl SHARED IMPORTED GLOBAL) + +set_target_properties(curl PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcurl.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libcurl.lib +) + +add_library(jpeg STATIC IMPORTED GLOBAL) + +set_target_properties(jpeg PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libjpeg.lib +) + +add_library(mpg123 SHARED IMPORTED GLOBAL) + +set_target_properties(mpg123 PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libmpg123.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libmpg123.lib +) + +add_library(ogg SHARED IMPORTED GLOBAL) + +set_target_properties(ogg PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libogg.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libogg.lib +) + +add_library(png SHARED IMPORTED GLOBAL) + +set_target_properties(png PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libpng16.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libpng16.lib +) + + +add_library(ssl STATIC IMPORTED GLOBAL) + +set_target_properties(ssl PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libssl.lib + #IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libssl-1_1.dll +) + +add_library(uv STATIC IMPORTED GLOBAL) + +set_target_properties(uv PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libuv.lib + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/uv +) + + +add_library(vorbis SHARED IMPORTED GLOBAL) + +set_target_properties(vorbis PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libvorbis.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libvorbis.lib +) + +add_library(vorbisfile SHARED IMPORTED GLOBAL) + +set_target_properties(vorbisfile PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libvorbisfile.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libvorbisfile.lib +) + +add_library(webp STATIC IMPORTED GLOBAL) + +set_target_properties(webp PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libwebp.lib +) + +add_library(zlib STATIC IMPORTED GLOBAL) + +set_target_properties(zlib PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libzlib.lib + #IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/zlib1.dll + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/zlib +) + +add_library(websockets SHARED IMPORTED GLOBAL) + +set_target_properties(websockets PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/websockets.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/websockets.lib +) + + +add_library(OpenAL32 SHARED IMPORTED GLOBAL) + +set_target_properties(OpenAL32 PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/OpenAL32.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/OpenAL32.lib + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/OpenalSoft +) + +add_library(sqlite3 SHARED IMPORTED GLOBAL) + +set_target_properties(sqlite3 PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/sqlite3.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/sqlite3.lib +) + + +add_library(SDL2 SHARED IMPORTED GLOBAL) +set_target_properties(SDL2 PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/SDL2.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/SDL2.lib +) + +add_library(SDL2Main SHARED IMPORTED GLOBAL) +set_target_properties(SDL2Main PROPERTIES + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/SDL2Main.lib +) + +add_library(tcmalloc SHARED IMPORTED GLOBAL) +set_target_properties(tcmalloc PROPERTIES + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libtcmalloc_minimal.lib +) + +set(se_libs_name) + +if(USE_SE_V8) + + add_library(v8 SHARED IMPORTED GLOBAL) + set_target_properties(v8 PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/v8.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/v8.dll.lib + ) + + add_library(v8_libbase SHARED IMPORTED GLOBAL) + set_target_properties(v8_libbase PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/v8_libbase.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/v8_libbase.dll.lib + ) + + add_library(v8_libplatform SHARED IMPORTED GLOBAL) + set_target_properties(v8_libplatform PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/v8_libplatform.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/v8_libplatform.dll.lib + ) + + target_link_libraries(v8 INTERFACE v8_libbase v8_libplatform) + + set_target_properties(v8 PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/v8 + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/v8 + ) + + set(se_libs_name v8) +else() + message(FATAL_ERROR "Only V8 is supported!") +endif() + +############################# glslang ############################# + +set(glslang_libs_name glslang glslang-default-resource-limits MachineIndependent OGLCompiler OSDependent SPIRV SPIRV-Tools-opt SPIRV-Tools GenericCodeGen) +foreach(gl IN LISTS glslang_libs_name) + add_library(${gl} STATIC IMPORTED GLOBAL) + set_target_properties(${gl} PROPERTIES + IMPORTED_LOCATION_DEBUG ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/${gl}d.lib + IMPORTED_LOCATION_RELEASE ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/${gl}.lib + ) +endforeach() + +############################# TBB ############################# + +add_library(tbb SHARED IMPORTED GLOBAL) +set_target_properties(tbb PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/tbb.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/tbb.lib +) +set(tbb_libs_name tbb) + +list(APPEND CC_EXTERNAL_PRIVATE_DEFINITIONS __TBB_LIB_NAME=tbb) + +######################## PhysX ############################## + +if(USE_PHYSICS_PHYSX) + set(PhysXSDK PhysX PhysXCommon PhysXFoundation PhysXExtensions PhysXCooking PhysXCharacterKinematic PhysXVehicle PhysXPvdSDK) + foreach(PX IN LISTS PhysXSDK) + add_library(${PX} STATIC IMPORTED GLOBAL) + set_target_properties(${PX} PROPERTIES + IMPORTED_LOCATION_DEBUG ${CMAKE_CURRENT_LIST_DIR}/libs/PhysX/debug/${PX}_static_32.lib + IMPORTED_LOCATION_RELEASE ${CMAKE_CURRENT_LIST_DIR}/libs/PhysX/release/${PX}_static_32.lib + ) + endforeach() +else() + set(PhysXSDK) +endif() + +list(APPEND CC_EXTERNAL_LIBS + freetype + glew32 + iconv + crypto + curl + jpeg + mpg123 + ogg + png + ssl + uv + vorbis + vorbisfile + webp + OpenAL32 + sqlite3 + websockets + SDL2 + SDL2Main + tcmalloc + ${glslang_libs_name} + ${tbb_libs_name} + ${PhysXSDK} +) + + +set(ZLIB zlib) +if(NOT USE_MODULES) + list(APPEND CC_EXTERNAL_LIBS ${ZLIB} + ${se_libs_name} + ) +endif() + + +list(APPEND CC_EXTERNAL_INCLUDES + ${CMAKE_CURRENT_LIST_DIR}/include +) diff --git a/win64/CMakeLists.txt b/win64/CMakeLists.txt index 0d585d9e..5e29aeeb 100644 --- a/win64/CMakeLists.txt +++ b/win64/CMakeLists.txt @@ -1,273 +1,273 @@ -add_library(dbgcore SHARED IMPORTED GLOBAL) - -set_target_properties(dbgcore PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/dbgcore.dll -) - -add_library(dbghelp SHARED IMPORTED GLOBAL) - -set_target_properties(dbghelp PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/dbghelp.dll -) - -add_library(dbgeng SHARED IMPORTED GLOBAL) - -set_target_properties(dbgeng PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/dbgeng.dll -) - -add_library(freetype STATIC IMPORTED GLOBAL) - -set_target_properties(freetype PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/freetype.lib -) - -add_library(glew32 SHARED IMPORTED GLOBAL) - -set_target_properties(glew32 PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glew32.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/glew32.lib -) - -add_library(iconv SHARED IMPORTED GLOBAL) - -set_target_properties(iconv PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/iconv-2.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/iconv.lib - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/charset-1.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/charset.lib -) - - -add_library(crypto STATIC IMPORTED GLOBAL) - -set_target_properties(crypto PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcrypto.lib -) - - -add_library(curl SHARED IMPORTED GLOBAL) - -set_target_properties(curl PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcurl.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libcurl.lib -) - -add_library(jpeg STATIC IMPORTED GLOBAL) - -set_target_properties(jpeg PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/jpeg.lib -) - -add_library(mpg123 SHARED IMPORTED GLOBAL) - -set_target_properties(mpg123 PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libmpg123-0.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libmpg123-0.lib - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/mpg123 -) - -add_library(ogg SHARED IMPORTED GLOBAL) - -set_target_properties(ogg PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/ogg.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/ogg.lib -) - -add_library(png SHARED IMPORTED GLOBAL) - -set_target_properties(png PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libpng16.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libpng16.lib -) - - -add_library(ssl STATIC IMPORTED GLOBAL) - -set_target_properties(ssl PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libssl.lib -) - -add_library(uv STATIC IMPORTED GLOBAL) - -set_target_properties(uv PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libuv.lib - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/uv -) - - -add_library(vorbis SHARED IMPORTED GLOBAL) - -set_target_properties(vorbis PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/vorbis.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/vorbis.lib -) - -add_library(vorbisfile SHARED IMPORTED GLOBAL) - -set_target_properties(vorbisfile PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/vorbisfile.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/vorbisfile.lib -) - -add_library(webp STATIC IMPORTED GLOBAL) - -set_target_properties(webp PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/webp.lib -) - -add_library(zlib SHARED IMPORTED GLOBAL) - -set_target_properties(zlib PROPERTIES - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/zlib.lib - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/zlib1.dll - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/zlib -) - -add_library(websockets SHARED IMPORTED GLOBAL) - -set_target_properties(websockets PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/websockets.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/websockets.lib - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/websockets -) - - -add_library(OpenAL32 STATIC IMPORTED GLOBAL) - -set_target_properties(OpenAL32 PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/OpenAL32.lib - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/openalSoft -) - -add_library(sqlite3 SHARED IMPORTED GLOBAL) - -set_target_properties(sqlite3 PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/sqlite3.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/sqlite3.lib -) - - -add_library(SDL2 SHARED IMPORTED GLOBAL) -set_target_properties(SDL2 PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/SDL2.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/SDL2.lib -) - -add_library(SDL2Main SHARED IMPORTED GLOBAL) -set_target_properties(SDL2Main PROPERTIES - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/SDL2Main.lib -) - -add_library(tcmalloc SHARED IMPORTED GLOBAL) -set_target_properties(tcmalloc PROPERTIES - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libtcmalloc_minimal.lib -) - -set(se_libs_name) - -if(CC_EDITOR) - message(VERBOSE "CC_EDITOR USE V8 FROM NODEJS") -elseif(USE_SE_V8) - add_library(v8 SHARED IMPORTED GLOBAL) - set_target_properties(v8 PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/v8.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/v8.dll.lib - INTERFACE_COMPILE_DEFINITIONS V8_COMPRESS_POINTERS - ) - - add_library(v8_libbase SHARED IMPORTED GLOBAL) - set_target_properties(v8_libbase PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/v8_libbase.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/v8_libbase.dll.lib - ) - - add_library(v8_libplatform SHARED IMPORTED GLOBAL) - set_target_properties(v8_libplatform PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/v8_libplatform.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/v8_libplatform.dll.lib - ) - - target_link_libraries(v8 INTERFACE v8_libbase v8_libplatform) - - set_target_properties(v8 PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/v8 - ) - - set(se_libs_name v8) -else() - message(FATAL_ERROR "Only V8 is supported!") -endif() - -############################# glslang ############################# - -set(glslang_libs_name glslang glslang-default-resource-limits MachineIndependent OGLCompiler OSDependent SPIRV SPIRV-Tools-opt SPIRV-Tools GenericCodeGen) -foreach(gl IN LISTS glslang_libs_name) - add_library(${gl} STATIC IMPORTED GLOBAL) - set_target_properties(${gl} PROPERTIES - IMPORTED_LOCATION_DEBUG ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/${gl}d.lib - IMPORTED_LOCATION_RELEASE ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/${gl}.lib - ) -endforeach() - -############################# TBB ############################# - -add_library(tbb SHARED IMPORTED GLOBAL) -set_target_properties(tbb PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/tbb.dll - IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/tbb.lib -) -set(tbb_libs_name tbb) - -list(APPEND CC_EXTERNAL_PRIVATE_DEFINITIONS __TBB_LIB_NAME=tbb) - -if(USE_PHYSICS_PHYSX) - set(PhysXSDK PhysX PhysXCommon PhysXFoundation PhysXExtensions PhysXCooking PhysXCharacterKinematic PhysXVehicle PhysXPvdSDK) - foreach(PX IN LISTS PhysXSDK) - add_library(${PX} STATIC IMPORTED GLOBAL) - set_target_properties(${PX} PROPERTIES - IMPORTED_LOCATION_DEBUG ${CMAKE_CURRENT_LIST_DIR}/libs/PhysX/debug/${PX}_static_64.lib - IMPORTED_LOCATION_RELEASE ${CMAKE_CURRENT_LIST_DIR}/libs/PhysX/release/${PX}_static_64.lib - ) - endforeach() -else() - set(PhysXSDK) -endif() - -list(APPEND CC_EXTERNAL_LIBS - freetype - glew32 - iconv - crypto - curl - jpeg - mpg123 - ogg - png - ssl - uv - vorbis - vorbisfile - webp - OpenAL32 - sqlite3 - zlib - websockets - SDL2 - SDL2Main - tcmalloc - ${glslang_libs_name} - ${tbb_libs_name} - ${PhysXSDK} -) - -set(ZLIB zlib) -if(NOT USE_MODULES) - list(APPEND CC_EXTERNAL_LIBS ${ZLIB} - ${se_libs_name} - ) -endif() - -list(APPEND CC_EXTERNAL_INCLUDES - ${CMAKE_CURRENT_LIST_DIR}/include -) +add_library(dbgcore SHARED IMPORTED GLOBAL) + +set_target_properties(dbgcore PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/dbgcore.dll +) + +add_library(dbghelp SHARED IMPORTED GLOBAL) + +set_target_properties(dbghelp PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/dbghelp.dll +) + +add_library(dbgeng SHARED IMPORTED GLOBAL) + +set_target_properties(dbgeng PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/dbgeng.dll +) + +add_library(freetype STATIC IMPORTED GLOBAL) + +set_target_properties(freetype PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/freetype.lib +) + +add_library(glew32 SHARED IMPORTED GLOBAL) + +set_target_properties(glew32 PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/glew32.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/glew32.lib +) + +add_library(iconv SHARED IMPORTED GLOBAL) + +set_target_properties(iconv PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/iconv-2.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/iconv.lib + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/charset-1.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/charset.lib +) + + +add_library(crypto STATIC IMPORTED GLOBAL) + +set_target_properties(crypto PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcrypto.lib +) + + +add_library(curl SHARED IMPORTED GLOBAL) + +set_target_properties(curl PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libcurl.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libcurl.lib +) + +add_library(jpeg STATIC IMPORTED GLOBAL) + +set_target_properties(jpeg PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/jpeg.lib +) + +add_library(mpg123 SHARED IMPORTED GLOBAL) + +set_target_properties(mpg123 PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libmpg123-0.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libmpg123-0.lib + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/mpg123 +) + +add_library(ogg SHARED IMPORTED GLOBAL) + +set_target_properties(ogg PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/ogg.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/ogg.lib +) + +add_library(png SHARED IMPORTED GLOBAL) + +set_target_properties(png PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libpng16.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libpng16.lib +) + + +add_library(ssl STATIC IMPORTED GLOBAL) + +set_target_properties(ssl PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libssl.lib +) + +add_library(uv STATIC IMPORTED GLOBAL) + +set_target_properties(uv PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/libuv.lib + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/uv +) + + +add_library(vorbis SHARED IMPORTED GLOBAL) + +set_target_properties(vorbis PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/vorbis.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/vorbis.lib +) + +add_library(vorbisfile SHARED IMPORTED GLOBAL) + +set_target_properties(vorbisfile PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/vorbisfile.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/vorbisfile.lib +) + +add_library(webp STATIC IMPORTED GLOBAL) + +set_target_properties(webp PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/webp.lib +) + +add_library(zlib SHARED IMPORTED GLOBAL) + +set_target_properties(zlib PROPERTIES + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/zlib.lib + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/zlib1.dll + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/zlib +) + +add_library(websockets SHARED IMPORTED GLOBAL) + +set_target_properties(websockets PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/websockets.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/websockets.lib + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/websockets +) + + +add_library(OpenAL32 STATIC IMPORTED GLOBAL) + +set_target_properties(OpenAL32 PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/OpenAL32.lib + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/openalSoft +) + +add_library(sqlite3 SHARED IMPORTED GLOBAL) + +set_target_properties(sqlite3 PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/sqlite3.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/sqlite3.lib +) + + +add_library(SDL2 SHARED IMPORTED GLOBAL) +set_target_properties(SDL2 PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/SDL2.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/SDL2.lib +) + +add_library(SDL2Main SHARED IMPORTED GLOBAL) +set_target_properties(SDL2Main PROPERTIES + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/SDL2Main.lib +) + +add_library(tcmalloc SHARED IMPORTED GLOBAL) +set_target_properties(tcmalloc PROPERTIES + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/libtcmalloc_minimal.lib +) + +set(se_libs_name) + +if(CC_EDITOR) + message(VERBOSE "CC_EDITOR USE V8 FROM NODEJS") +elseif(USE_SE_V8 OR USE_SE_NAPI) + add_library(v8 SHARED IMPORTED GLOBAL) + set_target_properties(v8 PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/v8.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/v8.dll.lib + INTERFACE_COMPILE_DEFINITIONS V8_COMPRESS_POINTERS + ) + + add_library(v8_libbase SHARED IMPORTED GLOBAL) + set_target_properties(v8_libbase PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/v8_libbase.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/v8_libbase.dll.lib + ) + + add_library(v8_libplatform SHARED IMPORTED GLOBAL) + set_target_properties(v8_libplatform PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/v8_libplatform.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/v8_libplatform.dll.lib + ) + + target_link_libraries(v8 INTERFACE v8_libbase v8_libplatform) + + set_target_properties(v8 PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/include/v8 + ) + + set(se_libs_name v8) +else() + message(FATAL_ERROR "Only V8 is supported!") +endif() + +############################# glslang ############################# + +set(glslang_libs_name glslang glslang-default-resource-limits MachineIndependent OGLCompiler OSDependent SPIRV SPIRV-Tools-opt SPIRV-Tools GenericCodeGen) +foreach(gl IN LISTS glslang_libs_name) + add_library(${gl} STATIC IMPORTED GLOBAL) + set_target_properties(${gl} PROPERTIES + IMPORTED_LOCATION_DEBUG ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/${gl}d.lib + IMPORTED_LOCATION_RELEASE ${CMAKE_CURRENT_LIST_DIR}/libs/glslang/${gl}.lib + ) +endforeach() + +############################# TBB ############################# + +add_library(tbb SHARED IMPORTED GLOBAL) +set_target_properties(tbb PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/libs/tbb.dll + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/libs/tbb.lib +) +set(tbb_libs_name tbb) + +list(APPEND CC_EXTERNAL_PRIVATE_DEFINITIONS __TBB_LIB_NAME=tbb) + +if(USE_PHYSICS_PHYSX) + set(PhysXSDK PhysX PhysXCommon PhysXFoundation PhysXExtensions PhysXCooking PhysXCharacterKinematic PhysXVehicle PhysXPvdSDK) + foreach(PX IN LISTS PhysXSDK) + add_library(${PX} STATIC IMPORTED GLOBAL) + set_target_properties(${PX} PROPERTIES + IMPORTED_LOCATION_DEBUG ${CMAKE_CURRENT_LIST_DIR}/libs/PhysX/debug/${PX}_static_64.lib + IMPORTED_LOCATION_RELEASE ${CMAKE_CURRENT_LIST_DIR}/libs/PhysX/release/${PX}_static_64.lib + ) + endforeach() +else() + set(PhysXSDK) +endif() + +list(APPEND CC_EXTERNAL_LIBS + freetype + glew32 + iconv + crypto + curl + jpeg + mpg123 + ogg + png + ssl + uv + vorbis + vorbisfile + webp + OpenAL32 + sqlite3 + zlib + websockets + SDL2 + SDL2Main + tcmalloc + ${glslang_libs_name} + ${tbb_libs_name} + ${PhysXSDK} +) + +set(ZLIB zlib) +if(NOT USE_MODULES) + list(APPEND CC_EXTERNAL_LIBS ${ZLIB} + ${se_libs_name} + ) +endif() + +list(APPEND CC_EXTERNAL_INCLUDES + ${CMAKE_CURRENT_LIST_DIR}/include +)