Skip to content

Commit d024508

Browse files
committed
add: python extension
1 parent 7ecdbda commit d024508

File tree

5 files changed

+158
-0
lines changed

5 files changed

+158
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
obj/
22

3+
pyext/build/
34
*.dll
45
*.exe
56

pyext/QJS.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#include <Python.h>
2+
#include <stdio.h>
3+
#include "libqjs.h"
4+
5+
6+
static PyObject* qjs_init(PyObject* self, PyObject *args) {
7+
8+
return Py_BuildValue("b", 0);
9+
}
10+
11+
static PyObject* qjs_runcode(PyObject* self, PyObject *args) {
12+
JSRuntime *rt;
13+
JSContext *ctx;
14+
const char *s;
15+
char *code;
16+
JSValue val, global_obj;
17+
int ret, tag, code_len, has_module=0, eval_flags;
18+
19+
if (!PyArg_ParseTuple(args, "s", &code))
20+
return NULL;
21+
code_len = strlen(code);
22+
rt = JS_NewRuntime();
23+
ctx = JS_NewContext(rt);
24+
25+
/* loader for ES6 modules */
26+
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
27+
28+
js_std_add_helpers(ctx, 0, NULL); // int argc, char **argv
29+
30+
/* system modules */
31+
js_init_module_std(ctx, "std");
32+
js_init_module_os(ctx, "os");
33+
34+
has_module = JS_DetectModule((const char *)code, code_len);
35+
36+
if (has_module)
37+
eval_flags = JS_EVAL_TYPE_MODULE;
38+
else
39+
eval_flags = JS_EVAL_TYPE_GLOBAL;
40+
41+
if ((eval_flags & JS_EVAL_TYPE_MASK) == JS_EVAL_TYPE_MODULE) {
42+
/* for the modules, we compile then run to be able to set
43+
import.meta */
44+
val = JS_Eval(ctx, code, code_len, "<input>",
45+
eval_flags | JS_EVAL_FLAG_COMPILE_ONLY);
46+
47+
if (JS_IsException(val)) {
48+
49+
js_std_dump_error(ctx);
50+
return NULL;
51+
}
52+
53+
js_module_set_import_meta(ctx, val, 1, 1);
54+
val = JS_EvalFunction(ctx, val);
55+
// 如果包含模块,返回值要写入全局变量
56+
global_obj = JS_GetGlobalObject(ctx);
57+
val = JS_GetPropertyStr(ctx, global_obj, "_r");
58+
JS_FreeValue(ctx, global_obj);
59+
} else { // 不包含模块,直接运行
60+
val = JS_Eval(ctx, code, code_len, "<input>", eval_flags);
61+
}
62+
// // buf, buf_len, filename, eval_flags
63+
// val = JS_Eval(ctx, code, strlen(code), "<input>", -1);
64+
65+
if (JS_IsException(val)) {
66+
js_std_dump_error(ctx);
67+
return NULL;
68+
}
69+
70+
tag = JS_VALUE_GET_TAG(val);
71+
72+
s = JS_ToCString(ctx, val);
73+
74+
JS_FreeValue(ctx, val);
75+
// printf("return val[%d]: %s \n", tag, s);
76+
77+
js_std_free_handlers(rt);
78+
JS_FreeContext(ctx);
79+
JS_FreeRuntime(rt);
80+
81+
return Py_BuildValue("s", s);
82+
83+
}
84+
85+
static PyMethodDef qjs_funcs[] = {
86+
{"init", (PyCFunction)qjs_init, METH_VARARGS, "helloworld_docs"},
87+
{"eval_js", (PyCFunction)qjs_runcode, METH_VARARGS, "helloworld_docs"},
88+
{NULL, NULL, 0, NULL}
89+
};
90+
91+
static PyModuleDef qjs_module = {
92+
PyModuleDef_HEAD_INIT,
93+
"qjs", /* name of module */
94+
NULL, /* module documentation, may be NULL */
95+
-1, /* size of per-interpreter state of the module,
96+
or -1 if the module keeps state in global variables. */
97+
qjs_funcs
98+
};
99+
100+
101+
PyMODINIT_FUNC PyInit_qjs() {
102+
return PyModule_Create(&qjs_module);
103+
}

pyext/qjs.cp36-win_amd64.pyd

683 KB
Binary file not shown.

pyext/setup.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from distutils.core import setup, Extension
2+
import distutils.cygwinccompiler
3+
distutils.cygwinccompiler.get_msvcr = lambda: []
4+
5+
# python setup.py build -f -c mingw32
6+
7+
#libs = ["../obj/quickjs.o","../obj/libregexp.o","../obj/libunicode.o","../obj/cutils.o","../obj/quickjs-libc.o"]
8+
9+
srcs = ['QJS.c', "../src/cutils.c","../src/libregexp.c","../src/libunicode.c","../src/quickjs.c","../src/quickjs-libc.c"]
10+
11+
extra_compile_args = ['-DCONFIG_VERSION=\\"2020-01-19\\"']
12+
13+
setup(name='qjs', version='1.0',
14+
ext_modules=[
15+
Extension('qjs', srcs ,
16+
include_dirs = ['../include'],
17+
extra_compile_args=extra_compile_args,
18+
extra_link_args = ["-Wl,-Bstatic"]
19+
#extra_link_args = ["-Wl,-Bstatic"] + libs
20+
)])
21+

pyext/test.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import os
2+
import qjs
3+
4+
code = '''import * as std from 'std';
5+
6+
7+
((G)=>{
8+
const sys_path = std.getenv('PATH');
9+
console.log("run .....");
10+
G._r = 'result: '+ sys_path;
11+
})(globalThis);
12+
13+
'''
14+
15+
code1 = '(()=>{return Date.now();})();'
16+
17+
mod_test = '''import * as m from '../lib/toolm.dll'
18+
19+
console.log("Hello World 你好");
20+
21+
console.log(m.echo("Hello , 哈哈"));
22+
23+
console.log(m.md5('123456'));'''
24+
25+
print("work dir:", os.getcwd())
26+
print(qjs.eval_js(code))
27+
print(qjs.eval_js(code1))
28+
29+
print(qjs.eval_js(mod_test))
30+
31+
32+
33+

0 commit comments

Comments
 (0)