diff --git a/.github/workflows/es-actions.yml b/.github/workflows/es-actions.yml index 61220e8ae..9d9633a94 100644 --- a/.github/workflows/es-actions.yml +++ b/.github/workflows/es-actions.yml @@ -174,6 +174,57 @@ jobs: CC=clang CXX=clang++ cmake -H. -Bout/release -DESCARGOT_ARCH=aarch64 -DESCARGOT_HOST=linux -DESCARGOT_MODE=release -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_OUTPUT=shell -GNinja ninja -Cout/release python3 ./tools/run-tests.py --engine="./out/release/escargot" new-es + test-on-windows-x86-clang-cl: + runs-on: windows-2022 + strategy: + matrix: + arch: [x86] + steps: + - name: Set git cllf config + run: | + git config --global core.autocrlf input + git config --global core.eol lf + - uses: actions/checkout@v3 + with: + submodules: true + - uses: szenius/set-timezone@v1.2 + with: + timezoneWindows: "Pacific Standard Time" + - uses: lukka/get-cmake@latest + - uses: GuillaumeFalourd/setup-windows10-sdk-action@v1.11 + with: + sdk-version: 20348 + - uses: actions/setup-python@v4 + with: + python-version: '3.11' + - name: Install msvc redist package + run: | + (new-object System.Net.WebClient).DownloadFile('https://github.com/abbodi1406/vcredist/releases/download/v0.73.0/VisualCppRedist_AIO_x86_x64.exe','VisualCppRedist_AIO_x86_x64.exe') + .\VisualCppRedist_AIO_x86_x64.exe /y + - uses: ilammy/msvc-dev-cmd@v1.12.1 + with: + arch: ${{ matrix.arch }} + sdk: "10.0.20348.0" + - name: Build ${{ matrix.arch }} Release + run: | + CMake -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_SYSTEM_VERSION:STRING="10.0" -DCMAKE_SYSTEM_PROCESSOR=x86 -DESCARGOT_ARCH=x86 -DESCARGOT_MODE=release -Bout/ -DESCARGOT_HOST=windows -DESCARGOT_OUTPUT=shell -DESCARGOT_LIBICU_SUPPORT=ON -DESCARGOT_LIBICU_SUPPORT_WITH_DLOPEN=NO -DESCARGOT_THREADING=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -G Ninja -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_BUILD_TYPE=release -DCMAKE_C_FLAGS="-m32" -DCMAKE_CXX_FLAGS="-m32" + CMake --build out/ --config Release + # windows internal ICU doesn't support Temporal and intl402 well + # github action windows runner only have 2 CPUs. that's why I disable Atomics(timeout occured with some tests) + - name: Run test262 + run: | + set GC_FREE_SPACE_DIVISOR=1 + pip install chardet + python tools\run-tests.py --engine=%cd%\out\escargot.exe test262 --extra-arg="--skip Temporal --skip intl402 --skip Atomics" + shell: cmd + - name: Run octane + run: | + copy test\octane\*.js + dir + .\out\escargot.exe run.js + - if: ${{ failure() }} + uses: mxschmitt/action-tmate@v3 + timeout-minutes: 15 test-on-windows-x86-x64: runs-on: windows-2022 diff --git a/build/target.cmake b/build/target.cmake index bd6cc080b..9319b6b42 100644 --- a/build/target.cmake +++ b/build/target.cmake @@ -10,8 +10,23 @@ SET (ESCARGOT_BUILD_32BIT OFF) SET (ESCARGOT_BUILD_64BIT OFF) SET (ESCARGOT_BUILD_64BIT_LARGE OFF) +# clang-cl defines ${CMAKE_CXX_COMPILER_ID} "Clang" and ${CMAKE_CXX_COMPILER_FRONTEND_VARIANT} "MSVC" +SET (COMPILER_CLANG_CL OFF) +IF (${CMAKE_VERSION} VERSION_GREATER "3.14.0") + IF (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" AND ${CMAKE_CXX_COMPILER_FRONTEND_VARIANT} STREQUAL "MSVC") + SET (COMPILER_CLANG_CL ON) + ENDIF() +ENDIF() + # Default options per compiler -IF (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") +IF (${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC" OR ${COMPILER_CLANG_CL}) + SET (ESCARGOT_CXXFLAGS /std:c++17 /fp:strict /Zc:__cplusplus /EHs /source-charset:utf-8 /D_CRT_SECURE_NO_WARNINGS /DGC_NOT_DLL /wd4244 /wd4267 /wd4805 /wd4018 /wd4172) + SET (ESCARGOT_CXXFLAGS_RELEASE /O2 /Oy-) + SET (ESCARGOT_THIRDPARTY_CFLAGS /D_CRT_SECURE_NO_WARNINGS /DGC_NOT_DLL /Oy- /wd4146) + IF (${COMPILER_CLANG_CL}) + SET (ESCARGOT_CXXFLAGS ${ESCARGOT_CXXFLAGS} /EHs -Wno-invalid-offsetof -Wno-inline-new-delete -fintegrated-cc1) + ENDIF() +ELSEIF (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") SET (ESCARGOT_CXXFLAGS ${ESCARGOT_CXXFLAGS} -std=c++11 -g3 @@ -50,11 +65,6 @@ ELSEIF (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") SET (ESCARGOT_CXXFLAGS_DEBUG -O0 -Wall -Wextra -Werror) SET (ESCARGOT_CXXFLAGS_RELEASE -O2 -fno-stack-protector -fno-omit-frame-pointer) SET (ESCARGOT_THIRDPARTY_CFLAGS -w -g3 -fdata-sections -ffunction-sections -fno-omit-frame-pointer -fvisibility=hidden) -ELSEIF (${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") - SET (CMAKE_CXX_STANDARD 11) - SET (ESCARGOT_CXXFLAGS /fp:strict /Zc:__cplusplus /source-charset:utf-8 /D_CRT_SECURE_NO_WARNINGS /DGC_NOT_DLL /wd4244 /wd4267 /wd4805 /wd4018 /wd4172) - SET (ESCARGOT_CXXFLAGS_RELEASE /O2 /Oy-) - SET (ESCARGOT_THIRDPARTY_CFLAGS /D_CRT_SECURE_NO_WARNINGS /DGC_NOT_DLL /Oy- /wd4146) ELSE() MESSAGE (FATAL_ERROR ${CMAKE_CXX_COMPILER_ID} " is Unsupported Compiler") ENDIF() diff --git a/src/Escargot.h b/src/Escargot.h index dbea89d52..7d9202887 100755 --- a/src/Escargot.h +++ b/src/Escargot.h @@ -52,6 +52,10 @@ #if defined(__clang__) #define COMPILER_CLANG 1 +// clang-cl defines _MSC_VER and __clang__ both +#if defined(_MSC_VER) +#define COMPILER_CLANG_CL 1 +#endif #elif defined(_MSC_VER) #define COMPILER_MSVC 1 #elif (__GNUC__) @@ -158,11 +162,6 @@ #endif #endif -#if defined(COMPILER_MSVC) -#define strncasecmp _strnicmp -#define strcasecmp _stricmp -#endif - #ifndef ATTRIBUTE_NO_SANITIZE_ADDRESS #if defined(COMPILER_GCC) || defined(COMPILER_CLANG) #define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) @@ -217,6 +216,12 @@ #define NOMINMAX #endif +#if defined(OS_WINDOWS) +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#endif + + /* we need to mark enum as unsigned if needs. because processing enum in msvc is little different @@ -226,7 +231,7 @@ struct Foo { Type type: 1; }; Foo f; f.type = 1; if (f.type == Type::B) { puts("failed in msvc."); } */ -#if defined(COMPILER_MSVC) +#if defined(OS_WINDOWS) #define ENSURE_ENUM_UNSIGNED : unsigned int #else #define ENSURE_ENUM_UNSIGNED @@ -481,7 +486,7 @@ void customEscargotErrorLogger(const char* format, ...); #if defined(COMPILER_GCC) || defined(COMPILER_CLANG) #define ESCARGOT_COMPUTED_GOTO_INTERPRETER // some devices cannot support getting label address from outside well -#if (defined(CPU_ARM64) || (defined(CPU_ARM32) && defined(COMPILER_CLANG))) || defined(OS_DARWIN) || defined(OS_ANDROID) +#if (defined(CPU_ARM64) || (defined(CPU_ARM32) && defined(COMPILER_CLANG))) || defined(OS_DARWIN) || defined(OS_ANDROID) || defined(OS_WINDOWS) #define ESCARGOT_COMPUTED_GOTO_INTERPRETER_INIT_WITH_NULL #endif #endif diff --git a/src/api/EscargotPublic.cpp b/src/api/EscargotPublic.cpp index 09912b1fc..c57f41057 100644 --- a/src/api/EscargotPublic.cpp +++ b/src/api/EscargotPublic.cpp @@ -205,20 +205,24 @@ class PlatformBridge : public Platform { PlatformRef* m_platform; }; -void PlatformRef::notifyHostImportModuleDynamicallyResult(ContextRef* relatedContext, ScriptRef* referrer, StringRef* src, PromiseObjectRef* promise, LoadModuleResult loadModuleResult) +// making this function with lambda causes "cannot compile this forwarded non-trivially copyable parameter yet" on Windows/ClangCL +static ValueRef* notifyHostImportModuleDynamicallyInnerExecute(ExecutionStateRef* state, PlatformRef::LoadModuleResult loadModuleResult, Script::ModuleData::ModulePromiseObject* promise) { - auto result = Evaluator::execute(relatedContext, [](ExecutionStateRef* state, LoadModuleResult loadModuleResult, Script::ModuleData::ModulePromiseObject* promise) -> ValueRef* { - if (loadModuleResult.script) { - if (loadModuleResult.script.value()->isExecuted()) { - if (loadModuleResult.script.value()->wasThereErrorOnModuleEvaluation()) { - state->throwException(loadModuleResult.script.value()->moduleEvaluationError()); - } + if (loadModuleResult.script) { + if (loadModuleResult.script.value()->isExecuted()) { + if (loadModuleResult.script.value()->wasThereErrorOnModuleEvaluation()) { + state->throwException(loadModuleResult.script.value()->moduleEvaluationError()); } - } else { - state->throwException(ErrorObjectRef::create(state, loadModuleResult.errorCode, loadModuleResult.errorMessage)); } - return ValueRef::createUndefined(); - }, + } else { + state->throwException(ErrorObjectRef::create(state, loadModuleResult.errorCode, loadModuleResult.errorMessage)); + } + return ValueRef::createUndefined(); +} + +void PlatformRef::notifyHostImportModuleDynamicallyResult(ContextRef* relatedContext, ScriptRef* referrer, StringRef* src, PromiseObjectRef* promise, LoadModuleResult loadModuleResult) +{ + auto result = Evaluator::execute(relatedContext, notifyHostImportModuleDynamicallyInnerExecute, loadModuleResult, (Script::ModuleData::ModulePromiseObject*)promise); Script::ModuleData::ModulePromiseObject* mp = (Script::ModuleData::ModulePromiseObject*)promise; diff --git a/src/interpreter/ByteCode.h b/src/interpreter/ByteCode.h index 05c80409f..8f8bb854f 100644 --- a/src/interpreter/ByteCode.h +++ b/src/interpreter/ByteCode.h @@ -197,7 +197,7 @@ struct ByteCodeLOC { } }; -#if defined(NDEBUG) && defined(ESCARGOT_32) && !defined(COMPILER_MSVC) +#if defined(NDEBUG) && defined(ESCARGOT_32) && !defined(OS_WINDOWS) #define BYTECODE_SIZE_CHECK_IN_32BIT(codeName, size) COMPILE_ASSERT(sizeof(codeName) == size, ""); #else #define BYTECODE_SIZE_CHECK_IN_32BIT(CodeName, Size) @@ -1247,7 +1247,7 @@ class GetObjectPreComputedCase : public ByteCode { static constexpr size_t inlineCacheProtoTraverseMaxCount = 12; - enum GetInlineCacheMode { + enum GetInlineCacheMode ENSURE_ENUM_UNSIGNED { None, Simple, Complex diff --git a/src/interpreter/ByteCodeInterpreter.cpp b/src/interpreter/ByteCodeInterpreter.cpp index 3d3900ba5..e3dc82d86 100644 --- a/src/interpreter/ByteCodeInterpreter.cpp +++ b/src/interpreter/ByteCodeInterpreter.cpp @@ -51,7 +51,7 @@ #include "parser/ScriptParser.h" #include "CheckedArithmetic.h" -#if defined(ESCARGOT_COMPUTED_GOTO_INTERPRETER) +#if defined(ESCARGOT_COMPUTED_GOTO_INTERPRETER) && !defined(ESCARGOT_COMPUTED_GOTO_INTERPRETER_INIT_WITH_NULL) extern char FillOpcodeTableAsmLbl[]; const void* FillOpcodeTableAddress[] = { &FillOpcodeTableAsmLbl[0] }; #endif @@ -1654,7 +1654,11 @@ Value Interpreter::interpret(ExecutionState* state, ByteCodeBlock* byteCodeBlock __attribute__((cold)); #endif #if defined(ESCARGOT_COMPUTED_GOTO_INTERPRETER) + +#if !defined(ESCARGOT_COMPUTED_GOTO_INTERPRETER_INIT_WITH_NULL) asm volatile("FillOpcodeTableAsmLbl:"); +#endif + #if defined(ENABLE_CODE_CACHE) #define REGISTER_TABLE(opcode) \ g_opcodeTable.m_addressTable[opcode##Opcode] = &&opcode##OpcodeLbl; \ diff --git a/src/runtime/BigInt.cpp b/src/runtime/BigInt.cpp index eaf3533ff..882c87dde 100644 --- a/src/runtime/BigInt.cpp +++ b/src/runtime/BigInt.cpp @@ -472,7 +472,7 @@ BigInt* BigInt::leftShift(ExecutionState& state, BigInt* src) const bf_init(ThreadLocal::bfContext(), &r); slimb_t v2; -#if defined(ESCARGOT_32) || defined(COMPILER_MSVC) +#if defined(ESCARGOT_32) || defined(OS_WINDOWS) bf_get_int32(&v2, src->bf(), 0); if (v2 == std::numeric_limits::min()) { v2 = std::numeric_limits::min() + 1; @@ -502,7 +502,7 @@ BigInt* BigInt::rightShift(ExecutionState& state, BigInt* src) const bf_init(ThreadLocal::bfContext(), &r); slimb_t v2; -#if defined(ESCARGOT_32) || defined(COMPILER_MSVC) +#if defined(ESCARGOT_32) || defined(OS_WINDOWS) bf_get_int32(&v2, src->bf(), 0); if (v2 == std::numeric_limits::min()) { v2 = std::numeric_limits::min() + 1; diff --git a/src/runtime/String.h b/src/runtime/String.h index ada04828c..c95c9dcd0 100644 --- a/src/runtime/String.h +++ b/src/runtime/String.h @@ -596,7 +596,7 @@ class String : public PointerValue { } }; -#if defined(NDEBUG) && defined(ESCARGOT_32) && !defined(COMPILER_MSVC) +#if defined(NDEBUG) && defined(ESCARGOT_32) && !defined(OS_WINDOWS) COMPILE_ASSERT(sizeof(String) == sizeof(size_t) * 4, ""); #endif diff --git a/src/runtime/ValueInlines.h b/src/runtime/ValueInlines.h index a9f986050..1327533b6 100644 --- a/src/runtime/ValueInlines.h +++ b/src/runtime/ValueInlines.h @@ -751,7 +751,8 @@ inline bool Value::isCallable() const // https://www.ecma-international.org/ecma-262/6.0/#sec-tonumber inline double Value::toNumber(ExecutionState& state) const { -#ifdef ESCARGOT_64 +// there is optimizer bug on clang-cl with below block +#if defined(ESCARGOT_64) && !defined(COMPILER_CLANG_CL) auto n = u.asInt64 & TagTypeNumber; if (LIKELY(n)) { if (n == TagTypeNumber) { diff --git a/src/shell/Shell.cpp b/src/shell/Shell.cpp index b5e7463ba..ab6dd1b32 100644 --- a/src/shell/Shell.cpp +++ b/src/shell/Shell.cpp @@ -43,7 +43,7 @@ #include #endif -#if !defined(__APPLE__) && !defined(_WINDOWS) +#if !defined(__APPLE__) && !defined(_WINDOWS) && !defined(_WIN32) && !defined(_WIN64) #include #include @@ -873,6 +873,11 @@ static bool evalScript(ContextRef* context, StringRef* source, StringRef* srcNam return result; } +// making this function with lambda causes "cannot compile this forwarded non-trivially copyable parameter yet" on Windows/ClangCL +static void globalObjectProxyCallback(ExecutionStateRef* state, GlobalObjectProxyObjectRef* proxy, GlobalObjectRef* targetGlobalObject, GlobalObjectProxyObjectRef::AccessOperationType operationType, OptionalRef nonIndexedStringPropertyNameIfExists) +{ + // TODO check security +} PersistentRefHolder createEscargotContext(VMInstanceRef* instance, bool isMainThread) { @@ -881,12 +886,9 @@ PersistentRefHolder createEscargotContext(VMInstanceRef* instance, b Evaluator::execute(context, [](ExecutionStateRef* state, bool isMainThread) -> ValueRef* { ContextRef* context = state->context(); - GlobalObjectProxyObjectRef* proxy = GlobalObjectProxyObjectRef::create(state, state->context()->globalObject(), [](ExecutionStateRef* state, GlobalObjectProxyObjectRef* proxy, GlobalObjectRef* targetGlobalObject, GlobalObjectProxyObjectRef::AccessOperationType operationType, OptionalRef nonIndexedStringPropertyNameIfExists) { - // TODO check security - }); + GlobalObjectProxyObjectRef* proxy = GlobalObjectProxyObjectRef::create(state, state->context()->globalObject(), globalObjectProxyCallback); context->setGlobalObjectProxy(proxy); - { FunctionObjectRef::NativeFunctionInfo nativeFunctionInfo(AtomicStringRef::create(context, "print"), builtinPrint, 1, true, false); FunctionObjectRef* buildFunctionObjectRef = FunctionObjectRef::create(state, nativeFunctionInfo); @@ -1056,13 +1058,13 @@ PersistentRefHolder createEscargotContext(VMInstanceRef* instance, b return context; } -#if defined(_WINDOWS) +#if defined(_WINDOWS) || defined(_WIN32) || defined(_WIN64) #include // for SetConsoleOutputCP #endif int main(int argc, char* argv[]) { -#if defined(_WINDOWS) +#if defined(_WINDOWS) || defined(_WIN32) || defined(_WIN64) SetConsoleOutputCP(65001); #endif #ifndef NDEBUG @@ -1070,7 +1072,7 @@ int main(int argc, char* argv[]) setbuf(stderr, NULL); #endif -#if defined(ESCARGOT_ENABLE_TEST) && !defined(__APPLE__) && !defined(_WINDOWS) +#if defined(ESCARGOT_ENABLE_TEST) && !defined(__APPLE__) && !defined(_WINDOWS) && !defined(_WIN32) && !defined(_WIN64) struct sigaction sa; sa.sa_handler = (void (*)(int))btSighandler; sigemptyset(&sa.sa_mask); diff --git a/src/util/Util.cpp b/src/util/Util.cpp index 1dd46f277..4c21bacb9 100644 --- a/src/util/Util.cpp +++ b/src/util/Util.cpp @@ -43,9 +43,9 @@ #include "Vector.h" #include "Util.h" -#if defined(__ANDROID__) +#if defined(OS_ANDROID) #include -#elif defined(_WINDOWS) +#elif defined(OS_WINDOWS) #include #else #include diff --git a/third_party/GCutil b/third_party/GCutil index c655a366e..65dffa8cf 160000 --- a/third_party/GCutil +++ b/third_party/GCutil @@ -1 +1 @@ -Subproject commit c655a366ee4f03d60f80f76782e35690c5fb0385 +Subproject commit 65dffa8cf5832ba6f28e2ab617e9c4b69467ae32 diff --git a/third_party/libbf/cutils.h b/third_party/libbf/cutils.h index 653588a2d..8225207b5 100644 --- a/third_party/libbf/cutils.h +++ b/third_party/libbf/cutils.h @@ -119,7 +119,7 @@ static inline int64_t min_int64(int64_t a, int64_t b) return b; } -#if defined(_MSC_VER) +#if defined(_MSC_VER) && !defined(__clang__) #include static inline int __builtin_ctz(unsigned x) {