Kaynağa Gözat

New Bytecode regen process:
1. Use python on windows and macOS/Linux
2. Suport multiple files of BuiltIns
3. Move file structure from ch.cpp into python
4. Delete defunct .cmd and .ps1 scripts
5. Delete defunct tests
6. Add testing via new python script and wire into CI
7. Add a noJit build on macOS to ensure noJit bytecode is tested

rhuanjl 5 yıl önce
ebeveyn
işleme
b1e8735309

+ 1 - 0
.gitattributes

@@ -3,6 +3,7 @@
 test/**/*.js -crlf
 test/es6/HTMLComments.js binary diff=cpp
 *.wasm binary
+lib/**/*.js eol=lf diff=cpp
 *.cpp text eol=lf diff=cpp
 *.h text eol=lf diff=cpp
 *.inl text eol=lf diff=cpp

+ 3 - 0
CMakeLists.txt

@@ -466,6 +466,9 @@ if(NO_JIT_SH)
     unset(NO_JIT_SH CACHE)      # don't cache
     unset(BuildJIT CACHE)       # also clear it just in case
     add_definitions(-DDISABLE_JIT=1)
+elseif(DISABLE_JIT)
+    set(BuildJIT 0)
+    add_definitions(-DDISABLE_JIT=1)
 else()
     set(BuildJIT 1)
 endif()

+ 0 - 84
RegenAllByteCode.cmd

@@ -1,84 +0,0 @@
-::-------------------------------------------------------------------------------------------------------
-:: Copyright (C) Microsoft. All rights reserved.
-:: Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
-::-------------------------------------------------------------------------------------------------------
-
-:: Regenerate all bytecode.
-:: Note, this script is windows only, on linux or macOS please use tools/xplatRegenByteCode.py
-:: ch.exe is used to generate Intl bytecodes.
-:: ch.exe (NoJIT variety) is used to generate NoJIT Intl bytecodes.
-:: Each set of bytecode requires an x86_debug and x64_debug binary.
-::
-:: Thus we need to build the following:
-:: [Core]   ch.exe        x64_debug
-:: [Core]   ch.exe        x86_debug
-:: [Core]   ch.exe        x64_debug (NoJIT)
-:: [Core]   ch.exe        x86_debug (NoJIT)
-
-setlocal
-pushd %~dp0
-
-:: ch.exe        x64_debug
-:: ch.exe        x86_debug
-call jenkins\buildone.cmd x64 debug
-if %errorlevel% neq 0 (
-  echo There was a build error for x64 debug. Stopping bytecode generation.
-  exit /b 1
-)
-call jenkins\buildone.cmd x86 debug
-if %errorlevel% neq 0 (
-  echo There was a build error for x86 debug. Stopping bytecode generation.
-  exit /b 1
-)
-
-pushd lib\Runtime\Library\InJavascript
-call GenByteCode.cmd
-if %errorlevel% neq 0 (
-  echo There was an error when regenerating bytecode header.
-  exit /b 1
-)
-popd
-
-pushd lib\Runtime\Library\JsBuiltIn
-call GenByteCode.cmd
-if %errorlevel% neq 0 (
-  echo There was an error when regenerating bytecode header.
-  exit /b 1
-)
-popd
-
-:: ch.exe        x64_debug (NoJIT)
-:: ch.exe        x86_debug (NoJIT)
-call jenkins\buildone.cmd x64 debug "/p:BuildJIT=false"
-if %errorlevel% neq 0 (
-  echo There was a build error for x64 debug NoJIT. Stopping bytecode generation.
-  exit /b 1
-)
-
-call jenkins\buildone.cmd x86 debug "/p:BuildJIT=false"
-if %errorlevel% neq 0 (
-  echo There was a build error for x86 debug NoJIT. Stopping bytecode generation.
-  exit /b 1
-)
-
-:: Generate Intl NoJIT Bytecodes using ch.exe (NoJIT)
-pushd lib\Runtime\Library\InJavascript
-call GenByteCode.cmd -nojit
-if %errorlevel% neq 0 (
-  echo There was an error when regenerating bytecode header for NoJIT.
-  exit /b 1
-)
-popd
-
-:: Generate BuiltIn NoJIT Bytecodes using ch.exe (NoJIT)
-pushd lib\Runtime\Library\JsBuiltIn
-call GenByteCode.cmd -nojit
-if %errorlevel% neq 0 (
-  echo There was an error when regenerating bytecode header for NoJIT.
-  exit /b 1
-)
-popd
-
-popd
-
-endlocal

+ 0 - 36
RegenAllByteCodeNoBuild.cmd

@@ -1,36 +0,0 @@
-::-------------------------------------------------------------------------------------------------------
-:: Copyright (C) Microsoft. All rights reserved.
-:: Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
-::-------------------------------------------------------------------------------------------------------
-
-:: WARNING: be careful when using this script as it assumes that
-:: you already have bytecode-format-compatible builds for all required flavors.
-:: This script helps speed things up when you are only making changes to scripts,
-:: e.g. Intl.js, without making any changes to bytecode format, since rebuilding
-:: every flavor of ChakraCore.dll when there are no relevant changes is a waste of time.
-:: Please ensure that you use buddy builds to validate the results.
-
-:: Note, this script is windows only, on linux or macOS please use tools/xplatRegenByteCode.py
-:: Regenerate all bytecode (without rebuilding each flavor of ch.exe)
-:: ch.exe is used to generate Intl bytecodes.
-:: ch.exe (NoJIT variety) is used to generate NoJIT Intl bytecodes.
-:: Each set of bytecode requires an x86_debug and x64_debug binary.
-::
-:: Thus we need to already have compatible builds of the following:
-:: [Core]   ch.exe        x64_debug
-:: [Core]   ch.exe        x86_debug
-:: [Core]   ch.exe        x64_debug (NoJIT)
-:: [Core]   ch.exe        x86_debug (NoJIT)
-
-@echo off
-setlocal
-  set _reporoot=%~dp0
-  pushd %_reporoot%\lib\Runtime\Library\InJavascript
-    call GenByteCode.cmd
-    call GenByteCode.cmd -nojit
-  popd
-  pushd %_reporoot%\lib\Runtime\Library\JsBuiltIn
-    call GenByteCode.cmd
-    call GenByteCode.cmd -nojit
-  popd
-endlocal

