How to call JS function from C (or get exported value from JS_Eval
)?
#643
-
Hello! I'm new to QuickJS and I want to use it to embed my JS project into a C-API. But I'm encountering a problem that I don't know how to call JS functions in a auto SOURCE = R"(
export function hello() {
return 'Hello';
}
)" "\0"sv;
int main() {
auto rt = JS_NewRuntime();
auto ctx = JS_NewContext(rt);
auto value = JS_Eval(ctx, SOURCE.data(), SOURCE.size() - 1, "main.js", JS_EVAL_TYPE_MODULE);
// ^- Seems to be Promise<undefined> ?
JSModuleDef* def = /* ??? */;
auto ns = JS_GetModuleNamespace(ctx, def);
auto fn = JS_GetPropertyStr(ctx, ns, "hello");
auto result = JS_Call(ctx, fn, JS_UNDEFINED, 0, nullptr);
auto str = JS_ToCString(ctx, result); // Expected "Hello"
// [...]
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
} It's that possible to get the |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 4 replies
-
I can't guarantee it'll work forever but the return value from JS_Eval is the module, and that's just the wrapped JSModuleDef pointer: JSValue v = JS_Eval(ctx, buf, len, filename, JS_EVAL_TYPE_MODULE);
if (JS_VALUE_GET_TAG(v) == JS_TAG_MODULE) {
JSModuleDef *m = JS_VALUE_GET_PTR(v);
// ...
} |
Beta Was this translation helpful? Give feedback.
-
Thank you @bnoordhuis and @saghul ! Here is a working example (sorry for using C++): int main() {
auto rt = JS_NewRuntime();
auto ctx = JS_NewContext(rt);
auto bytecode = JS_Eval(ctx, SOURCE.data(), SOURCE.size() - 1, "main.js",
JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
JS_ResolveModule(ctx, bytecode);
JS_EvalFunction(ctx, bytecode);
auto def = static_cast<JSModuleDef*>(JS_VALUE_GET_PTR(bytecode));
auto ns = JS_GetModuleNamespace(ctx, def);
auto fn = JS_GetPropertyStr(ctx, ns, "hello");
auto result = JS_Call(ctx, fn, JS_UNDEFINED, 0, nullptr);
auto str = JS_ToCString(ctx, result);
std::cout << str << std::endl; // Expected "Hello"
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
} Use |
Beta Was this translation helpful? Give feedback.
Thank you @bnoordhuis and @saghul ! Here is a working example (sorry for using C++):