Created
February 12, 2015 17:52
-
-
Save t-mat/becbec46d53652e84177 to your computer and use it in GitHub Desktop.
Windows : JavaScript Runtime Hosting Sample
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// JavaScript Runtime Hosting Sample | |
// https://code.msdn.microsoft.com/windowsdesktop/JavaScript-Runtime-Hosting-d3a13880/ | |
#include <windows.h> | |
#include <jsrt.h> | |
#include <vector> | |
#include <string> | |
#pragma comment(lib, "jsrt.lib") | |
static void ThrowException(const std::wstring& errorString) | |
{ | |
JsValueRef errorValue; | |
JsValueRef errorObject; | |
JsPointerToString(errorString.c_str(), errorString.length(), &errorValue); | |
JsCreateError(errorValue, &errorObject); | |
JsSetException(errorObject); | |
} | |
static JsValueRef CALLBACK Echo( | |
JsValueRef callee | |
, bool isConstructCall | |
, JsValueRef *arguments | |
, unsigned short argumentCount | |
, void *callbackState | |
) { | |
for (auto index = 1u; index < argumentCount; ++index) { | |
if (index > 1) { | |
wprintf(L" "); | |
} | |
JsValueRef stringValue; | |
const auto r0 = JsConvertValueToString(arguments[index], &stringValue); | |
if(r0 != JsNoError) { | |
ThrowException(L"invalid argument"); | |
return JS_INVALID_REFERENCE; | |
} | |
const wchar_t *string; | |
size_t length; | |
const auto r1 = JsStringToPointer(stringValue, &string, &length); | |
if(r1 != JsNoError) { | |
ThrowException(L"invalid argument"); | |
return JS_INVALID_REFERENCE; | |
} | |
wprintf(L"%s", string); | |
} | |
wprintf(L"\n"); | |
return JS_INVALID_REFERENCE; | |
} | |
int main() { | |
_wsetlocale(LC_ALL, L""); | |
std::wstring script = LR"( | |
host.echo('42'); | |
for(var i = 0; i < host.arguments.length; ++i) { | |
host.echo('host.arguments[' + i + '] = ', host.arguments[i]); | |
} | |
)"; | |
const wchar_t* sourceUrl = L"http://localhost/"; | |
std::vector<std::wstring> jsArgs; | |
jsArgs.push_back(L"main_to_js_arg0"); | |
jsArgs.push_back(L"main_to_js_arg1"); | |
JsRuntimeHandle runtime; | |
JsCreateRuntime(JsRuntimeAttributeNone, JsRuntimeVersion11, nullptr, &runtime); | |
JsContextRef context; | |
JsCreateContext(runtime, nullptr, &context); | |
JsSetCurrentContext(context); | |
{ | |
JsValueRef globalObject; | |
JsGetGlobalObject(&globalObject); | |
JsValueRef hostObject; | |
JsCreateObject(&hostObject); | |
JsPropertyIdRef hostPropertyId; | |
JsGetPropertyIdFromName(L"host", &hostPropertyId); | |
JsSetProperty(globalObject, hostPropertyId, hostObject, true); | |
{ | |
const wchar_t* callbackName = L"echo"; | |
JsNativeFunction callbackFunc = Echo; | |
void* callbackArg = nullptr; | |
JsPropertyIdRef propertyId; | |
JsGetPropertyIdFromName(callbackName, &propertyId); | |
JsValueRef function; | |
JsCreateFunction(callbackFunc, callbackArg, &function); | |
JsSetProperty(hostObject, propertyId, function, true); | |
} | |
JsValueRef arguments; | |
JsCreateArray(jsArgs.size(), &arguments); | |
for (auto index = 0u; index < jsArgs.size(); ++index) { | |
const auto* a = jsArgs[index].c_str(); | |
JsValueRef argument; | |
JsPointerToString(a, wcslen(a), &argument); | |
JsValueRef indexValue; | |
JsIntToNumber(index, &indexValue); | |
JsSetIndexedProperty(arguments, indexValue, argument); | |
} | |
JsPropertyIdRef argumentsPropertyId; | |
JsGetPropertyIdFromName(L"arguments", &argumentsPropertyId); | |
JsSetProperty(hostObject, argumentsPropertyId, arguments, true); | |
JsSetCurrentContext(JS_INVALID_REFERENCE); | |
} | |
JsSetCurrentContext(context); | |
const JsErrorCode errorCode = JsRunScript(script.c_str(), 0, sourceUrl, nullptr); | |
if(errorCode == JsErrorScriptException) { | |
JsValueRef exception; | |
JsGetAndClearException(&exception); | |
JsPropertyIdRef messageId; | |
JsGetPropertyIdFromName(L"message", &messageId); | |
JsValueRef messageValue; | |
JsGetProperty(exception, messageId, &messageValue); | |
const wchar_t *message; | |
size_t length; | |
JsStringToPointer(messageValue, &message, &length); | |
wprintf(L"exception: %s\n", message); | |
exit(EXIT_FAILURE); | |
} | |
if(errorCode != JsNoError) { | |
wprintf(L"failed to run script.\n"); | |
exit(EXIT_FAILURE); | |
} | |
JsSetCurrentContext(JS_INVALID_REFERENCE); | |
JsDisposeRuntime(runtime); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment