JsValueRef WScriptJsrt::LoadScriptFileHelper(JsValueRef callee, JsValueRef *arguments, unsigned short argumentCount, bool isSourceModule) { HRESULT hr = E_FAIL; JsValueRef returnValue = JS_INVALID_REFERENCE; JsErrorCode errorCode = JsNoError; LPCWSTR errorMessage = _u(""); if (argumentCount < 2 || argumentCount > 4) { errorCode = JsErrorInvalidArgument; errorMessage = _u("Need more or fewer arguments for WScript.LoadScript"); } else { LPCSTR fileContent; AutoString fileName; AutoString scriptInjectType; size_t fileNameLength; size_t scriptInjectTypeLength; IfJsrtErrorSetGo(ChakraRTInterface::JsStringToPointerUtf8Copy(arguments[1], &fileName, &fileNameLength)); if (argumentCount > 2) { IfJsrtErrorSetGo(ChakraRTInterface::JsStringToPointerUtf8Copy(arguments[2], &scriptInjectType, &scriptInjectTypeLength)); } if (errorCode == JsNoError) { hr = Helpers::LoadScriptFromFile(*fileName, fileContent); if (FAILED(hr)) { fwprintf(stderr, _u("Couldn't load file.\n")); } else { returnValue = LoadScript(callee, *fileName, fileContent, *scriptInjectType ? *scriptInjectType : "self", isSourceModule); } } } Error: if (errorCode != JsNoError) { JsValueRef errorObject; JsValueRef errorMessageString; if (wcscmp(errorMessage, _u("")) == 0) { errorMessage = ConvertErrorCodeToMessage(errorCode); } ERROR_MESSAGE_TO_STRING(errCode, errorMessage, errorMessageString); ChakraRTInterface::JsCreateError(errorMessageString, &errorObject); ChakraRTInterface::JsSetException(errorObject); } return returnValue; }
JsValueRef WScriptJsrt::LoadScriptHelper(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState, bool isSourceModule) { HRESULT hr = E_FAIL; JsErrorCode errorCode = JsNoError; LPCWSTR errorMessage = _u(""); JsValueRef returnValue = JS_INVALID_REFERENCE; if (argumentCount < 2 || argumentCount > 4) { errorCode = JsErrorInvalidArgument; errorMessage = _u("Need more or fewer arguments for WScript.LoadScript"); } else { AutoString fileContent; AutoString fileName; AutoString scriptInjectType; size_t fileContentLength; size_t scriptInjectTypeLength; IfJsrtErrorSetGo(ChakraRTInterface::JsStringToPointerUtf8Copy(arguments[1], &fileContent, &fileContentLength)); if (argumentCount > 2) { IfJsrtErrorSetGo(ChakraRTInterface::JsStringToPointerUtf8Copy(arguments[2], &scriptInjectType, &scriptInjectTypeLength)); if (argumentCount > 3) { size_t unused; IfJsrtErrorSetGo(ChakraRTInterface::JsStringToPointerUtf8Copy(arguments[3], &fileName, &unused)); } } if (*fileContent) { // TODO: This is CESU-8. How to tell the engine? // TODO: How to handle this source (script) life time? returnValue = LoadScript(callee, *fileName, *fileContent, *scriptInjectType ? *scriptInjectType : "self", isSourceModule); } } Error: if (errorCode != JsNoError) { JsValueRef errorObject; JsValueRef errorMessageString; if (wcscmp(errorMessage, _u("")) == 0) { errorMessage = ConvertErrorCodeToMessage(errorCode); } ERROR_MESSAGE_TO_STRING(errCode, errorMessage, errorMessageString); ChakraRTInterface::JsCreateError(errorMessageString, &errorObject); ChakraRTInterface::JsSetException(errorObject); } return returnValue; }
JsValueRef WScriptJsrt::LoadScriptFileHelper(JsValueRef callee, JsValueRef *arguments, unsigned short argumentCount, bool isSourceModule) { HRESULT hr = E_FAIL; JsValueRef returnValue = JS_INVALID_REFERENCE; JsErrorCode errorCode = JsNoError; LPCWSTR errorMessage = L""; if (argumentCount < 2 || argumentCount > 4) { errorCode = JsErrorInvalidArgument; errorMessage = L"Need more or fewer arguments for WScript.LoadScript"; } else { const wchar_t *fileContent; const wchar_t *fileName; const wchar_t *scriptInjectType = L"self"; size_t fileNameLength; size_t scriptInjectTypeLength; IfJsrtErrorSetGo(ChakraRTInterface::JsStringToPointer(arguments[1], &fileName, &fileNameLength)); if (argumentCount > 2) { IfJsrtErrorSetGo(ChakraRTInterface::JsStringToPointer(arguments[2], &scriptInjectType, &scriptInjectTypeLength)); } if (errorCode == JsNoError) { hr = Helpers::LoadScriptFromFile(fileName, fileContent); if (FAILED(hr)) { fwprintf(stderr, L"Couldn't load file.\n"); } else { returnValue = LoadScript(callee, fileName, fileNameLength, fileContent, scriptInjectType, isSourceModule); } } } Error: if (errorCode != JsNoError) { JsValueRef errorObject; JsValueRef errorMessageString; if (wcscmp(errorMessage, L"") == 0) { errorMessage = ConvertErrorCodeToMessage(errorCode); } ChakraRTInterface::JsPointerToString(errorMessage, wcslen(errorMessage), &errorMessageString); ChakraRTInterface::JsCreateError(errorMessageString, &errorObject); ChakraRTInterface::JsSetException(errorObject); } return returnValue; }
JsValueRef WScriptJsrt::LoadScriptHelper(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState, bool isSourceModule) { HRESULT hr = E_FAIL; JsErrorCode errorCode = JsNoError; LPCWSTR errorMessage = L""; JsValueRef returnValue = JS_INVALID_REFERENCE; if (argumentCount < 2 || argumentCount > 4) { errorCode = JsErrorInvalidArgument; errorMessage = L"Need more or fewer arguments for WScript.LoadScript"; } else { const wchar_t *fileContent; const wchar_t *fileName; const wchar_t *scriptInjectType = L"self"; size_t fileContentLength; size_t fileNameLength; size_t scriptInjectTypeLength; IfJsrtErrorSetGo(ChakraRTInterface::JsStringToPointer(arguments[1], &fileContent, &fileContentLength)); if (argumentCount > 2) { IfJsrtErrorSetGo(ChakraRTInterface::JsStringToPointer(arguments[2], &scriptInjectType, &scriptInjectTypeLength)); } fileName = L"script.js"; fileNameLength = wcslen(fileName); if (argumentCount > 3) { IfJsrtErrorSetGo(ChakraRTInterface::JsStringToPointer(arguments[3], &fileName, &fileNameLength)); } returnValue = LoadScript(callee, fileName, fileNameLength, fileContent, scriptInjectType, isSourceModule); } Error: if (errorCode != JsNoError) { JsValueRef errorObject; JsValueRef errorMessageString; if (wcscmp(errorMessage, L"") == 0) { errorMessage = ConvertErrorCodeToMessage(errorCode); } ChakraRTInterface::JsPointerToString(errorMessage, wcslen(errorMessage), &errorMessageString); ChakraRTInterface::JsCreateError(errorMessageString, &errorObject); ChakraRTInterface::JsSetException(errorObject); } return returnValue; }
bool WScriptJsrt::PrintException(LPCSTR fileName, JsErrorCode jsErrorCode) { LPCWSTR errorTypeString = ConvertErrorCodeToMessage(jsErrorCode); JsValueRef exception; ChakraRTInterface::JsGetAndClearException(&exception); if (exception != nullptr) { if (jsErrorCode == JsErrorCode::JsErrorScriptCompile || jsErrorCode == JsErrorCode::JsErrorScriptException) { AutoString errorMessage; size_t errorMessageLength = 0; JsValueRef errorString = JS_INVALID_REFERENCE; IfJsrtErrorFail(ChakraRTInterface::JsConvertValueToString(exception, &errorString), false); IfJsrtErrorFail(ChakraRTInterface::JsStringToPointerUtf8Copy(errorString, &errorMessage, &errorMessageLength), false); AutoWideString wideErrorMessage; NarrowStringToWideDynamic(*errorMessage, &wideErrorMessage); if (jsErrorCode == JsErrorCode::JsErrorScriptCompile) { JsPropertyIdRef linePropertyId = JS_INVALID_REFERENCE; JsValueRef lineProperty = JS_INVALID_REFERENCE; JsPropertyIdRef columnPropertyId = JS_INVALID_REFERENCE; JsValueRef columnProperty = JS_INVALID_REFERENCE; int line; int column; IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromNameUtf8("line", &linePropertyId), false); IfJsrtErrorFail(ChakraRTInterface::JsGetProperty(exception, linePropertyId, &lineProperty), false); IfJsrtErrorFail(ChakraRTInterface::JsNumberToInt(lineProperty, &line), false); IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromNameUtf8("column", &columnPropertyId), false); IfJsrtErrorFail(ChakraRTInterface::JsGetProperty(exception, columnPropertyId, &columnProperty), false); IfJsrtErrorFail(ChakraRTInterface::JsNumberToInt(columnProperty, &column), false); CHAR shortFileName[_MAX_PATH]; CHAR ext[_MAX_EXT]; _splitpath_s(fileName, nullptr, 0, nullptr, 0, shortFileName, _countof(shortFileName), ext, _countof(ext)); fwprintf(stderr, _u("%ls\n\tat code (%S%S:%d:%d)\n"), *wideErrorMessage, shortFileName, ext, (int)line + 1, (int)column + 1); } else { JsValueType propertyType = JsUndefined; JsPropertyIdRef stackPropertyId = JS_INVALID_REFERENCE; JsValueRef stackProperty = JS_INVALID_REFERENCE; AutoString errorStack; size_t errorStackLength = 0; JsErrorCode errorCode = ChakraRTInterface::JsGetPropertyIdFromNameUtf8("stack", &stackPropertyId); if (errorCode == JsErrorCode::JsNoError) { errorCode = ChakraRTInterface::JsGetProperty(exception, stackPropertyId, &stackProperty); if (errorCode == JsErrorCode::JsNoError) { errorCode = ChakraRTInterface::JsGetValueType(stackProperty, &propertyType); } } if (errorCode != JsErrorCode::JsNoError || propertyType == JsUndefined) { const char *fName = fileName != nullptr ? fileName : "(unknown)"; // do not mix char/wchar. print them separately fprintf(stderr, "thrown at %s:\n^\n", fName); fwprintf(stderr, _u("%ls\n"), *wideErrorMessage); } else { IfJsrtErrorFail(ChakraRTInterface::JsStringToPointerUtf8Copy(stackProperty, &errorStack, &errorStackLength), false); AutoWideString wideErrorStack; NarrowStringToWideDynamic(*errorStack, &wideErrorStack); fwprintf(stderr, _u("%ls\n"), *wideErrorStack); } } } else { fwprintf(stderr, _u("Error : %ls\n"), errorTypeString); } return true; } else { fwprintf(stderr, _u("Error : %ls\n"), errorTypeString); } return false; }
JsValueRef WScriptJsrt::LoadScript(JsValueRef callee, LPCSTR fileName, LPCSTR fileContent, LPCSTR scriptInjectType, bool isSourceModule) { HRESULT hr = E_FAIL; JsErrorCode errorCode = JsNoError; LPCWSTR errorMessage = _u("Internal error."); JsValueRef returnValue = JS_INVALID_REFERENCE; JsErrorCode innerErrorCode = JsNoError; JsContextRef currentContext = JS_INVALID_REFERENCE; JsRuntimeHandle runtime = JS_INVALID_RUNTIME_HANDLE; char fullPathNarrow[_MAX_PATH]; size_t len = 0; IfJsrtErrorSetGo(ChakraRTInterface::JsGetCurrentContext(¤tContext)); IfJsrtErrorSetGo(ChakraRTInterface::JsGetRuntime(currentContext, &runtime)); if (fileName) { if (_fullpath(fullPathNarrow, fileName, _MAX_PATH) == nullptr) { IfFailGo(E_FAIL); } // canonicalize that path name to lower case for the profile storage // REVIEW: This doesn't work for UTF8... len = strlen(fullPathNarrow); for (size_t i = 0; i < len; i++) { fullPathNarrow[i] = (char)tolower(fullPathNarrow[i]); } } else { // No fileName provided (WScript.LoadScript()), use dummy "script.js" strcpy_s(fullPathNarrow, "script.js"); } // this is called with LoadModuleCallback method as well where caller pass in a string that should be // treated as a module source text instead of opening a new file. if (isSourceModule || (strcmp(scriptInjectType, "module") == 0)) { errorCode = LoadModuleFromString(fileName, fileContent); } else if (strcmp(scriptInjectType, "self") == 0) { JsContextRef calleeContext; IfJsrtErrorSetGo(ChakraRTInterface::JsGetContextOfObject(callee, &calleeContext)); IfJsrtErrorSetGo(ChakraRTInterface::JsSetCurrentContext(calleeContext)); errorCode = ChakraRTInterface::JsRunScriptUtf8(fileContent, GetNextSourceContext(), fullPathNarrow, &returnValue); if(errorCode == JsNoError) { errorCode = ChakraRTInterface::JsGetGlobalObject(&returnValue); } IfJsrtErrorSetGo(ChakraRTInterface::JsSetCurrentContext(currentContext)); } else if (strcmp(scriptInjectType, "samethread") == 0) { JsValueRef newContext = JS_INVALID_REFERENCE; // Create a new context and set it as the current context IfJsrtErrorSetGo(ChakraRTInterface::JsCreateContext(runtime, &newContext)); IfJsrtErrorSetGo(ChakraRTInterface::JsSetCurrentContext(newContext)); // Initialize the host objects Initialize(); errorCode = ChakraRTInterface::JsRunScriptUtf8(fileContent, GetNextSourceContext(), fullPathNarrow, &returnValue); if (errorCode == JsNoError) { errorCode = ChakraRTInterface::JsGetGlobalObject(&returnValue); } // Set the context back to the old one ChakraRTInterface::JsSetCurrentContext(currentContext); } else { errorCode = JsErrorInvalidArgument; errorMessage = _u("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; ERROR_MESSAGE_TO_STRING(errCode, errorMessage, messageProperty); if (errCode == JsNoError) { errCode = ChakraRTInterface::JsCreateError(messageProperty, &error); if (errCode == JsNoError) { errCode = ChakraRTInterface::JsSetException(error); } } ChakraRTInterface::JsDoubleToNumber(errorCode, &value); } _flushall(); return value; }
bool WScriptJsrt::PrintException(LPCWSTR fileName, JsErrorCode jsErrorCode) { LPCWSTR errorTypeString = ConvertErrorCodeToMessage(jsErrorCode); JsValueRef exception; ChakraRTInterface::JsGetAndClearException(&exception); if (exception != nullptr) { if (jsErrorCode == JsErrorCode::JsErrorScriptCompile || jsErrorCode == JsErrorCode::JsErrorScriptException) { LPCWSTR errorMessage = nullptr; size_t errorMessageLength = 0; JsValueRef errorString = JS_INVALID_REFERENCE; IfJsrtErrorFail(ChakraRTInterface::JsConvertValueToString(exception, &errorString), false); IfJsrtErrorFail(ChakraRTInterface::JsStringToPointer(errorString, &errorMessage, &errorMessageLength), false); if (jsErrorCode == JsErrorCode::JsErrorScriptCompile) { JsPropertyIdRef linePropertyId = JS_INVALID_REFERENCE; JsValueRef lineProperty = JS_INVALID_REFERENCE; JsPropertyIdRef columnPropertyId = JS_INVALID_REFERENCE; JsValueRef columnProperty = JS_INVALID_REFERENCE; int line; int column; IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromName(L"line", &linePropertyId), false); IfJsrtErrorFail(ChakraRTInterface::JsGetProperty(exception, linePropertyId, &lineProperty), false); IfJsrtErrorFail(ChakraRTInterface::JsNumberToInt(lineProperty, &line), false); IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromName(L"column", &columnPropertyId), false); IfJsrtErrorFail(ChakraRTInterface::JsGetProperty(exception, columnPropertyId, &columnProperty), false); IfJsrtErrorFail(ChakraRTInterface::JsNumberToInt(columnProperty, &column), false); WCHAR shortFileName[_MAX_PATH]; WCHAR ext[_MAX_EXT]; _wsplitpath_s(fileName, nullptr, 0, nullptr, 0, shortFileName, _countof(shortFileName), ext, _countof(ext)); fwprintf(stderr, L"%ls\n\tat code (%ls%ls:%d:%d)\n", errorMessage, shortFileName, ext, (int)line + 1, (int)column + 1); } else { JsValueType propertyType = JsUndefined; JsPropertyIdRef stackPropertyId = JS_INVALID_REFERENCE; JsValueRef stackProperty = JS_INVALID_REFERENCE; LPCWSTR errorStack = nullptr; size_t errorStackLength = 0; IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromName(L"stack", &stackPropertyId), false); IfJsrtErrorFail(ChakraRTInterface::JsGetProperty(exception, stackPropertyId, &stackProperty), false); IfJsrtErrorFail(ChakraRTInterface::JsGetValueType(stackProperty, &propertyType), false); if (propertyType == JsUndefined) { fwprintf(stderr, L"%ls\n", errorMessage); } else { IfJsrtErrorFail(ChakraRTInterface::JsStringToPointer(stackProperty, &errorStack, &errorStackLength), false); fwprintf(stderr, L"%ls\n", errorStack); } } } else { fwprintf(stderr, L"Error : %ls\n", errorTypeString); } return true; } else { fwprintf(stderr, L"Error : %ls\n", errorTypeString); } return false; }
JsValueRef WScriptJsrt::LoadScript(JsValueRef callee, LPCWSTR fileName, size_t fileNameLength, LPCWSTR fileContent, LPCWSTR scriptInjectType, bool isSourceModule) { 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; JsContextRef currentContext = JS_INVALID_REFERENCE; JsRuntimeHandle runtime = JS_INVALID_RUNTIME_HANDLE; IfJsrtErrorSetGo(ChakraRTInterface::JsGetCurrentContext(¤tContext)); IfJsrtErrorSetGo(ChakraRTInterface::JsGetRuntime(currentContext, &runtime)); 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) { JsContextRef calleeContext; IfJsrtErrorSetGo(ChakraRTInterface::JsGetContextOfObject(callee, &calleeContext)); IfJsrtErrorSetGo(ChakraRTInterface::JsSetCurrentContext(calleeContext)); if (isSourceModule) { errorCode = ChakraRTInterface::JsRunModule(fileContent, GetNextSourceContext(), fullPath, &returnValue); } else { errorCode = ChakraRTInterface::JsRunScript(fileContent, GetNextSourceContext(), fullPath, &returnValue); } if (errorCode == JsNoError) { errorCode = ChakraRTInterface::JsGetGlobalObject(&returnValue); } IfJsrtErrorSetGo(ChakraRTInterface::JsSetCurrentContext(currentContext)); } else if (wcscmp(scriptInjectType, L"samethread") == 0) { JsValueRef newContext = JS_INVALID_REFERENCE; // Create a new context and set it as the current context IfJsrtErrorSetGo(ChakraRTInterface::JsCreateContext(runtime, &newContext)); IfJsrtErrorSetGo(ChakraRTInterface::JsSetCurrentContext(newContext)); // Initialize the host objects Initialize(); if (isSourceModule) { errorCode = ChakraRTInterface::JsRunModule(fileContent, GetNextSourceContext(), fullPath, &returnValue); } else { errorCode = ChakraRTInterface::JsRunScript(fileContent, GetNextSourceContext(), fullPath, &returnValue); } if (errorCode == JsNoError) { errorCode = ChakraRTInterface::JsGetGlobalObject(&returnValue); } // Set the context back to the old one ChakraRTInterface::JsSetCurrentContext(currentContext); } 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; }