+ 6 - 0
azure-pipelines.yml

@@ -50,6 +50,12 @@ jobs:
           build_type: 'Release'
           do_test: false
           libtype_flag: ''
+        OSX.noJit:
+          image_name: 'macOS-latest'
+          deps: 'brew install ninja icu4c'
+          build_type: 'Debug'
+          do_test: true
+          libtype_flag: '-DSTATIC_LIBRARY=ON -DDISABLE_JIT=1'
         OSX.Debug:
           image_name: 'macOS-latest'
           deps: 'brew install ninja icu4c'

+ 34 - 81
bin/ch/ch.cpp

@@ -196,97 +196,62 @@ HANDLE GetFileHandle(LPCWSTR filename)
     return GetStdHandle(STD_OUTPUT_HANDLE);
 }
 
-HRESULT CreateLibraryByteCodeHeader(LPCSTR contentsRaw, JsFinalizeCallback contentsRawFinalizeCallback, DWORD lengthBytes, LPCWSTR bcFullPath, LPCSTR libraryNameNarrow)
+HRESULT CreateLibraryByteCode(const char* contentsRaw)
 {
-    HANDLE bcFileHandle = nullptr;
     JsValueRef bufferVal;
     BYTE *bcBuffer = nullptr;
     unsigned int bcBufferSize = 0;
-    DWORD written;
-    // For validating the header file against the library file
-    auto outputStr =
-        "//-------------------------------------------------------------------------------------------------------\n"
-        "// Copyright (C) Microsoft. All rights reserved.\n"
-        "// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.\n"
-        "//-------------------------------------------------------------------------------------------------------\n"
-        "#if 0\n";
-
-    std::string normalizedContentStr;
-    char* nextToken = nullptr;
-    char* token = strtok_s((char*)contentsRaw, "\r", &nextToken);
-    while (token)
-    {
-        normalizedContentStr.append(token);
-        token = strtok_s(nullptr, "\r", &nextToken);
-    }
-    // We no longer need contentsRaw, so call the finalizer for it if one was provided
-    if (contentsRawFinalizeCallback != nullptr)
-    {
-        contentsRawFinalizeCallback((void*)contentsRaw);
-    }
-
-    const char* normalizedContent = normalizedContentStr.c_str();
-    // We still need contentsRaw after this, so pass a null finalizeCallback into it
-    HRESULT hr = GetSerializedBuffer(normalizedContent, nullptr, &bufferVal);
-
-    IfFailedGoLabel((hr), ErrorRunFinalize);
-
-    IfJsrtErrorHRLabel(ChakraRTInterface::JsGetArrayBufferStorage(bufferVal, &bcBuffer, &bcBufferSize), ErrorRunFinalize);
-
-    bcFileHandle = GetFileHandle(bcFullPath);
-    IfFalseGo(bcFileHandle != INVALID_HANDLE_VALUE && bcFileHandle != nullptr);
-
-    IfFalseGoLabel(WriteFile(bcFileHandle, outputStr, (DWORD)strlen(outputStr), &written, nullptr), ErrorRunFinalize);
-    IfFalseGoLabel(WriteFile(bcFileHandle, normalizedContent, (DWORD)normalizedContentStr.size(), &written, nullptr), ErrorRunFinalize);
-    outputStr = "\n#endif\n";
+    HRESULT hr = E_FAIL;
+    
+    // Windows can't do the below with printf - so use windows API on windows but printf on posix
+    #ifdef _WIN32
+        HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
+        DWORD written = 0;
+        #define print_format(format, element, size) \
+        { \
+            auto scratchLen = size; \
+            char scratch[size]; \
+            int len = _snprintf_s(scratch, scratchLen, _countof(scratch), format, element); \
+            IfFalseGo(WriteFile(out, scratch, (DWORD)(len), &written, nullptr)); \
+        }
+        #define print(text) \
+            WriteFile(out, text, (DWORD)strlen(text), &written, nullptr);
+    #else
+        #define print_format(format, element, size) printf(format, element)
+        #define print printf
+    #endif
 
-    IfFalseGo(WriteFile(bcFileHandle, outputStr, (DWORD)strlen(outputStr), &written, nullptr));
+    // Generate the bytecode, free the original buffer then retrieve the generated bytecode
+    IfFailGo(GetSerializedBuffer(contentsRaw, WScriptJsrt::FinalizeFree, &bufferVal));
+    IfFailGo(ChakraRTInterface::JsGetArrayBufferStorage(bufferVal, &bcBuffer, &bcBufferSize));
 
     // Write out the bytecode
-    outputStr = "namespace Js\n{\n    const char Library_Bytecode_";
-    IfFalseGo(WriteFile(bcFileHandle, outputStr, (DWORD)strlen(outputStr), &written, nullptr));
-    IfFalseGo(WriteFile(bcFileHandle, libraryNameNarrow, (DWORD)strlen(libraryNameNarrow), &written, nullptr));
-    outputStr = "[] = {\n/* 00000000 */";
-    IfFalseGo(WriteFile(bcFileHandle, outputStr, (DWORD)strlen(outputStr), &written, nullptr));
+    print("[] = {\n/* 00000000 */");
 
     for (unsigned int i = 0; i < bcBufferSize; i++)
     {
-        char scratch[6];
-        auto scratchLen = sizeof(scratch);
-        int num = _snprintf_s(scratch, scratchLen, _countof(scratch), " 0x%02X", bcBuffer[i]);
-        Assert(num == 5);
-        IfFalseGo(WriteFile(bcFileHandle, scratch, (DWORD)(scratchLen - 1), &written, nullptr));
-
-        // Add a comma and a space if this is not the last item
+        print_format(" 0x%02X", bcBuffer[i], 6);
+        // Add a comma if this is not the last item
         if (i < bcBufferSize - 1)
         {
-            char commaSpace[2];
-            _snprintf_s(commaSpace, sizeof(commaSpace), _countof(commaSpace), ",");  // close quote, new line, offset and open quote
-            IfFalseGo(WriteFile(bcFileHandle, commaSpace, (DWORD)strlen(commaSpace), &written, nullptr));
+            print(",");
         }
 
         // Add a line break every 16 scratches, primarily so the compiler doesn't complain about the string being too long.
         // Also, won't add for the last scratch
         if (i % 16 == 15 && i < bcBufferSize - 1)
         {
-            char offset[17];
-            int actualLen = _snprintf_s(offset, sizeof(offset), _countof(offset), "\n/* %08X */", i + 1);  // close quote, new line, offset and open quote
-            IfFalseGo(WriteFile(bcFileHandle, offset, actualLen, &written, nullptr));
+            print_format("\n/* %08X */", i + 1, 17);
         }
     }
-    outputStr = "};\n\n";
-    IfFalseGo(WriteFile(bcFileHandle, outputStr, (DWORD)strlen(outputStr), &written, nullptr));
+    print("};\n\n");
 
-    outputStr = "}\n";
-    IfFalseGo(WriteFile(bcFileHandle, outputStr, (DWORD)strlen(outputStr), &written, nullptr));
+    #undef print
+    #undef print_format
 
-ErrorRunFinalize:
-Error:
-    if (bcFileHandle != nullptr)
-    {
-        CloseHandle(bcFileHandle);
-    }
+    hr = S_OK;
 
+Error:
     return hr;
 }
 
