Skip to content

Commit

Permalink
make quickjs callable as native ext
Browse files Browse the repository at this point in the history
  • Loading branch information
hmsk committed Jun 11, 2024
1 parent 8dba8d5 commit 1add102
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 10 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "ext/quickjsrb/quickjs"]
path = ext/quickjsrb/quickjs
url = https://github.com/bellard/quickjs.git
35 changes: 35 additions & 0 deletions ext/quickjsrb/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,44 @@

require 'mkmf'

$VPATH << "$(srcdir)/quickjs"

$srcs = [
'libunicode.c',
'libbf.c',
'libregexp.c',
'cutils.c',
'quickjs.c',
'quickjs-libc.c',
'quickjsrb.c',
]

append_cflags('-I$(srcdir)/quickjs')

append_cflags('-fwrapv')
append_cflags('-g')
append_cflags('-O2')
append_cflags('-Wall')
append_cflags('-MMD')
append_cflags('-MF')
append_cflags('-Wextra')
append_cflags('-Wno-sign-compare')
append_cflags('-Wno-missing-field-initializers')
append_cflags('-Wundef -Wuninitialized')
append_cflags('-Wunused -Wno-unused-parameter')
append_cflags('-Wwrite-strings')
append_cflags('-Wchar-subscripts -funsigned-char')
append_cflags('-D_GNU_SOURCE -DCONFIG_VERSION=\"2024-02-14\" -DCONFIG_BIGNUM')

abort('could not find quickjs.h') unless find_header('quickjs.h')
abort('could not find cutils.h') unless find_header('cutils.h')
abort('could not find quickjs-libc.h') unless find_header('quickjs-libc.h')
#abort('could not find libbf.h') unless find_header('libbf.h')

# Makes all symbols private by default to avoid unintended conflict
# with other gems. To explicitly export symbols you can use RUBY_FUNC_EXPORTED
# selectively, or entirely remove this flag.
append_cflags('-fvisibility=hidden')
$warnflags = ''

create_makefile('quickjsrb/quickjsrb')
1 change: 1 addition & 0 deletions ext/quickjsrb/quickjs
Submodule quickjs added at 36911f
36 changes: 31 additions & 5 deletions ext/quickjsrb/quickjsrb.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,42 @@

VALUE rb_mQuickjs;


VALUE rb_module_say_hi(VALUE klass)
VALUE rb_module_eval_js_code(VALUE klass, VALUE r_code)
{
VALUE r_hello = rb_str_new2("Hello!");
return r_hello;
JSRuntime *rt = JS_NewRuntime();
JSContext *ctx = JS_NewContext(rt);

JS_SetMemoryLimit(rt, 0x4000000);
JS_SetMaxStackSize(rt, 0x10000);
JS_AddIntrinsicBigFloat(ctx);
JS_AddIntrinsicBigDecimal(ctx);
JS_AddIntrinsicOperators(ctx);
JS_EnableBignumExt(ctx, 1);
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
js_std_add_helpers(ctx, 0, NULL);

js_std_init_handlers(rt);
js_init_module_std(ctx, "std");
js_init_module_os(ctx, "os");

char *code = StringValueCStr(r_code);
JSValue res = JS_Eval(ctx, code, strlen(code), "<code>", JS_EVAL_TYPE_GLOBAL);

int r = 0;
if (JS_IsException(res)) {
} else {
JS_ToInt32(ctx, &r, res);
}
JS_FreeValue(ctx, res);
JS_FreeContext(ctx);
JS_FreeRuntime(rt);

return INT2NUM(r);
}

RUBY_FUNC_EXPORTED void
Init_quickjsrb(void)
{
rb_mQuickjs = rb_define_module("Quickjs");
rb_define_module_function(rb_mQuickjs, "say_hi", rb_module_say_hi, 0);
rb_define_module_function(rb_mQuickjs, "evalCode", rb_module_eval_js_code, 1);
}
14 changes: 11 additions & 3 deletions ext/quickjsrb/quickjsrb.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
#ifndef QUICKJS_H
#define QUICKJS_H 1
#ifndef QUICKJSRB_H
#define QUICKJSRB_H 1

#include "ruby.h"

#endif /* QUICKJS_H */
#include "quickjs.h"
#include "quickjs-libc.h"

#include <stdint.h>
#include <stdio.h>
#include <string.h>


#endif /* QUICKJSRB_H */
5 changes: 3 additions & 2 deletions test/quickjs_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ class QuickjsTest < Test::Unit::TestCase
end
end

test "something useful" do
assert_equal(::Quickjs.say_hi, "Hello!")
test "support returning integer" do
assert_equal(::Quickjs.evalCode("2+3"), 5)
assert_equal(::Quickjs.evalCode("const func = () => 8; func();"), 8)
end
end

0 comments on commit 1add102

Please sign in to comment.