Skip to content

Commit

Permalink
Implement building with clang-cl
Browse files Browse the repository at this point in the history
Signed-off-by: Seonghyun Kim <[email protected]>
  • Loading branch information
ksh8281 committed Jul 11, 2023
1 parent 073eeca commit 7792e6b
Show file tree
Hide file tree
Showing 13 changed files with 120 additions and 43 deletions.
51 changes: 51 additions & 0 deletions .github/workflows/es-actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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/[email protected]
with:
timezoneWindows: "Pacific Standard Time"
- uses: lukka/get-cmake@latest
- uses: GuillaumeFalourd/[email protected]
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/[email protected]
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
Expand Down
22 changes: 16 additions & 6 deletions build/target.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down
19 changes: 12 additions & 7 deletions src/Escargot.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__)
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
26 changes: 15 additions & 11 deletions src/api/EscargotPublic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/interpreter/ByteCode.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -1247,7 +1247,7 @@ class GetObjectPreComputedCase : public ByteCode {

static constexpr size_t inlineCacheProtoTraverseMaxCount = 12;

enum GetInlineCacheMode {
enum GetInlineCacheMode ENSURE_ENUM_UNSIGNED {
None,
Simple,
Complex
Expand Down
6 changes: 5 additions & 1 deletion src/interpreter/ByteCodeInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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; \
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/BigInt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int32_t>::min()) {
v2 = std::numeric_limits<int32_t>::min() + 1;
Expand Down Expand Up @@ -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<int32_t>::min()) {
v2 = std::numeric_limits<int32_t>::min() + 1;
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/String.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
3 changes: 2 additions & 1 deletion src/runtime/ValueInlines.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
18 changes: 10 additions & 8 deletions src/shell/Shell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
#include <dlfcn.h>
#endif

#if !defined(__APPLE__) && !defined(_WINDOWS)
#if !defined(__APPLE__) && !defined(_WINDOWS) && !defined(_WIN32) && !defined(_WIN64)
#include <signal.h>
#include <execinfo.h>

Expand Down Expand Up @@ -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<AtomicStringRef> nonIndexedStringPropertyNameIfExists)
{
// TODO check security
}

PersistentRefHolder<ContextRef> createEscargotContext(VMInstanceRef* instance, bool isMainThread)
{
Expand All @@ -881,12 +886,9 @@ PersistentRefHolder<ContextRef> 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<AtomicStringRef> 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);
Expand Down Expand Up @@ -1056,21 +1058,21 @@ PersistentRefHolder<ContextRef> createEscargotContext(VMInstanceRef* instance, b
return context;
}

#if defined(_WINDOWS)
#if defined(_WINDOWS) || defined(_WIN32) || defined(_WIN64)
#include <windows.h> // for SetConsoleOutputCP
#endif

int main(int argc, char* argv[])
{
#if defined(_WINDOWS)
#if defined(_WINDOWS) || defined(_WIN32) || defined(_WIN64)
SetConsoleOutputCP(65001);
#endif
#ifndef NDEBUG
setbuf(stdout, NULL);
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);
Expand Down
4 changes: 2 additions & 2 deletions src/util/Util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@
#include "Vector.h"
#include "Util.h"

#if defined(__ANDROID__)
#if defined(OS_ANDROID)
#include <sys/time.h>
#elif defined(_WINDOWS)
#elif defined(OS_WINDOWS)
#include <time.h>
#else
#include <sys/timeb.h>
Expand Down
2 changes: 1 addition & 1 deletion third_party/GCutil
Submodule GCutil updated 2 files
+13 −13 CMakeLists.txt
+37 −7 bdwgc/os_dep.c
2 changes: 1 addition & 1 deletion third_party/libbf/cutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <intrin.h>
static inline int __builtin_ctz(unsigned x)
{
Expand Down

0 comments on commit 7792e6b

Please sign in to comment.