@@ -933,19 +898,7 @@ HRESULT ExecuteTest(const char* fileName)
         len = strlen(fullPath);
         if (HostConfigFlags::flags.GenerateLibraryByteCodeHeaderIsEnabled)
         {
-
-            if (HostConfigFlags::flags.GenerateLibraryByteCodeHeader != nullptr)
-            {
-                if (wcslen(HostConfigFlags::flags.GenerateLibraryByteCodeHeader) == 0)
-                {
-                    HostConfigFlags::flags.GenerateLibraryByteCodeHeader = nullptr;
-                }
-            }
-            CHAR libraryName[_MAX_PATH];
-            CHAR ext[_MAX_EXT];
-            _splitpath_s(fullPath, NULL, 0, NULL, 0, libraryName, _countof(libraryName), ext, _countof(ext));
-
-            IfFailGo(CreateLibraryByteCodeHeader(fileContents, WScriptJsrt::FinalizeFree, lengthBytes, HostConfigFlags::flags.GenerateLibraryByteCodeHeader, libraryName));
+            IfFailGo(CreateLibraryByteCode(fileContents));
         }
         else if (HostConfigFlags::flags.SerializedIsEnabled)
         {

+ 0 - 85
lib/Runtime/Library/InJavascript/GenByteCode.cmd

@@ -1,85 +0,0 @@
-::-------------------------------------------------------------------------------------------------------
-:: Copyright (C) Microsoft. All rights reserved.
-:: Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
-::-------------------------------------------------------------------------------------------------------
-
-@echo off
-setlocal
-set _HASERROR=0
-set _binary=ch.exe
-set _BuildDir=%~dp0..\..\..\..\Build
-
-if "%_FILE%" == "" (
-    set "_FILE=%~dp0*.js"
-)
-
-:ContinueArgParse
-if not [%1]==[] (
-    if [%1]==[-nojit] (
-        set _suffix=.nojit
-        goto :ContinueArgParseEnd
-    )
-    if [%1]==[-binary] (
-        if [%2]==[] (
-            echo Error: no argument supplied to -binary. Exiting ...
-            exit /b 1
-        )
-        set _binary=%2
-        shift
-        goto :ContinueArgParseEnd
-    )
-    if [%1]==[-bindir] (
-        if [%2]==[] (
-            echo Error: no argument supplied to -bindir. Exiting ...
-            exit /b 1
-        )
-        set _BinLocation=%2
-        shift
-        goto :ContinueArgParseEnd
-    )
-
-    :ContinueArgParseEnd
-    shift
-    goto :ContinueArgParse
-)
-
-:: This script will expect %_binary% to be built for x86_debug and x64_debug
-
-if "%OutBaseDir%" NEQ "" (
-    set _BinLocation=%OutBaseDir%\Chakra.Core%_suffix%\bin
-)
-if "%_BinLocation%"=="" (
-    set _BinLocation=%_BuildDir%\VcBuild%_suffix%\bin
-)
-
-if not exist %_BinLocation%\x86_debug\%_binary% (
-    echo Error: %_BinLocation%\x86_debug\%_binary% not found, please build sources. Exiting ...
-    exit /b 1
-)
-
-if not exist %_BinLocation%\x64_debug\%_binary% (
-    echo Error: %_BinLocation%\x64_debug\%_binary% not found, please build sources. Exiting ...
-    exit /b 1
-)
-
-for %%i in (%_FILE%) do (
-    call :GenerateLibraryByteCodeHeader %%i
-)
-exit /B %_HASERROR%
-
-:GenerateLibraryBytecodeHeader
-
-echo Generating %1%_suffix%.bc.32b.h
-call :Generate %1 %_BinLocation%\x86_debug %1%_suffix%.bc.32b.h
-echo Generating %1%_suffix%.bc.64b.h
-call :Generate %1 %_BinLocation%\x64_debug %1%_suffix%.bc.64b.h
-exit /B 0
-
-:Generate
-%2\%_binary% -GenerateLibraryByteCodeHeader:%3 -Intl %1
-if "%errorlevel%" NEQ "0" (
-    echo %1: Error generating bytecode file. Ensure %3 writable.
-    set _HASERROR=1
-) else (
-    echo Bytecode generated. Please rebuild to incorporate the new bytecode.
-)

+ 0 - 85
lib/Runtime/Library/JsBuiltIn/GenByteCode.cmd

@@ -1,85 +0,0 @@
-::-------------------------------------------------------------------------------------------------------
-:: Copyright (C) Microsoft. All rights reserved.
-:: Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
-::-------------------------------------------------------------------------------------------------------
-
-@echo off
-setlocal
-set _HASERROR=0
-set _binary=ch.exe
-set _BuildDir=%~dp0..\..\..\..\Build
-
-if "%_FILE%" == "" (
-    set "_FILE=%~dp0*.js"
-)
-
-:ContinueArgParse
-if not [%1]==[] (
-    if [%1]==[-nojit] (
-        set _suffix=.nojit
-        goto :ContinueArgParseEnd
-    )
-    if [%1]==[-binary] (
-        if [%2]==[] (
-            echo Error: no argument supplied to -binary. Exiting ...
-            exit /b 1
-        )
-        set _binary=%2
-        shift
-        goto :ContinueArgParseEnd
-    )
-    if [%1]==[-bindir] (
-        if [%2]==[] (
-            echo Error: no argument supplied to -bindir. Exiting ...
-            exit /b 1
-        )
-        set _BinLocation=%2
-        shift
-        goto :ContinueArgParseEnd
-    )
-
-    :ContinueArgParseEnd
-    shift
-    goto :ContinueArgParse
-)
-
-:: This script will expect %_binary% to be built for x86_debug and x64_debug
-
-if "%OutBaseDir%" NEQ "" (
-    set _BinLocation=%OutBaseDir%\Chakra.Core%_suffix%\bin
-)
-if "%_BinLocation%"=="" (
-    set _BinLocation=%_BuildDir%\VcBuild%_suffix%\bin
-)
-
-if not exist %_BinLocation%\x86_debug\%_binary% (
-    echo Error: %_BinLocation%\x86_debug\%_binary% not found, please build sources. Exiting ...
-    exit /b 1
-)
-
-if not exist %_BinLocation%\x64_debug\%_binary% (
-    echo Error: %_BinLocation%\x64_debug\%_binary% not found, please build sources. Exiting ...
-    exit /b 1
-)
-
-for %%i in (%_FILE%) do (
-    call :GenerateLibraryByteCodeHeader %%i
-)
-exit /B %_HASERROR%
-
-:GenerateLibraryBytecodeHeader
-
-echo Generating %1%_suffix%.bc.32b.h
-call :Generate %1 %_BinLocation%\x86_debug %1%_suffix%.bc.32b.h
-echo Generating %1%_suffix%.bc.64b.h
-call :Generate %1 %_BinLocation%\x64_debug %1%_suffix%.bc.64b.h
-exit /B 0
-
-:Generate
-%2\%_binary% -GenerateLibraryByteCodeHeader:%3 -JsBuiltIn -LdChakraLib %1
-if "%errorlevel%" NEQ "0" (
-    echo %1: Error generating bytecode file. Ensure %3 writable.
-    set _HASERROR=1
-) else (
-    echo Bytecode generated. Please rebuild to incorporate the new bytecode.
-)

+ 10 - 2
test/CMakeLists.txt

@@ -5,11 +5,19 @@ elseif (CMAKE_BUILD_TYPE STREQUAL Debug)
 endif ()
 
 if (NO_ICU)
-    set(TEST_EXCLUDE --not-tag exclude_noicu)
+    set(TEST_ICU --not-tag exclude_noicu)
+endif()
+
+if (BuildJIT)
+    set(VARIANT --jit)
+else ()
+    set(TEST_VARIANT --variants=disable_jit)
+    set(VARIANT --noJit)
 endif()
 
 add_custom_target(check
-    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/runtests.py ${TEST_BUILD_TYPE} ${TEST_EXCLUDE} --binary ${CMAKE_BINARY_DIR}/ch
+    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../tools/regenByteCode.py ${VARIANT} --verify --binary=${CMAKE_BINARY_DIR}/ch
+    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/runtests.py ${TEST_BUILD_TYPE} ${TEST_ICU} ${TEST_VARIANT} --binary ${CMAKE_BINARY_DIR}/ch
     WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
     USES_TERMINAL
     DEPENDS ch

+ 0 - 74
test/Miscellaneous/rlexe.xml

@@ -1,79 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <regress-exe>
-<!-- ByteCode Header verification tests begin -->
-  <test>
-    <default>
-      <files>../../lib/Runtime/Library/JsBuiltIn/JsBuiltIn.js</files>
-      <baseline>../../lib/Runtime/Library/JsBuiltIn/JsBuiltIn.js.bc.32b.h</baseline>
-      <compile-flags>-GenerateLibraryByteCodeHeader -JsBuiltIn -LdChakraLib</compile-flags>
-      <tags>exclude_dynapogo,exclude_x64,exclude_disable_jit,exclude_lite,exclude_forceserialized</tags>
-      <eol-normalization />
-    </default>
-  </test>
-  <test>
-    <default>
-      <files>../../lib/Runtime/Library/JsBuiltIn/JsBuiltIn.js</files>
-      <baseline>../../lib/Runtime/Library/JsBuiltIn/JsBuiltIn.js.bc.64b.h</baseline>
-      <compile-flags>-GenerateLibraryByteCodeHeader -JsBuiltIn -LdChakraLib</compile-flags>
-      <tags>exclude_dynapogo,exclude_x86,exclude_disable_jit,exclude_lite,exclude_forceserialized</tags>
-      <eol-normalization />
-    </default>
-  </test>
-  <test>
-    <default>
-      <files>../../lib/Runtime/Library/JsBuiltIn/JsBuiltIn.js</files>
-      <baseline>../../lib/Runtime/Library/JsBuiltIn/JsBuiltIn.js.nojit.bc.32b.h</baseline>
-      <compile-flags>-GenerateLibraryByteCodeHeader -JsBuiltIn -LdChakraLib</compile-flags>
-      <tags>exclude_x64,require_disable_jit,exclude_forceserialized</tags>
-      <eol-normalization />
-    </default>
-  </test>
-  <test>
-    <default>
-      <files>../../lib/Runtime/Library/JsBuiltIn/JsBuiltIn.js</files>
-      <baseline>../../lib/Runtime/Library/JsBuiltIn/JsBuiltIn.js.nojit.bc.64b.h</baseline>
-      <compile-flags>-GenerateLibraryByteCodeHeader -JsBuiltIn -LdChakraLib</compile-flags>
-      <tags>exclude_x86,require_disable_jit,exclude_forceserialized</tags>
-      <eol-normalization />
-    </default>
-  </test>
-  <test>
-    <default>
-      <files>../../lib/Runtime/Library/InJavascript/Intl.js</files>
-      <baseline>../../lib/Runtime/Library/InJavascript/Intl.js.bc.32b.h</baseline>
-      <compile-flags>-GenerateLibraryByteCodeHeader -Intl</compile-flags>
-      <tags>exclude_dynapogo,exclude_x64,exclude_disable_jit,exclude_lite,exclude_forceserialized</tags>
-      <eol-normalization />
-    </default>
-  </test>
-  <test>
-    <default>
-      <files>../../lib/Runtime/Library/InJavascript/Intl.js</files>
-      <baseline>../../lib/Runtime/Library/InJavascript/Intl.js.bc.64b.h</baseline>
-      <compile-flags>-GenerateLibraryByteCodeHeader -Intl</compile-flags>
-      <tags>exclude_dynapogo,exclude_x86,exclude_disable_jit,exclude_lite,exclude_forceserialized</tags>
-      <eol-normalization />
-    </default>
-  </test>
-  <test>
-    <default>
-      <files>../../lib/Runtime/Library/InJavascript/Intl.js</files>
-      <baseline>../../lib/Runtime/Library/InJavascript/Intl.js.nojit.bc.32b.h</baseline>
-      <compile-flags>-GenerateLibraryByteCodeHeader -Intl</compile-flags>
-      <tags>exclude_x64,require_disable_jit,exclude_lite,exclude_forceserialized</tags>
-      <eol-normalization />
-    </default>
-  </test>
-  <test>
-    <default>
-      <files>../../lib/Runtime/Library/InJavascript/Intl.js</files>
-      <baseline>../../lib/Runtime/Library/InJavascript/Intl.js.nojit.bc.64b.h</baseline>
-      <compile-flags>-GenerateLibraryByteCodeHeader -Intl</compile-flags>
-      <tags>exclude_x86,require_disable_jit,exclude_lite,exclude_forceserialized</tags>
-      <eol-normalization />
-    </default>
-  </test>
-<!-- ByteCode Header verification tests end -->
   <test>
     <default>
       <files>HasOnlyWritableDataPropertiesCache.js</files>

+ 35 - 8
test/jenkins.testone.cmd

@@ -1,5 +1,6 @@
 ::-------------------------------------------------------------------------------------------------------
 :: Copyright (C) Microsoft. All rights reserved.
+:: Copyright (c) 2021 ChakraCore Project Contributors. All rights reserved.
 :: Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
 ::-------------------------------------------------------------------------------------------------------
 
@@ -53,19 +54,26 @@ set _error=0
 
   call :doSilent rd /s/q %_LogDir%
 
-  call :runTests %_TestArgs%
-  if "%_ReducedTestRun%" == "1" (
-    echo -- jenkins.testone.cmd ^>^> Reduced test run: skipping native tests.
-  ) else (
-    call :runNativeTests %_TestArgs%
-  )
+  call :verifyBytcode
+
+  if "%_HadFailures%" == "0" (
+    call :runTests %_TestArgs%
 
-  call :summarizeLogs
+    if "%_ReducedTestRun%" == "1" (
+      echo -- jenkins.testone.cmd ^>^> Reduced test run: skipping native tests.
+    ) else (
+      call :runNativeTests %_TestArgs%
+    )
+
+    call :summarizeLogs
+  )
 
   echo.
   echo -- jenkins.testone.cmd ^>^> Failure code: %_HadFailures%
   if "%_HadFailures%" NEQ "0" (
-    if "%_HadFailures%" == "3" (
+    if "%_HadFailures%" == "2" (
+      echo -- jenkins.testone.cmd ^>^> Bytecode test failed, bytecode needs to be updated! 1>&2
+    ) else if "%_HadFailures%" == "3" (
       echo -- jenkins.testone.cmd ^>^> Unit tests failed! 1>&2
     ) else if "%_HadFailures%" == "4" (
       echo -- jenkins.testone.cmd ^>^> Native tests failed! 1>&2
@@ -82,6 +90,25 @@ set _error=0
 
   goto :eof
 
+:: ============================================================================
+:: Verify that generated bytecode if up to date for one config report if not
+:: ============================================================================
+:verifyBytcode
+
+  set bytecode_type=--jit
+  if "%_SpecialBuild%" == ".NoJIT" (
+    set bytecode_type=--noJit
+  )
+
+  call :do python %_RootDir%\tools\regenByteCode.py --verify %bytecode_type% --%_TestArch% --binary=%_BinDir%\%_TestArch%_%_TestType%\ch.exe
+
+  if "%_error%" NEQ "0" (
+    echo -- jenkins.testone.cmd ^>^> verifying bytecode failed
+    set _HadFailures=2
+  )
+
+  goto :eof
+
 :: ============================================================================
 :: Run one test suite against one build config and record if there were errors
 :: ============================================================================

+ 286 - 0
tools/regenByteCode.py

@@ -0,0 +1,286 @@
+#!/usr/bin/env python
+#-------------------------------------------------------------------------------------------------------
+# Copyright (C) Microsoft. All rights reserved.
+# Copyright (c) 2021 ChakraCore Project Contributors. All rights reserved.
+# Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+#-------------------------------------------------------------------------------------------------------
+
+# Regenerate embedded bytecode headers. This script must be run when:
+# a) Ahy changes have been made to the javascript in lib/Runtime/Library/InJavascript
+# b) Any changes have been made to the bytecode emission process including edits to JnDirectFields.h
+# NOTEs:
+# 1. this script relies on forcing 64bit CC builds to produce 32bit bytecode - this could break due to future
+#    changes to CC. If this facility breaks it will need to be fixed or this script will need to be updated to
+#    use 32 bit builds as well as 64 bit
+# 2. Options:
+#    --skip-build  Don't build CC just generate bytecode with already built binaries
+#    --jit only generate bytecode for CC with jit (default is to do both jit and noJit)
+#    --noJit only generate bytecode for CC with noJit (default is to do both jit and noJit)
+#    --verify throw an error if bytecode changes detected - intended for use in CI
+#    --binary=path provide a path to a binary to use, requires either --jit or --noJit to be set
+#    --x86 specify that provided binary is an x86 build, will generate x86 bytecode only - requires pre-built binary
+# 3. Python version - this script is designed to run on both Python 2.x and 3.x
+
+import subprocess
+import sys
+import uuid
+import os
+
+# Parse provided parameters
+verification_mode = False
+skip_build = False
+noJit = True
+jit = True
+x86 = False
+overide_binary = ""
+
+for param in sys.argv:
+    if param == '--skip-build':
+        skip_build = True
+    elif param == '--verify':
+        # welcome message for CI
+        print('######### Verifying generated bytecode #########')
+        verification_mode = True
+    elif param == '--noJit':
+        jit = False
+    elif param == '--jit':
+        noJit = False
+    elif param == '--x86':
+        x86 = True
+    elif param[:9] == '--binary=':
+        overide_binary = param[9:]
+        skip_build = True
+
+# Detect OS
+windows = False
+if os.name == 'posix':
+    print('OS is Linux or macOS')
+else:
+    print('OS is Windows')
+    windows = True
+
+# If Jit or noJit flag has been give print a message also if both flags given revert to default behaviour
+if jit == False:
+    if noJit == True:
+        print('Regenerating bytecode for no-jit build only')
+    else:
+        noJit = True
+        jit = True
+elif noJit == False:
+    print('Regenerating bytecode for jit build only')
+
+if x86 == True:
+    if overide_binary == "":
+        print('x86 build can only be used when pre-built and provided with the --binary command line parameter')
+        sys.exit(1)
+
+# Adjust path for running from different locations
+base_path = os.path.abspath(os.path.dirname(__file__))
+
+# Compile ChakraCore both noJit and Jit variants (unless disabled by args)
+def run_sub(message, commands, error):
+    print(message)
+    sub = subprocess.Popen(commands, shell=windows)
+    sub.wait()
+    if sub.returncode != 0:
+        print(error)
+        sys.exit(1)
+
+if skip_build == False:
+    # build for linux or macOS with build.sh script - could update to use cmake directly but this works for now
+    if windows == False:
+        if noJit == True:
+            run_sub('Compiling ChakraCore with no Jit',
+                [base_path + '/../build.sh', '--no-jit', '--debug', '--static', '--target-path=' + base_path + '/../out/noJit', '-j=8'], 
+                'No Jit build failed - aborting bytecode generation')
+        if jit == True:
+            run_sub('Compiling ChakraCore with Jit',
+                [base_path + '/../build.sh', '--debug', '--static', '--target-path=' + base_path + '/../out/Jit', '-j=8'], 
+                'Jit build failed - aborting bytecode generation')
+    # build for windows
+    else:
+        if noJit == True:
+            run_sub('Compiling ChakraCore with no Jit',
+                ['msbuild', '/P:platform=x64', '/P:configuration=debug', '/M', '/p:BuildJIT=false', base_path+ '/../Build/Chakra.Core.sln'],
+                'No Jit build failed - aborting bytecode generation')
+        if jit == True:
+            run_sub('Compiling ChakraCore with Jit',
+                ['msbuild', '/P:platform=x64', '/P:configuration=debug', '/M', base_path + '/../Build/Chakra.Core.sln'],
+                'No Jit build failed - aborting bytecode generation')
+
+
+# Generate the new bytecode checking for changes to each file
+# First define variables and methods that will be used then the calls take place below
+changes_detected = False
+
+# this header text will be placed at the top of the generated files
+header_text = '''//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Copyright (c) 2021 ChakraCore Project Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+// Generated Bytecode Header, this file was created by tools/regenByteCode.py
+// This file contains:
+// a) bytecode for Intl library methods implemented in javascript and
+// b) bytecode for other Js library methods, JsBuiltIns, implemented in javascript
+
+#define JsBuiltIns(VALUE)'''
+
+def append_bytecode(header, command, in_path, file_name, error):
+    command_with_file = command[:]
+    command_with_file.append(in_path + file_name)
+    header.write('//Bytecode generated from ' + file_name + '\nconst char Library_Bytecode_')
+    header.write(file_name[:-3])
+    header.flush()
+    job = subprocess.Popen(command_with_file, stdout=header)
+    job.wait()
+    if job.returncode != 0:
+        print(error)
+        sys.exit(1)
+
+# Load file and ensure line endings are '\n' if on windows
+def load_file(path, mode):
+    global windows
+    if windows == True:
+        if sys.version_info[0] < 3:
+            return open(path, mode + 'b')
+        else:
+            return open(path, mode, newline='\n')
+    else:
+        return open(path, mode)
+
+# Regenerate the bytecode
+def bytecode_job(out_path, command, in_path, error):
+    if verification_mode == True:
+        print('Checking bytecode in file ' + out_path)
+    else:
+        print('Generating bytecode in file ' + out_path)
+
+    old_version = ''
+    global changes_detected
+    if changes_detected == False:
+        old_version = load_file(out_path, 'r').read()
+
+    header = load_file(out_path, 'w')
+    header.write(header_text)
+    files = os.listdir(in_path)
+    files.sort()
+    filtered_files = []
+    for file_name in files:
+        if file_name.endswith('.js'):
+            if file_name != 'Intl.js':
+                without_extension = file_name[:-3]
+                parts = without_extension.split('_')
+                header.write(' \\\nVALUE(' + parts[0] + ', ' + parts[1] + ', ' +  parts[0] + parts[1].title() + ')')
+                filtered_files.append(file_name)
+
+    header.write('\n\nnamespace js\n{\n\n#ifdef ENABLE_JS_BUILTINS\n\n')
+
+    # generate bytecode for JsBuiltins
+    command_with_chakra_lib = command[:]
+    command_with_chakra_lib.append('-LdChakraLib')
+    command_with_chakra_lib.append('-JsBuiltIn')
+    for file_name in filtered_files:
+        append_bytecode(header, command_with_chakra_lib, in_path, file_name, error)
+
+    # generate bytecode for Intl
+    command.append('-Intl')
+    header.write('#endif\n\n#ifdef ENABLE_INTL_OBJECT\n\n')
+    append_bytecode(header, command, in_path, 'Intl.js', error)
+
+    header.write('#endif\n\n}\n')
+    header.close()
+    if changes_detected == False:
+        new_version = load_file(out_path, 'r').read()
+        if new_version != old_version:
+            changes_detected = True
+            if verification_mode == True:
+                new_lines = new_version.split('\n')
+                old_lines = old_version.split('\n')
+                max_lines = min(len(new_lines), len(old_lines))
+                for i in range(0, max_lines):
+                    if new_lines[i] != old_lines[i]:
+                        print('Error found - output on line ' + str(i + 1) + ' is:')
+                        print(new_lines[i].replace('\r', '\\r'))
+                        print('Expected output was:')
+                        print(old_lines[i].replace('\r', '\\r'))
+                        break
+
+
+# set paths for binaries - default paths based on build seteps above (different for windows to macOS and linux)
+# OR overridden path provided on command line
+noJitpath = base_path + "/../out/noJit/debug/ch"
+jitPath = base_path + "/../out/jit/debug/ch"
+
+if overide_binary != "":
+    noJitpath = overide_binary
+    jitPath = overide_binary
+    if jit == True and noJit == True:
+        print("Cannot use override binary option without specifying either jit or noJit")
+        sys.exit(1)
+elif windows == True:
+    noJitpath = base_path + '/../Build/VcBuild.NoJIT/bin/x64_debug/ch.exe'
+    jitPath = base_path + '/../Build/VcBuild/bin/x64_debug/ch.exe'
+
+# Call the functions above to generate the bytecode
+if noJit == True:
+    commands = [noJitpath, '-GenerateLibraryByteCodeHeader']
+    if x86 == False:
+        bytecode_job(base_path + '/../lib/Runtime/Library/InJavascript/JsBuiltIn.nojit.bc.64b.h',
+            commands, base_path + '/../lib/Runtime/Library/InJavascript/',
+            'Failed to generate noJit 64bit Bytecode')
+        commands.append('-Force32BitByteCode')
+
+    bytecode_job(base_path + '/../lib/Runtime/Library/InJavascript/JsBuiltIn.nojit.bc.32b.h',
+        commands, base_path + '/../lib/Runtime/Library/InJavascript/',
+        'Failed to generate noJit 32bit JsBuiltin Bytecode')
+
+if jit == True:
+    commands = [jitPath, '-GenerateLibraryByteCodeHeader']
+    if x86 == False:
+        bytecode_job(base_path + '/../lib/Runtime/Library/InJavascript/JsBuiltIn.bc.64b.h',
+            commands, base_path + '/../lib/Runtime/Library/InJavascript/',
+            'Failed to generate 64bit JsBuiltin Bytecode')
+        commands.append('-Force32BitByteCode')
+
+    bytecode_job(base_path + '/../lib/Runtime/Library/InJavascript/JsBuiltIn.bc.32b.h',
+        commands, base_path + '/../lib/Runtime/Library/InJavascript/',
+        'Failed to generate 32bit JsBuiltin Bytecode')
+
+
+# Bytecode regeneration complete - assess changes, report result AND if appropriate generate a new GUID
+if changes_detected == True:
+    if verification_mode == True:
+        print('Bytecode changes detected - the generated bytecode files are not up to date please run tools/regenByteCode.py\n')
+        sys.exit(1)
+    if jit == False or noJit == False:
+        print("Bytecode updated for one variant only - ensure you re-run for both variants before submitting code")
+    else:
+        print('Generating new GUID for new bytecode')
+        guid_header = load_file(base_path + '/../lib/Runtime/Bytecode/ByteCodeCacheReleaseFileVersion.h', 'w')
+        guid = str(uuid.uuid4())
+
+        output_str = '''//-------------------------------------------------------------------------------------------------------
+        // Copyright (C) Microsoft. All rights reserved.
+        // Copyright (c) 2021 ChakraCore Project Contributors. All rights reserved.
+        // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+        //-------------------------------------------------------------------------------------------------------
+        // NOTE: If there is a merge conflict the correct fix is to make a new GUID.
+        // This file was generated with tools/regenByteCode.py
+
+        // {%s}
+        const GUID byteCodeCacheReleaseFileVersion =
+        { 0x%s, 0x%s, 0x%s, {0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s } };
+        ''' % (guid,
+            guid[:8], guid[9:13], guid[14:18], guid[19:21], guid[21:23], guid[24:26],
+            guid[26:28], guid[28:30], guid[30:32], guid[32:34], guid[-2:])
+
+        guid_header.write(output_str)
+
+        print('Bytecode successfully regenerated. Please rebuild ChakraCore to incorporate it.')
+else:
+    if verification_mode == True:
+        print('Bytecode is up to date\n')
+    else:
+        print('Bytecode update was not required')

+ 0 - 39
tools/update_bytecode_version.ps1

@@ -1,39 +0,0 @@
-# -------------------------------------------------------------------------------------------------------
-# Copyright (C) Microsoft. All rights reserved.
-# Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
-# -------------------------------------------------------------------------------------------------------
-
-# Generates a new ByteCodeCacheReleaseFileVersion.h
-$scriptRoot=Split-Path -Path $MyInvocation.MyCommand.Path
-$versionHeader="$scriptRoot\..\lib\Runtime\ByteCode\ByteCodeCacheReleaseFileVersion.h"
-
-Write-Host "Writing file to $versionHeader"
-Remove-Item -Path $versionHeader -Force
-
-function Write-Header() {
-    Write-Output $args | Out-File -Encoding ASCII -Append $versionHeader
-}
-
-$copyright=@"
-//-------------------------------------------------------------------------------------------------------
-// Copyright (C) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
-//-------------------------------------------------------------------------------------------------------
-// NOTE: If there is a merge conflict the correct fix is to make a new GUID.
-// This file was generated with tools\update_bytecode_version.ps1
-
-"@
-
-$version=[Guid]::NewGuid().ToString().ToUpper()
-
-Write-Header $copyright
-Write-Header "// {$version}"
-Write-Header "const GUID byteCodeCacheReleaseFileVersion ="
-
-$version -match "^(\w{8})-(\w{4})-(\w{4})-(\w{4}-\w{12})$" | Out-Null
-$majorParts=$Matches
-$Matches[4] -match "^(\w{2})(\w{2})-(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})$" | Out-Null
-$minorParts=$Matches
-$minorStr="0x{0}, 0x{1}, 0x{2}, 0x{3}, 0x{4}, 0x{5}, 0x{6}, 0x{7}" -f $minorParts[1], $minorParts[2], $minorParts[3], $minorParts[4], $minorParts[5], $minorParts[6], $minorParts[7], $minorParts[8]
-$majorStr="0x{0}, 0x{1}, 0x{2}" -f $majorParts[1], $majorParts[2], $majorParts[3]
-Write-Header "{ $majorStr, { $minorStr } };"

+ 0 - 105
tools/xplatRegenByteCode.py

@@ -1,105 +0,0 @@
-#!/usr/bin/env python
-#-------------------------------------------------------------------------------------------------------
-# Copyright (C) Microsoft. All rights reserved.
-# Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
-#-------------------------------------------------------------------------------------------------------
-
-# Regenerate embedded bytecode headers.
-# NOTEs:
-# 1. this script is for linux and macOS only, on windows please use RegenAllByteCode.cmd AND update_bytecode_version.ps1
-# 2. this script uses paths relative to the tools directory it's in so cd to it before running
-# 3. this script relies on forcing 64bit CC builds to produce 32bit bytecode - this could break due to future changes to CC.
-#    If this facility breaks the CI will fail AND either this will need fixing or bytecode will need to be regenerated using
-#    32 bit builds on windows
-# 4. Run with flag '--skip-build' if the necessary versions of ChakraCore are already built to skip the compilation step
-#    (this is useful if editing the .js files that the bytecode is produced from)
-# Two versions of CC and ch must be compiled for bytecode generation 
-# ch is used to generate bytecode.
-# ch (NoJIT variety) is used to generate NoJIT bytecodes.
-
-import subprocess
-import sys
-import uuid
-
-# Compile ChakraCore both noJit and Jit variants
-def run_sub(message, commands, error):
-    print(message)
-    sub = subprocess.Popen(commands)
-    sub.wait()
-    if sub.returncode != 0:
-        sys.exit(error)
-
-if len(sys.argv) == 1 or sys.argv[1] != '--skip-build':
-    run_sub('Compiling ChakraCore with no Jit',
-        ['../build.sh', '--no-jit', '--test-build', '--target-path=../out/noJit', '-j=2'], 
-        'No Jit build failed - aborting bytecode generation')
-    run_sub('Compiling ChakraCore with Jit',
-        ['../build.sh', '--test-build', '--target-path=../out/Jit', '-j=2'], 
-        'Jit build failed - aborting bytecode generation')
-
-# Regenerate the bytecode
-def bytecode_job(outPath, command, error):
-    header = open(outPath, 'w')
-    job = subprocess.Popen(command, stdout=header)
-    job.wait()
-    if job.returncode != 0:
-        sys.exit(error)
-
-# INTL
-print('Generating INTL bytecode')
-bytecode_job('../lib/Runtime/Library/InJavascript/Intl.js.nojit.bc.64b.h',
-    ['../out/noJit/test/ch', '-GenerateLibraryByteCodeHeader', '-Intl', '../lib/Runtime/Library/InJavascript/Intl.js'],
-    'Failed to generate INTL 64bit noJit bytecode')
-
-bytecode_job('../lib/Runtime/Library/InJavascript/Intl.js.nojit.bc.32b.h',
-    ['../out/noJit/test/ch', '-GenerateLibraryByteCodeHeader', '-Intl', '-Force32BitByteCode','../lib/Runtime/Library/InJavascript/Intl.js'],
-    'Failed to generate INTL 32bit noJit bytecode')
-
-bytecode_job('../lib/Runtime/Library/InJavascript/Intl.js.bc.64b.h',
-    ['../out/Jit/test/ch', '-GenerateLibraryByteCodeHeader', '-Intl', '../lib/Runtime/Library/InJavascript/Intl.js'],
-    'Failed to generate INTL 64bit bytecode')
-
-bytecode_job('../lib/Runtime/Library/InJavascript/Intl.js.bc.32b.h',
-    ['../out/Jit/test/ch', '-GenerateLibraryByteCodeHeader', '-Intl', '-Force32BitByteCode','../lib/Runtime/Library/InJavascript/Intl.js'],
-    'Failed to generate INTL 32bit bytecode')
-
-# JsBuiltin
-print('Generating JsBuiltin Bytecode')
-bytecode_job('../lib/Runtime/Library/JsBuiltin/JsBuiltin.js.nojit.bc.64b.h',
-    ['../out/noJit/test/ch', '-GenerateLibraryByteCodeHeader', '-JsBuiltIn', '-LdChakraLib', '../lib/Runtime/Library/JsBuiltin/JsBuiltin.js'],
-    'Failed to generate noJit 64bit JsBuiltin Bytecode')
-
-bytecode_job('../lib/Runtime/Library/JsBuiltin/JsBuiltin.js.nojit.bc.32b.h',
-    ['../out/noJit/test/ch', '-GenerateLibraryByteCodeHeader', '-JsBuiltIn', '-LdChakraLib', '-Force32BitByteCode', '../lib/Runtime/Library/JsBuiltin/JsBuiltin.js'],
-    'Failed to generate noJit 32bit JsBuiltin Bytecode')
-
-bytecode_job('../lib/Runtime/Library/JsBuiltin/JsBuiltin.js.bc.64b.h',
-    ['../out/Jit/test/ch', '-GenerateLibraryByteCodeHeader', '-JsBuiltIn', '-LdChakraLib', '../lib/Runtime/Library/JsBuiltin/JsBuiltin.js'],
-    'Failed to generate 64bit JsBuiltin Bytecode')
-
-bytecode_job('../lib/Runtime/Library/JsBuiltin/JsBuiltin.js.bc.32b.h',
-    ['../out/Jit/test/ch', '-GenerateLibraryByteCodeHeader', '-JsBuiltIn', '-LdChakraLib', '-Force32BitByteCode', '../lib/Runtime/Library/JsBuiltin/JsBuiltin.js'],
-    'Failed to generate 32bit JsBuiltin Bytecode')
-
-# Bytecode regeneration complete - create a new GUID for it
-print('Generating new GUID for new bytecode')
-guid_header = open('../lib/Runtime/Bytecode/ByteCodeCacheReleaseFileVersion.h', 'w')
-guid = str(uuid.uuid4())
-
-output_str = '''//-------------------------------------------------------------------------------------------------------
-// Copyright (C) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
-//-------------------------------------------------------------------------------------------------------
-// NOTE: If there is a merge conflict the correct fix is to make a new GUID.
-// This file was generated with tools/xplatRegenByteCode.py
-
-// {%s}
-const GUID byteCodeCacheReleaseFileVersion =
-{ 0x%s, 0x%s, 0x%s, {0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s } };
-''' % (guid,
-    guid[:8], guid[9:13], guid[14:18], guid[19:21], guid[21:23], guid[24:26],
-    guid[26:28], guid[28:30], guid[30:32], guid[32:34], guid[-2:])
-
-guid_header.write(output_str)
-
-print('Bytecode successfully regenerated. Please rebuild ChakraCore to incorporate it.')