Last active
January 27, 2018 02:04
-
-
Save yuzurihara/db2a6ecb497f334917df893a96d4151a to your computer and use it in GitHub Desktop.
Embedding ChakraCore into Python apps.
This file contains hidden or 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
# -*- 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