bool WScriptJsrt::CreateArgumentsObject(JsValueRef *argsObject) { LPWSTR *argv = HostConfigFlags::argsVal; JsValueRef retArr; Assert(argsObject); *argsObject = nullptr; IfJsrtErrorFail(ChakraRTInterface::JsCreateArray(HostConfigFlags::argsCount, &retArr), false); for (int i = 0; i < HostConfigFlags::argsCount; i++) { JsValueRef value; JsValueRef index; char *argNarrow; if (FAILED(WideStringToNarrowDynamic(argv[i], &argNarrow))) { return false; } JsErrorCode errCode = ChakraRTInterface::JsPointerToStringUtf8(argNarrow, strlen(argNarrow), &value); free(argNarrow); IfJsrtErrorFail(errCode, false); IfJsrtErrorFail(ChakraRTInterface::JsDoubleToNumber(i, &index), false); IfJsrtErrorFail(ChakraRTInterface::JsSetIndexedProperty(retArr, index, value), false); } *argsObject = retArr; return true; }
bool WScriptJsrt::CreateNamedFunction(const char* nameString, JsNativeFunction callback, JsValueRef* functionVar) { JsValueRef nameVar; IfJsrtErrorFail(ChakraRTInterface::JsPointerToStringUtf8(nameString, strlen(nameString), &nameVar), false); IfJsrtErrorFail(ChakraRTInterface::JsCreateNamedFunction(nameVar, callback, nullptr, functionVar), false); return true; }
bool WScriptJsrt::InstallObjectsOnObject(JsValueRef object, const char* name, JsNativeFunction nativeFunction) { JsValueRef propertyValueRef; JsPropertyIdRef propertyId; IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromNameUtf8(name, &propertyId), false); CreateNamedFunction(name, nativeFunction, &propertyValueRef); IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(object, propertyId, propertyValueRef, true), false); return true; }
JsValueRef __stdcall WScriptJsrt::QuitCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState) { int exitCode = 0; if (argumentCount > 1) { double exitCodeDouble; IfJsrtErrorFail(ChakraRTInterface::JsNumberToDouble(arguments[1], &exitCodeDouble), JS_INVALID_REFERENCE); exitCode = (int)exitCodeDouble; } ExitProcess(exitCode); }
bool WScriptJsrt::CreateArgumentsObject(JsValueRef *argsObject) { LPWSTR *argv = HostConfigFlags::argsVal; JsValueRef retArr; Assert(argsObject); *argsObject = nullptr; IfJsrtErrorFail(ChakraRTInterface::JsCreateArray(HostConfigFlags::argsCount, &retArr), false); for (int i = 0; i < HostConfigFlags::argsCount; i++) { JsValueRef value; JsValueRef index; IfJsrtErrorFail(ChakraRTInterface::JsPointerToString(argv[i], wcslen(argv[i]), &value), false); IfJsrtErrorFail(ChakraRTInterface::JsDoubleToNumber(i, &index), false); IfJsrtErrorFail(ChakraRTInterface::JsSetIndexedProperty(retArr, index, value), false); } *argsObject = retArr; return true; }
bool WScriptJsrt::Initialize() { HRESULT hr = S_OK; JsValueRef wscript; IfJsrtErrorFail(ChakraRTInterface::JsCreateObject(&wscript), false); IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "Echo", EchoCallback)); IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "Quit", QuitCallback)); IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "LoadScriptFile", LoadScriptFileCallback)); IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "LoadModuleFile", LoadModuleFileCallback)); IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "LoadScript", LoadScriptCallback)); IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "LoadModule", LoadModuleCallback)); IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "SetTimeout", SetTimeoutCallback)); IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "ClearTimeout", ClearTimeoutCallback)); IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "Attach", AttachCallback)); IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "Detach", DetachCallback)); IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "DumpFunctionPosition", DumpFunctionPositionCallback)); IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "RequestAsyncBreak", RequestAsyncBreakCallback)); // ToDo Remove IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "Edit", EmptyCallback)); JsValueRef argsObject; if (!CreateArgumentsObject(&argsObject)) { return false; } JsPropertyIdRef argsName; IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromNameUtf8("Arguments", &argsName), false); IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(wscript, argsName, argsObject, true), false); JsPropertyIdRef wscriptName; IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromNameUtf8("WScript", &wscriptName), false); JsValueRef global; IfJsrtErrorFail(ChakraRTInterface::JsGetGlobalObject(&global), false); IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(global, wscriptName, wscript, true), false); IfFalseGo(WScriptJsrt::InstallObjectsOnObject(global, "print", EchoCallback)); Error: return hr == S_OK; }
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; }
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; }
bool WScriptJsrt::Initialize() { JsValueRef wscript; IfJsrtErrorFail(ChakraRTInterface::JsCreateObject(&wscript), false); JsValueRef echo; JsPropertyIdRef echoPropertyId; const wchar_t* echoString = L"Echo"; CreateNamedFunction(echoString, EchoCallback, &echo); IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromName(echoString, &echoPropertyId), false); IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(wscript, echoPropertyId, echo, true), false); JsValueRef argsObject; if (!CreateArgumentsObject(&argsObject)) { return false; } JsPropertyIdRef argsName; IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromName(L"Arguments", &argsName), false); IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(wscript, argsName, argsObject, true), false); JsValueRef quit; const wchar_t* quitString = L"Quit"; JsPropertyIdRef quitPropertyId; IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromName(quitString, &quitPropertyId), false); CreateNamedFunction(quitString, QuitCallback, &quit); IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(wscript, quitPropertyId, quit, true), false); JsValueRef loadScriptFile; const wchar_t* loadScriptFileString = L"LoadScriptFile"; JsPropertyIdRef loadScriptFilePropertyId; IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromName(loadScriptFileString, &loadScriptFilePropertyId), false); CreateNamedFunction(loadScriptFileString, LoadScriptFileCallback, &loadScriptFile); IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(wscript, loadScriptFilePropertyId, loadScriptFile, true), false); JsValueRef loadModuleFile; const wchar_t* loadModuleFileString = L"LoadModuleFile"; JsPropertyIdRef loadModuleFilePropertyId; IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromName(loadModuleFileString, &loadModuleFilePropertyId), false); CreateNamedFunction(loadModuleFileString, LoadModuleFileCallback, &loadModuleFile); IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(wscript, loadModuleFilePropertyId, loadModuleFile, true), false); JsValueRef loadScript; JsPropertyIdRef loadScriptName; const wchar_t* loadScriptString = L"LoadScript"; IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromName(loadScriptString, &loadScriptName), false); CreateNamedFunction(loadScriptString, LoadScriptCallback, &loadScript); IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(wscript, loadScriptName, loadScript, true), false); JsValueRef loadModule; JsPropertyIdRef loadModuleName; const wchar_t* loadModuleString = L"LoadModule"; IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromName(loadModuleString, &loadModuleName), false); CreateNamedFunction(loadModuleString, LoadModuleCallback, &loadModule); IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(wscript, loadModuleName, loadModule, true), false); JsValueRef setTimeout; JsPropertyIdRef setTimeoutName; const wchar_t* setTimeoutString = L"SetTimeout"; IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromName(setTimeoutString, &setTimeoutName), false); CreateNamedFunction(setTimeoutString, SetTimeoutCallback, &setTimeout); IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(wscript, setTimeoutName, setTimeout, true), false); JsValueRef clearTimeout; JsPropertyIdRef clearTimeoutName; const wchar_t* clearTimeoutString = L"ClearTimeout"; IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromName(clearTimeoutString, &clearTimeoutName), false); CreateNamedFunction(clearTimeoutString, ClearTimeoutCallback, &clearTimeout); IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(wscript, clearTimeoutName, clearTimeout, true), false); JsPropertyIdRef wscriptName; IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromName(L"WScript", &wscriptName), false); JsValueRef global; IfJsrtErrorFail(ChakraRTInterface::JsGetGlobalObject(&global), false); IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(global, wscriptName, wscript, true), false); JsPropertyIdRef printName; IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromName(L"print", &printName), false); IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(global, printName, echo, true), false); return true; }