Skip to content

Instantly share code, notes, and snippets.

@yuzurihara
Last active January 27, 2018 02:04
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 yuzurihara/db2a6ecb497f334917df893a96d4151a to your computer and use it in GitHub Desktop.
Save yuzurihara/db2a6ecb497f334917df893a96d4151a to your computer and use it in GitHub Desktop.
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