public ChakraHost() { if (Native.JsCreateRuntime(JavaScriptRuntimeAttributes.None, null, out runtime) != JavaScriptErrorCode.NoError) { throw new Exception("failed to create runtime."); } if (Native.JsCreateContext(runtime, out context) != JavaScriptErrorCode.NoError) { throw new Exception("failed to create execution context."); } if (Native.JsSetCurrentContext(context) != JavaScriptErrorCode.NoError) { throw new Exception("failed to set current context."); } // ES6 Promise callback JavaScriptPromiseContinuationCallback promiseContinuationCallback = delegate(JavaScriptValue task, IntPtr callbackState) { promiseCallback = task; }; if (Native.JsSetPromiseContinuationCallback(promiseContinuationCallback, IntPtr.Zero) != JavaScriptErrorCode.NoError) { throw new Exception("failed to setup callback for ES6 Promise"); } // Bind to global object // setTimeout SetTimeoutJavaScriptNativeFunction = SetTimeout.SetTimeoutJavaScriptNativeFunction; DefineHostCallback("setTimeout", SetTimeoutJavaScriptNativeFunction); SendToHostJavaScriptNativeFunction = CommunicationManager.SendToHostJavaScriptNativeFunction; DefineHostCallback("sendToHost", SendToHostJavaScriptNativeFunction); // Projections if (Native.JsProjectWinRTNamespace("ChakraBridge") != JavaScriptErrorCode.NoError) { throw new Exception("failed to project ChakraBridge namespace."); } this.window = new Window(); ProjectObjectToGlobal(new Console(), "console"); ProjectObjectToGlobal(this.window, "window"); ProjectObjectToGlobal(this.window.navigator, "navigator"); ProjectObjectToGlobal(this.window.document, "document"); // Add references RunScript(@"XMLHttpRequest = ChakraBridge.XMLHttpRequest; HTMLCanvasElement = ChakraBridge.HTMLCanvasElementWrapper; atob = window.atob; btoa = window.btoa;"); #if DEBUG // Debug if (Native.JsStartDebugging() != JavaScriptErrorCode.NoError) { throw new Exception("failed to start debugging."); } #endif }
public string RunScript(string script) { IntPtr returnValue; JavaScriptValue result; if (Native.JsRunScript(script, currentSourceContext++, "", out result) != JavaScriptErrorCode.NoError) { // Get error message and clear exception JavaScriptValue exception; if (Native.JsGetAndClearException(out exception) != JavaScriptErrorCode.NoError) { throw new Exception("failed to get and clear exception"); } JavaScriptPropertyId messageName; if (Native.JsGetPropertyIdFromName("message", out messageName) != JavaScriptErrorCode.NoError) { throw new Exception("failed to get error message id"); } JavaScriptValue messageValue; if (Native.JsGetProperty(exception, messageName, out messageValue) != JavaScriptErrorCode.NoError) { throw new Exception("failed to get error message"); } IntPtr message; UIntPtr length; if (Native.JsStringToPointer(messageValue, out message, out length) != JavaScriptErrorCode.NoError) { throw new Exception("failed to convert error message"); } return(Marshal.PtrToStringUni(message)); } // Execute promise tasks stored in promiseCallback while (promiseCallback.IsValid) { JavaScriptValue task = promiseCallback; promiseCallback = JavaScriptValue.Invalid; JavaScriptValue promiseResult; Native.JsCallFunction(task, null, 0, out promiseResult); } // Convert the return value. JavaScriptValue stringResult; UIntPtr stringLength; if (Native.JsConvertValueToString(result, out stringResult) != JavaScriptErrorCode.NoError) { throw new Exception("failed to convert value to string."); } if (Native.JsStringToPointer(stringResult, out returnValue, out stringLength) != JavaScriptErrorCode.NoError) { throw new Exception("failed to convert return value."); } return(Marshal.PtrToStringUni(returnValue)); }