Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebAssembly prototype implementation #63

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.baseline -crlf
*.cmd -crlf
test/*.js -crlf
*.wasm -crlf
26 changes: 25 additions & 1 deletion Build/Chakra.Core.sln
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ChakraCore", "..\bin\ChakraCore\ChakraCore.vcxproj", "{EA882C8D-81FC-42FE-ABD5-2666DB933FDB}"
ProjectSection(ProjectDependencies) = postProject
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD} = {53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{D8216B93-BD6E-4293-8D98-79CEF7CF66BC}"
EndProject
Expand Down Expand Up @@ -56,6 +59,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rl", "..\bin\rl\rl.vcxproj"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Runtime.Base", "..\lib\Runtime\Base\Chakra.Runtime.Base.vcxproj", "{706083F7-6AA4-4558-A153-6352EF9110EE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.WasmReader", "..\lib\WasmReader\Chakra.WasmReader.vcxproj", "{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Expand Down Expand Up @@ -447,6 +452,24 @@ Global
{706083F7-6AA4-4558-A153-6352EF9110EE}.Test|x64.Build.0 = Test|x64
{706083F7-6AA4-4558-A153-6352EF9110EE}.Test|x86.ActiveCfg = Test|Win32
{706083F7-6AA4-4558-A153-6352EF9110EE}.Test|x86.Build.0 = Test|Win32
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Debug|ARM.ActiveCfg = Debug|ARM
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Debug|ARM.Build.0 = Debug|ARM
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Debug|x64.ActiveCfg = Debug|x64
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Debug|x64.Build.0 = Debug|x64
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Debug|x86.ActiveCfg = Debug|Win32
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Debug|x86.Build.0 = Debug|Win32
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Release|ARM.ActiveCfg = Release|ARM
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Release|ARM.Build.0 = Release|ARM
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Release|x64.ActiveCfg = Release|x64
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Release|x64.Build.0 = Release|x64
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Release|x86.ActiveCfg = Release|Win32
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Release|x86.Build.0 = Release|Win32
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Test|ARM.ActiveCfg = Test|ARM
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Test|ARM.Build.0 = Test|ARM
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Test|x64.ActiveCfg = Test|x64
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Test|x64.Build.0 = Test|x64
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Test|x86.ActiveCfg = Test|Win32
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}.Test|x86.Build.0 = Test|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -478,5 +501,6 @@ Global
{0216C4BE-86CE-478D-A134-23EAEE545B9D} = {D3BA0BFC-4757-4B73-994F-3556950884A1}
{80A70F57-0F89-458F-AFD3-CE2159EB9BB1} = {D3BA0BFC-4757-4B73-994F-3556950884A1}
{706083F7-6AA4-4558-A153-6352EF9110EE} = {DDF436E7-0A8E-41AA-82B3-902B5D2D0809}
{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD} = {D8216B93-BD6E-4293-8D98-79CEF7CF66BC}
EndGlobalSection
EndGlobal
4 changes: 4 additions & 0 deletions bin/ChakraCore/ChakraCore.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
$(MSBuildThisFileDirectory);
$(ChakraCoreRootDirectory)Lib\Common;
$(ChakraCoreRootDirectory)Lib\Parser;
$(ChakraCoreRootDirectory)Lib\WasmReader;
$(ChakraCoreRootDirectory)Lib\Runtime;
$(ChakraCoreRootDirectory)Lib\Jsrt;
$(IntDir);
Expand Down Expand Up @@ -117,6 +118,9 @@
<ProjectReference Include="..\..\lib\Runtime\Base\Chakra.Runtime.Base.vcxproj">
<Project>{706083f7-6aa4-4558-a153-6352ef9110ee}</Project>
</ProjectReference>
<ProjectReference Include="..\..\Lib\WasmReader\Chakra.WasmReader.vcxproj">
<Project>{53D52B0B-86D9-4D31-AD09-0D6B3C063ADD}</Project>
</ProjectReference>
<ProjectReference Include="..\..\Lib\Runtime\ByteCode\Chakra.Runtime.ByteCode.vcxproj">
<Project>{706083f7-6aa4-4558-a153-6352ef9110f5}</Project>
</ProjectReference>
Expand Down
74 changes: 74 additions & 0 deletions bin/ch/Helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,77 @@ HRESULT Helpers::LoadScriptFromFile(LPCWSTR filename, LPCWSTR& contents, bool* i

return hr;
}


HRESULT Helpers::LoadBinaryFile(LPCWSTR filename, LPCWSTR& contents, UINT& lengthBytes, bool printFileOpenError)
{
HRESULT hr = S_OK;
contents = nullptr;
lengthBytes = 0;
FILE * file;

//
// Open the file as a binary file to prevent CRT from handling encoding, line-break conversions,
// etc.
//
if (_wfopen_s(&file, filename, L"rb") != 0)
{
if (printFileOpenError)
{
DWORD lastError = GetLastError();
wchar_t wszBuff[512];
fwprintf(stderr, L"Error in opening file '%s' ", filename);
wszBuff[0] = 0;
if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
nullptr,
lastError,
0,
wszBuff,
_countof(wszBuff),
nullptr))
{
fwprintf(stderr, L": %s", wszBuff);
}
fwprintf(stderr, L"\n");
IfFailGo(E_FAIL);
}
else
{
return E_FAIL;
}
}
// file will not be nullptr if _wfopen_s succeeds
__analysis_assume(file != nullptr);

//
// Determine the file length, in bytes.
//
fseek(file, 0, SEEK_END);
lengthBytes = ftell(file);
fseek(file, 0, SEEK_SET);
contents = (LPCWSTR)HeapAlloc(GetProcessHeap(), 0, lengthBytes);
if (nullptr == contents)
{
fwprintf(stderr, L"out of memory");
IfFailGo(E_OUTOFMEMORY);
}
//
// Read the entire content as a binary block.
//
size_t result = fread((void*)contents, sizeof(char), lengthBytes, file);
if (result != lengthBytes)
{
fwprintf(stderr, L"Read error");
IfFailGo(E_FAIL);
}
fclose(file);

Error:
if (contents && FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, (void*)contents);
contents = nullptr;
}

return hr;
}
1 change: 1 addition & 0 deletions bin/ch/Helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ class Helpers
{
public :
static HRESULT LoadScriptFromFile(LPCWSTR filename, LPCWSTR& contents, bool* isUtf8Out = nullptr, LPCWSTR* contentsRawOut = nullptr, UINT* lengthBytesOut = nullptr, bool printFileOpenError = true);
static HRESULT LoadBinaryFile(LPCWSTR filename, LPCWSTR& contents, UINT& lengthBytes, bool printFileOpenError = true);
};
138 changes: 138 additions & 0 deletions bin/ch/WScriptJsrt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,11 +398,149 @@ bool WScriptJsrt::CreateNamedFunction(const wchar_t* nameString, JsNativeFunctio
return true;
}

#ifdef ENABLE_WASM
JsValueRef __stdcall WScriptJsrt::LoadWasmCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
{
HRESULT hr = E_FAIL;
JsValueRef returnValue = JS_INVALID_REFERENCE;
JsErrorCode errorCode = JsNoError;

if (argumentCount < 2 || argumentCount > 4)
{
fwprintf(stderr, L"Too many or too few arguments.\n");
}
else
{
const wchar_t *fileContent;
const wchar_t *fileName;
const wchar_t *scriptInjectType = L"self";
size_t fileNameLength;
size_t scriptInjectTypeLength;
bool isBinaryFormat = false;

IfJsrtErrorSetGo(ChakraRTInterface::JsStringToPointer(arguments[1], &fileName, &fileNameLength));

if (argumentCount > 2)
{
IfJsrtErrorSetGo(ChakraRTInterface::JsBooleanToBool(arguments[2], &isBinaryFormat));
}


if (argumentCount > 3)
{
IfJsrtErrorSetGo(ChakraRTInterface::JsStringToPointer(arguments[3], &scriptInjectType, &scriptInjectTypeLength));
}


if (errorCode == JsNoError)
{
HRESULT hr;
UINT lengthBytes = 0;

if (!isBinaryFormat)
{
hr = Helpers::LoadScriptFromFile(fileName, fileContent);
}
else
{
hr = Helpers::LoadBinaryFile(fileName, fileContent, lengthBytes);
}
if (FAILED(hr))
{
fwprintf(stderr, L"Couldn't load file.\n");
}
else
{
returnValue = LoadWasm(fileName, fileNameLength, fileContent, isBinaryFormat, lengthBytes, scriptInjectType);
}
}
}

Error:
return returnValue;
}

JsValueRef WScriptJsrt::LoadWasm(LPCWSTR fileName, size_t fileNameLength, LPCWSTR fileContent, const bool isBinary, const UINT lengthBytes, LPCWSTR scriptInjectType)
{
HRESULT hr = E_FAIL;
JsErrorCode errorCode = JsNoError;
LPCWSTR errorMessage = L"Internal error.";
size_t errorMessageLength = wcslen(errorMessage);
JsValueRef returnValue = JS_INVALID_REFERENCE;
JsErrorCode innerErrorCode = JsNoError;

wchar_t fullPath[_MAX_PATH];
if (_wfullpath(fullPath, fileName, _MAX_PATH) == nullptr)
{
IfFailGo(E_FAIL);
}
// canonicalize that path name to lower case for the profile storage
size_t len = wcslen(fullPath);
for (size_t i = 0; i < len; i++)
{
fullPath[i] = towlower(fullPath[i]);
}

if (wcscmp(scriptInjectType, L"self") == 0)
{
errorCode = ChakraRTInterface::JsRunWasmScript(fileContent, 0, fullPath, isBinary, lengthBytes, &returnValue);
if (errorCode != JsNoError)
{
PrintException(fileName, errorCode);
}
}
else
{
errorCode = JsErrorInvalidArgument;
errorMessage = L"Unsupported argument type inject type.";
}


Error:
JsValueRef value = returnValue;
if (errorCode != JsNoError)
{
if (innerErrorCode != JsNoError)
{
// Failed to retrieve the inner error message, so set a custom error string
errorMessage = ConvertErrorCodeToMessage(errorCode);
}

JsValueRef error = JS_INVALID_REFERENCE;
JsValueRef messageProperty = JS_INVALID_REFERENCE;
errorMessageLength = wcslen(errorMessage);
innerErrorCode = ChakraRTInterface::JsPointerToString(errorMessage, errorMessageLength, &messageProperty);
if (innerErrorCode == JsNoError)
{
innerErrorCode = ChakraRTInterface::JsCreateError(messageProperty, &error);
if (innerErrorCode == JsNoError)
{
innerErrorCode = ChakraRTInterface::JsSetException(error);
}
}

ChakraRTInterface::JsDoubleToNumber(errorCode, &value);
}

_flushall();

return value;
}
#endif

bool WScriptJsrt::Initialize()
{
JsValueRef wscript;
IfJsrtErrorFail(ChakraRTInterface::JsCreateObject(&wscript), false);

#ifdef ENABLE_WASM
JsValueRef loadWasm;
IfJsrtErrorFail(ChakraRTInterface::JsCreateFunction(LoadWasmCallback, nullptr, &loadWasm), false);
JsPropertyIdRef loadWasmName;
IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromName(L"LoadWasmFile", &loadWasmName), false);
IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(wscript, loadWasmName, loadWasm, true), false);
#endif

JsValueRef echo;
JsPropertyIdRef echoPropertyId;
const wchar_t* echoString = L"Echo";
Expand Down
8 changes: 8 additions & 0 deletions bin/ch/WScriptJsrt.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ class WScriptJsrt
static JsValueRef LoadScript(JsValueRef callee, LPCWSTR fileName, size_t fileNameLength, LPCWSTR fileContent, LPCWSTR scriptInjectType);
static DWORD_PTR GetNextSourceContext();

#ifdef ENABLE_WASM
static JsValueRef LoadWasm(LPCWSTR fileName, size_t fileNameLength, LPCWSTR fileContent, const bool isBinary, const UINT lengthBytes, LPCWSTR scriptInjectType);
#endif
private:
static bool CreateArgumentsObject(JsValueRef *argsObject);
static bool CreateNamedFunction(const wchar_t*, JsNativeFunction callback, JsValueRef* functionVar);
Expand All @@ -61,6 +64,11 @@ class WScriptJsrt
static JsValueRef __stdcall LoadScriptCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);
static JsValueRef __stdcall SetTimeoutCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);
static JsValueRef __stdcall ClearTimeoutCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);

#ifdef ENABLE_WASM
static JsValueRef __stdcall LoadWasmCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);
#endif

static MessageQueue *messageQueue;
static DWORD_PTR sourceContext;
};
3 changes: 3 additions & 0 deletions bin/ch/chakrartinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ HINSTANCE ChakraRTInterface::LoadChakraDll(ArgInfo& argInfo)
m_jsApiHooks.pfJsrtGetProperty = (JsAPIHooks::JsrtGetPropertyPtr)GetProcAddress(library, "JsGetProperty");
m_jsApiHooks.pfJsrtHasProperty = (JsAPIHooks::JsrtHasPropertyPtr)GetProcAddress(library, "JsHasProperty");
m_jsApiHooks.pfJsrtRunScript = (JsAPIHooks::JsrtRunScriptPtr)GetProcAddress(library, "JsRunScript");
#ifdef ENABLE_WASM
m_jsApiHooks.pfJsrtRunWasmScript = (JsAPIHooks::JsrtRunWasmScriptPtr)GetProcAddress(library, "JsRunWasmScript");
#endif
m_jsApiHooks.pfJsrtCallFunction = (JsAPIHooks::JsrtCallFunctionPtr)GetProcAddress(library, "JsCallFunction");
m_jsApiHooks.pfJsrtNumbertoDouble = (JsAPIHooks::JsrtNumberToDoublePtr)GetProcAddress(library, "JsNumberToDouble");
m_jsApiHooks.pfJsrtNumbertoInt = (JsAPIHooks::JsrtNumberToIntPtr)GetProcAddress(library, "JsNumberToInt");
Expand Down
5 changes: 5 additions & 0 deletions bin/ch/chakrartinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ struct JsAPIHooks
typedef JsErrorCode (WINAPI *JsrtGetPropertyPtr)(JsValueRef object, JsPropertyIdRef property, JsValueRef* value);
typedef JsErrorCode (WINAPI *JsrtHasPropertyPtr)(JsValueRef object, JsPropertyIdRef property, bool *hasProperty);
typedef JsErrorCode (WINAPI *JsrtRunScriptPtr)(const wchar_t *script, DWORD_PTR sourceContext, const wchar_t *sourceUrl, JsValueRef* result);
typedef JsErrorCode(WINAPI *JsrtRunWasmScriptPtr)(const wchar_t *script, DWORD_PTR sourceContext, const wchar_t *sourceUrl, const bool isBinary, const UINT lengthBytes, JsValueRef* result);
typedef JsErrorCode (WINAPI *JsrtCallFunctionPtr)(JsValueRef function, JsValueRef* arguments, unsigned short argumentCount, JsValueRef *result);
typedef JsErrorCode (WINAPI *JsrtNumberToDoublePtr)(JsValueRef value, double *doubleValue);
typedef JsErrorCode (WINAPI *JsrtNumberToIntPtr)(JsValueRef value, int *intValue);
Expand Down Expand Up @@ -71,6 +72,7 @@ struct JsAPIHooks
JsrtGetPropertyPtr pfJsrtGetProperty;
JsrtHasPropertyPtr pfJsrtHasProperty;
JsrtRunScriptPtr pfJsrtRunScript;
JsrtRunWasmScriptPtr pfJsrtRunWasmScript;
JsrtCallFunctionPtr pfJsrtCallFunction;
JsrtNumberToDoublePtr pfJsrtNumbertoDouble;
JsrtNumberToIntPtr pfJsrtNumbertoInt;
Expand Down Expand Up @@ -176,6 +178,9 @@ class ChakraRTInterface
static JsErrorCode WINAPI JsGetProperty(JsValueRef object, JsPropertyIdRef property, JsValueRef* value) { return m_jsApiHooks.pfJsrtGetProperty(object, property, value); }
static JsErrorCode WINAPI JsHasProperty(JsValueRef object, JsPropertyIdRef property, bool *hasProperty) { return m_jsApiHooks.pfJsrtHasProperty(object, property, hasProperty); }
static JsErrorCode WINAPI JsRunScript(const wchar_t *script, DWORD_PTR sourceContext, const wchar_t *sourceUrl, JsValueRef* result) { return m_jsApiHooks.pfJsrtRunScript(script, sourceContext, sourceUrl, result); }
#ifdef ENABLE_WASM
static JsErrorCode WINAPI JsRunWasmScript(const wchar_t *script, DWORD_PTR sourceContext, const wchar_t *sourceUrl, const bool isBinary, const UINT lengthBytes, JsValueRef* result) { return m_jsApiHooks.pfJsrtRunWasmScript(script, sourceContext, sourceUrl, isBinary, lengthBytes, result); }
#endif
static JsErrorCode WINAPI JsCallFunction(JsValueRef function, JsValueRef* arguments, unsigned short argumentCount, JsValueRef *result) { return m_jsApiHooks.pfJsrtCallFunction(function, arguments, argumentCount, result); }
static JsErrorCode WINAPI JsNumberToDouble(JsValueRef value, double* doubleValue) { return m_jsApiHooks.pfJsrtNumbertoDouble(value, doubleValue); }
static JsErrorCode WINAPI JsNumberToInt(JsValueRef value, int* intValue) { return m_jsApiHooks.pfJsrtNumbertoInt(value, intValue); }
Expand Down
1 change: 1 addition & 0 deletions jenkins.check_copyright.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ git diff --name-only `git merge-base origin/master HEAD` HEAD |
grep -v -E '\.txt$' |
grep -v -E '\.baseline$' |
grep -v -E '\.sln$' |
grep -v -E '\.wasm$' |
grep -v -E '\.vcxproj$' |
grep -v -E '\.filters$' |
grep -v -E '\.targets$' |
Expand Down
7 changes: 6 additions & 1 deletion jenkins.check_eol.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ fi
ERRFILE=jenkins.check_eol.sh.err
rm -f $ERRFILE

git diff --name-only `git merge-base origin/master HEAD` HEAD | grep -v -E "(test/.*\\.js|\\.cmd|\\.baseline)" | xargs -I % ./jenkins.check_file_eol.sh %
git diff --name-only `git merge-base origin/master HEAD` HEAD |
grep -v -E 'test/.*\.js$' |
grep -v -E '\.cmd$' |
grep -v -E '\.wasm$' |
grep -v -E '\.baseline$' |
xargs -I % ./jenkins.check_file_eol.sh %

if [ -e $ERRFILE ]; then # if error file exists then there were errors
>&2 echo "--------------" # leading >&2 means echo to stderr
Expand Down
Loading