Skip to content

Instantly share code, notes, and snippets.

@t-mat
Created February 12, 2015 17:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save t-mat/becbec46d53652e84177 to your computer and use it in GitHub Desktop.
Save t-mat/becbec46d53652e84177 to your computer and use it in GitHub Desktop.
Windows : JavaScript Runtime Hosting Sample
// 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