Embedding ChakraCore into Python apps.
# -*- coding: utf-8 -*- | |
# Hello World! | |
# see: https://github.com/Microsoft/ChakraCore/wiki/Embedding-ChakraCore | |
from ctypes import * | |
cc = cdll.LoadLibrary('ChakraCore') | |
# typedef void (CALLBACK *JsBackgroundWorkItemCallback)(_In_opt_ void *callbackState); | |
JsBackgroundWorkItemCallback = CFUNCTYPE(None, c_void_p) | |
# typedef bool (CALLBACK *JsThreadServiceCallback)(_In_ JsBackgroundWorkItemCallback callback, _In_opt_ void *callbackState); | |
JsThreadServiceCallback = CFUNCTYPE(c_bool, JsBackgroundWorkItemCallback, c_void_p) | |
# typedef void *JsRuntimeHandle; | |
JsRuntimeHandle = POINTER(c_uint) | |
# typedef void *JsRef; | |
JsRef = POINTER(c_uint) | |
# typedef JsRef JsContextRef; | |
JsContextRef = POINTER(c_uint) | |
# typedef JsRef JsValueRef; | |
JsValueRef = POINTER(c_uint) | |
# typedef DWORD_PTR JsSourceContext; | |
JsSourceContext = c_int64 | |
### | |
### JSRT Const References | |
### | |
JS_INVALID_REFERENCE = JsRef() | |
JS_INVALID_RUNTIME_HANDLE = JsRuntimeHandle() | |
JS_SOURCE_CONTEXT_NONE = JsSourceContext(-1) | |
### | |
### JSRT Enum References | |
## enum JsErrorCode | |
JsErrorCode = c_uint32 | |
JsNoError = 0 | |
... | |
## enum JsRuntimeAttributes | |
JsRuntimeAttributes = c_uint32 | |
JsRuntimeAttributeNone = JsRuntimeAttributes(0x00000000) | |
JsRuntimeAttributeDisableBackgroundWork = JsRuntimeAttributes(0x00000001) | |
JsRuntimeAttributeAllowScriptInterrupt = JsRuntimeAttributes(0x00000002) | |
JsRuntimeAttributeEnableIdleProcessing = JsRuntimeAttributes(0x00000004) | |
JsRuntimeAttributeDisableNativeCodeGeneration = JsRuntimeAttributes(0x00000008) | |
JsRuntimeAttributeDisableEval = JsRuntimeAttributes(0x00000010) | |
JsRuntimeAttributeEnableExperimentalFeatures = JsRuntimeAttributes(0x00000020) | |
JsRuntimeAttributeDispatchSetExceptionsToDebugger = JsRuntimeAttributes(0x00000040) | |
JsRuntimeAttributeDisableFatalOnOOM = JsRuntimeAttributes(0x00000080) | |
### | |
### JSRT API References | |
### | |
""" | |
STDAPI_(JsErrorCode) | |
JsCreateRuntime( | |
_In_ JsRuntimeAttributes attributes, | |
_In_opt_ JsThreadServiceCallback threadService, | |
_Out_ JsRuntimeHandle *runtime); | |
""" | |
JsCreateRuntime = cc.JsCreateRuntime | |
JsCreateRuntime.argtypes = [JsRuntimeAttributes, JsThreadServiceCallback, POINTER(JsRuntimeHandle)] | |
JsCreateRuntime.restype = JsErrorCode | |
""" | |
STDAPI_(JsErrorCode) | |
JsCreateContext( | |
_In_ JsRuntimeHandle runtime, | |
_Out_ JsContextRef *newContext); | |
""" | |
JsCreateContext = cc.JsCreateContext | |
JsCreateContext.argtypes = [JsRuntimeHandle, POINTER(JsContextRef)] | |
JsCreateContext.restype = JsErrorCode | |
""" | |
STDAPI_(JsErrorCode) | |
JsSetCurrentContext( | |
_In_ JsContextRef context); | |
""" | |
JsSetCurrentContext = cc.JsSetCurrentContext | |
JsSetCurrentContext.argtypes = [JsContextRef] | |
JsSetCurrentContext.restype = JsErrorCode | |
""" | |
STDAPI_(JsErrorCode) | |
JsRunScript( | |
_In_z_ const wchar_t *script, | |
_In_ JsSourceContext sourceContext, | |
_In_z_ const wchar_t *sourceUrl, | |
_Out_ JsValueRef *result); | |
""" | |
JsRunScript = cc.JsRunScript | |
JsRunScript.argtypes = [c_wchar_p, JsSourceContext, c_wchar_p, POINTER(JsValueRef)] | |
JsRunScript.restype = JsErrorCode | |
""" | |
STDAPI_(JsErrorCode) | |
JsConvertValueToString( | |
_In_ JsValueRef value, | |
_Out_ JsValueRef *stringValue); | |
""" | |
JsConvertValueToString = cc.JsConvertValueToString | |
JsConvertValueToString.argtypes = [JsValueRef, POINTER(JsValueRef)] | |
JsConvertValueToString.restype = JsErrorCode | |
""" | |
STDAPI_(JsErrorCode) | |
JsStringToPointer( | |
_In_ JsValueRef value, | |
_Outptr_result_buffer_(*stringLength) const wchar_t **stringValue, | |
_Out_ size_t *stringLength); | |
""" | |
JsStringToPointer = cc.JsStringToPointer | |
JsStringToPointer.argtypes = [JsValueRef, POINTER(c_wchar_p), POINTER(c_size_t)] | |
JsStringToPointer.restype = JsErrorCode | |
""" | |
STDAPI_(JsErrorCode) | |
JsDisposeRuntime( | |
_In_ JsRuntimeHandle runtime); | |
""" | |
JsDisposeRuntime = cc.JsDisposeRuntime | |
JsDisposeRuntime.argtypes = [JsRuntimeHandle] | |
JsDisposeRuntime.restype = JsErrorCode | |
def main(): | |
runtime = JsRuntimeHandle() | |
context = JsContextRef() | |
result = JsValueRef() | |
currentSourceContext = 0 | |
empty_str = create_unicode_buffer('') | |
# Your script; try replace hello-world with something else | |
script = create_unicode_buffer("(()=>{return \'Hello world!\';})()") | |
# create a runtime | |
JsCreateRuntime(JsRuntimeAttributeNone, JsThreadServiceCallback(), byref(runtime)) | |
# create an execution context | |
JsCreateContext(runtime, byref(context)) | |
# Now set the current execution context. | |
JsSetCurrentContext(context) | |
# Run the script. | |
JsRunScript(script, currentSourceContext, empty_str, byref(result)) | |
currentSourceContext += 1 | |
# Convert your script result to String in JavaScript; redundant if your script returns a String | |
resultJSString = JsValueRef() | |
JsConvertValueToString(result, byref(resultJSString)) | |
# Project script result back to Python. | |
resultWC = c_wchar_p() | |
stringLength = c_size_t() | |
JsStringToPointer(resultJSString, byref(resultWC), byref(stringLength)) | |
print(wstring_at(resultWC)) | |
# Dispose runtime | |
JsSetCurrentContext(JS_INVALID_REFERENCE); | |
JsDisposeRuntime(runtime); | |
return 0 | |
if __name__=='__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment