Ver Fonte

Add unit test to regenerate bytecode header to verify that what the current build generates matches with the current header file.

Michael Ferris há 8 anos atrás
pai
commit
ff2b64bc03
4 ficheiros alterados com 83 adições e 47 exclusões
  1. 43 47
      bin/ch/ch.cpp
  2. 34 0
      test/Miscellaneous/rlexe.xml
  3. 2 0
      test/runtests.cmd
  4. 4 0
      test/runtests.py

+ 43 - 47
bin/ch/ch.cpp

@@ -5,6 +5,7 @@
 #include "stdafx.h"
 #include "Core/AtomLockGuids.h"
 #include <CommonPal.h>
+#include <regex>
 #ifdef _WIN32
 #include <winver.h>
 #include <process.h>
@@ -172,7 +173,7 @@ Error:
     return hr;
 }
 
-HRESULT CreateLibraryByteCodeHeader(LPCSTR contentsRaw, JsFinalizeCallback contentsRawFinalizeCallback, DWORD lengthBytes, LPCWSTR bcFullPath, LPCSTR libraryNameNarrow)
+HRESULT CreateLibraryByteCodeHeader(LPCSTR contentRaw, JsFinalizeCallback contentsRawFinalizeCallback, DWORD lengthBytes, LPCWSTR bcFullPath, LPCSTR libraryNameNarrow)
 {
     HANDLE bcFileHandle = nullptr;
     JsValueRef bufferVal;
@@ -181,51 +182,53 @@ HRESULT CreateLibraryByteCodeHeader(LPCSTR contentsRaw, JsFinalizeCallback conte
     DWORD written;
     // For validating the header file against the library file
     auto outputStr =
-        "//-------------------------------------------------------------------------------------------------------\r\n"
-        "// Copyright (C) Microsoft. All rights reserved.\r\n"
-        "// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.\r\n"
-        "//-------------------------------------------------------------------------------------------------------\r\n"
-        "#if 0\r\n";
-
+        "//-------------------------------------------------------------------------------------------------------\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::regex r("\r");
+    auto normalizedContentStr = std::regex_replace(contentRaw, r, "");
+    // We no longer need contentsRaw, so call the finalizer for it if one was provided
+    if (contentsRawFinalizeCallback != nullptr)
+    {
+        contentsRawFinalizeCallback((void*)contentRaw);
+    }
 
+    const char* normalizedContent = normalizedContentStr.c_str();
     // We still need contentsRaw after this, so pass a null finalizeCallback into it
-    HRESULT hr = GetSerializedBuffer(contentsRaw, nullptr, &bufferVal);
+    HRESULT hr = GetSerializedBuffer(normalizedContent, nullptr, &bufferVal);
 
     IfFailedGoLabel((hr), ErrorRunFinalize);
 
     IfJsrtErrorHRLabel(ChakraRTInterface::JsGetArrayBufferStorage(bufferVal, &bcBuffer, &bcBufferSize), ErrorRunFinalize);
 
-    bcFileHandle = CreateFile(bcFullPath, GENERIC_WRITE, FILE_SHARE_DELETE,
-        nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
-    if (bcFileHandle == INVALID_HANDLE_VALUE)
+    if (bcFullPath)
     {
-        IfFailedGoLabel(E_FAIL, ErrorRunFinalize);
-    }
-
-    IfFalseGoLabel(WriteFile(bcFileHandle, outputStr, (DWORD)strlen(outputStr), &written, nullptr), ErrorRunFinalize);
-    IfFalseGoLabel(WriteFile(bcFileHandle, contentsRaw, lengthBytes, &written, nullptr), ErrorRunFinalize);
-    if (lengthBytes < 2 || contentsRaw[lengthBytes - 2] != '\r' || contentsRaw[lengthBytes - 1] != '\n')
-    {
-        outputStr = "\r\n#endif\r\n";
+        bcFileHandle = CreateFile(bcFullPath, GENERIC_WRITE, FILE_SHARE_DELETE,
+            nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
     }
     else
     {
-        outputStr = "#endif\r\n";
+        bcFileHandle = GetStdHandle(STD_OUTPUT_HANDLE);
     }
-    
-    // We no longer need contentsRaw, so call the finalizer for it if one was provided
-    if(contentsRawFinalizeCallback != nullptr)
+    if (bcFileHandle == INVALID_HANDLE_VALUE)
     {
-        contentsRawFinalizeCallback((void*)contentsRaw);
+        IfFailedGoLabel(E_FAIL, ErrorRunFinalize);
     }
 
+    IfFalseGoLabel(WriteFile(bcFileHandle, outputStr, (DWORD)strlen(outputStr), &written, nullptr), ErrorRunFinalize);
+    IfFalseGoLabel(WriteFile(bcFileHandle, normalizedContent, (DWORD)normalizedContentStr.size(), &written, nullptr), ErrorRunFinalize);
+    outputStr = "\n#endif\n";
+
     IfFalseGo(WriteFile(bcFileHandle, outputStr, (DWORD)strlen(outputStr), &written, nullptr));
 
     // Write out the bytecode
-    outputStr = "namespace Js\r\n{\r\n    const char Library_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 = "[] = {\r\n/* 00000000 */";
+    outputStr = "[] = {\n/* 00000000 */";
     IfFalseGo(WriteFile(bcFileHandle, outputStr, (DWORD)strlen(outputStr), &written, nullptr));
 
     for (unsigned int i = 0; i < bcBufferSize; i++)
@@ -249,24 +252,17 @@ HRESULT CreateLibraryByteCodeHeader(LPCSTR contentsRaw, JsFinalizeCallback conte
         if (i % 16 == 15 && i < bcBufferSize - 1)
         {
             char offset[17];
-            _snprintf_s(offset, sizeof(offset), _countof(offset), "\r\n/* %08X */", i + 1);  // close quote, new line, offset and open quote
-            IfFalseGo(WriteFile(bcFileHandle, offset, (DWORD)strlen(offset), &written, nullptr));
+            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));
         }
     }
-    outputStr = "};\r\n\r\n";
+    outputStr = "};\n\n";
     IfFalseGo(WriteFile(bcFileHandle, outputStr, (DWORD)strlen(outputStr), &written, nullptr));
 
-    outputStr = "}\r\n";
+    outputStr = "}\n";
     IfFalseGo(WriteFile(bcFileHandle, outputStr, (DWORD)strlen(outputStr), &written, nullptr));
 
-    if(false)
-    {
 ErrorRunFinalize:
-        if(contentsRawFinalizeCallback != nullptr)
-        {
-            contentsRawFinalizeCallback((void*)contentsRaw);
-        }
-    }
 Error:
     if (bcFileHandle != nullptr)
     {
@@ -716,19 +712,19 @@ HRESULT ExecuteTest(const char* fileName)
         len = strlen(fullPath);
         if (HostConfigFlags::flags.GenerateLibraryByteCodeHeaderIsEnabled)
         {
-            if (HostConfigFlags::flags.GenerateLibraryByteCodeHeader != nullptr && *HostConfigFlags::flags.GenerateLibraryByteCodeHeader != _u('\0'))
-            {
-                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));
-            }
-            else
+            if (HostConfigFlags::flags.GenerateLibraryByteCodeHeader != nullptr)
             {
-                fwprintf(stderr, _u("FATAL ERROR: -GenerateLibraryByteCodeHeader must provide the file name, i.e., -GenerateLibraryByteCodeHeader:<bytecode file name>, exiting\n"));
-                IfFailGo(E_FAIL);
+                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));
         }
         else if (HostConfigFlags::flags.SerializedIsEnabled)
         {

+ 34 - 0
test/Miscellaneous/rlexe.xml

@@ -1,5 +1,39 @@
 <?xml version="1.0" encoding="utf-8"?>
 <regress-exe>
+<!-- ByteCode Header verification tests begin -->
+  <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_jshost,exclude_dynapogo,exclude_amd64,exclude_disable_jit</tags>
+    </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_jshost,exclude_dynapogo,exclude_x86,exclude_disable_jit</tags>
+    </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_jshost,exclude_amd64,require_disable_jit</tags>
+    </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_jshost,exclude_x86,require_disable_jit</tags>
+    </default>
+  </test>
+<!-- ByteCode Header verification tests end -->
   <test>
     <default>
       <files>HasOnlyWritableDataPropertiesCache.js</files>

+ 2 - 0
test/runtests.cmd

@@ -400,6 +400,8 @@ goto :main
   if "%_TESTCONFIG%"=="disable_jit" (
     set EXTRA_CC_FLAGS=%EXTRA_CC_FLAGS% -nonative
     set EXTRA_RL_FLAGS=-nottags:exclude_interpreted -nottags:fails_interpreted -nottags:require_backend
+  ) else (
+    set EXTRA_RL_FLAGS=%EXTRA_RL_FLAGS% -nottags:require_disable_jit
   )
   if "%_TESTCONFIG%"=="dynapogo"    (
     set EXTRA_CC_FLAGS=%EXTRA_CC_FLAGS% -forceNative -off:simpleJit -bgJitDelay:0 %_dynamicprofileinput%

+ 4 - 0
test/runtests.py

@@ -689,10 +689,14 @@ def main():
         TestVariant('interpreted', [
                 '-maxInterpretCount:1', '-maxSimpleJitRunCount:1', '-bgjit-',
                 '-dynamicprofilecache:profile.dpl.${id}'
+            ], [
+                'require_disable_jit'
             ]),
         TestVariant('dynapogo', [
                 '-forceNative', '-off:simpleJit', '-bgJitDelay:0',
                 '-dynamicprofileinput:profile.dpl.${id}'
+            ], [
+                'require_disable_jit'
             ]),
         TestVariant('disable_jit', [
                 '-nonative'