Skip to content

Commit

Permalink
Merge pull request #525 from ruby/katei/npm-jco
Browse files Browse the repository at this point in the history
Add `RubyVM.instantiateComponent` and `RubyVM.instantiateModule`
  • Loading branch information
kateinoigakukun authored Sep 5, 2024
2 parents 3912725 + 2e6882b commit 56b00f1
Show file tree
Hide file tree
Showing 26 changed files with 452 additions and 499 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
- run: ./bin/setup
- run: bundle exec rake check:type
- run: sudo apt-get install clang-format
- run: ./tools/clang-format-diff.sh
- run: ./bin/clang-format-diff.sh
- run: bundle exec rake check:bindgen
- run: git diff --exit-code

Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion tools/exe/rbminify → bin/rbminify
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env ruby

$LOAD_PATH << File.join(File.dirname(__FILE__), "../lib")
$LOAD_PATH << File.join(File.dirname(__FILE__), "lib")

require "syntax_tree"
require "syntax_tree/cli"
Expand Down
121 changes: 121 additions & 0 deletions bin/repl.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import * as preview2Shim from "@bytecodealliance/preview2-shim"
import * as nodeWasi from "wasi";
import fs from "fs/promises";
import path from "path";
import { RubyVM } from "@ruby/wasm-wasi";
import * as readline from 'node:readline/promises';
import { stdin as input, stdout as output } from 'node:process';
import { parseArgs } from "node:util"

async function instantiateComponent(pkgPath) {
const componentJsPath = path.resolve(pkgPath, "dist/component/ruby.component.js");
const { instantiate } = await import(componentJsPath);
const getCoreModule = async (relativePath) => {
const coreModulePath = path.resolve(pkgPath, "dist/component", relativePath);
const buffer = await fs.readFile(coreModulePath);
return WebAssembly.compile(buffer);
}
const { cli, filesystem } = preview2Shim;
cli._setArgs(["ruby.wasm"].concat(process.argv.slice(2)));
cli._setCwd("/")
filesystem._setPreopens({})

const { vm } = await RubyVM.instantiateComponent({
instantiate, getCoreModule, wasip2: preview2Shim,
});
return vm;
}

async function instantiateModule(pkgPath) {
const binaryPath = path.resolve(pkgPath, "dist/ruby.debug+stdlib.wasm");
const binary = await fs.readFile(binaryPath);
const rubyModule = await WebAssembly.compile(binary);
const wasi = new nodeWasi.WASI({
stdio: "inherit",
args: ["ruby.wasm"].concat(process.argv.slice(2)),
env: process.env,
version: "preview1",
});

const { vm } = await RubyVM.instantiateModule({
module: rubyModule, wasip1: wasi
})
return vm;
};

function parseOptions(args) {
/** @type {import("util").ParseArgsConfig["options"]} */
const options = {
pkg: {
type: "string",
short: "p",
default: (() => {
const dirname = path.dirname(new URL(import.meta.url).pathname);
return path.resolve(dirname, "../packages/npm-packages/ruby-head-wasm-wasi");
})()
},
type: {
type: "string",
short: "t",
default: "component",
},
help: {
type: "boolean",
short: "h",
},
}
const { values } = parseArgs({ args, options });
return values;
}

function printUsage() {
console.log("Usage: repl.mjs [--pkg <npm-package-path>] [--type <component|module>]");
}

async function main() {
const args = parseOptions(process.argv.slice(2));
if (args["help"]) {
printUsage();
return;
}
const pkgPath = args["pkg"];
const vm = await (async () => {
switch (args["type"]) {
case "component": {
console.log(`Loading component from ${pkgPath}`);
return await instantiateComponent(pkgPath);
}
case "module": {
console.log(`Loading core module from ${pkgPath}`);
return await instantiateModule(pkgPath);
}
default:
throw new Error(`Unknown type: ${args["type"]}`);
}
})();
const rl = readline.createInterface({ input, output });

vm.eval(`puts RUBY_DESCRIPTION`);

const printer = vm.eval(`
class ReplPrinter
def puts(*args)
args.each do |arg|
Kernel.puts(arg)
end
end
end
ReplPrinter.new
`);
while (true) {
const line = await rl.question(`>> `);
try {
const result = vm.eval(line);
printer.call("puts", result);
} catch (e) {
console.error(e);
}
}
}

main().catch(console.error);
51 changes: 2 additions & 49 deletions packages/gems/js/ext/js/bindgen/ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,6 @@ extern void __wasm_import_ruby_js_js_runtime_throw_prohibit_rewind_exception(uin






__attribute__((__weak__, __export_name__("cabi_post_ruby:js/ruby-runtime#rstring-ptr")))
void __wasm_export_exports_ruby_js_ruby_runtime_rstring_ptr_post_return(uint8_t * arg0) {
if ((*((size_t*) (arg0 + 4))) > 0) {
Expand Down Expand Up @@ -150,32 +147,6 @@ void ruby_js_js_runtime_list_borrow_js_abi_value_free(ruby_js_js_runtime_list_bo
}
}

__attribute__((__import_module__("[export]ruby:js/ruby-runtime"), __import_name__("[resource-drop]rb-iseq")))
extern void __wasm_import_exports_ruby_js_ruby_runtime_rb_iseq_drop(int32_t handle);

void exports_ruby_js_ruby_runtime_rb_iseq_drop_own(exports_ruby_js_ruby_runtime_own_rb_iseq_t handle) {
__wasm_import_exports_ruby_js_ruby_runtime_rb_iseq_drop(handle.__handle);
}

__attribute__(( __import_module__("[export]ruby:js/ruby-runtime"), __import_name__("[resource-new]rb-iseq")))
extern int32_t __wasm_import_exports_ruby_js_ruby_runtime_rb_iseq_new(int32_t);

__attribute__((__import_module__("[export]ruby:js/ruby-runtime"), __import_name__("[resource-rep]rb-iseq")))
extern int32_t __wasm_import_exports_ruby_js_ruby_runtime_rb_iseq_rep(int32_t);

exports_ruby_js_ruby_runtime_own_rb_iseq_t exports_ruby_js_ruby_runtime_rb_iseq_new(exports_ruby_js_ruby_runtime_rb_iseq_t *rep) {
return (exports_ruby_js_ruby_runtime_own_rb_iseq_t) { __wasm_import_exports_ruby_js_ruby_runtime_rb_iseq_new((int32_t) rep) };
}

exports_ruby_js_ruby_runtime_rb_iseq_t* exports_ruby_js_ruby_runtime_rb_iseq_rep(exports_ruby_js_ruby_runtime_own_rb_iseq_t handle) {
return (exports_ruby_js_ruby_runtime_rb_iseq_t*) __wasm_import_exports_ruby_js_ruby_runtime_rb_iseq_rep(handle.__handle);
}

__attribute__((__export_name__("ruby:js/ruby-runtime#[dtor]rb_iseq")))
void __wasm_export_exports_ruby_js_ruby_runtime_rb_iseq_dtor(exports_ruby_js_ruby_runtime_rb_iseq_t* arg) {
exports_ruby_js_ruby_runtime_rb_iseq_destructor(arg);
}

__attribute__((__import_module__("[export]ruby:js/ruby-runtime"), __import_name__("[resource-drop]rb-abi-value")))
extern void __wasm_import_exports_ruby_js_ruby_runtime_rb_abi_value_drop(int32_t handle);

Expand Down Expand Up @@ -437,27 +408,9 @@ void __wasm_export_exports_ruby_js_ruby_runtime_ruby_show_version(void) {
}

__attribute__((__export_name__("ruby:js/ruby-runtime#ruby-init")))
void __wasm_export_exports_ruby_js_ruby_runtime_ruby_init(void) {
exports_ruby_js_ruby_runtime_ruby_init();
}

__attribute__((__export_name__("ruby:js/ruby-runtime#ruby-sysinit")))
void __wasm_export_exports_ruby_js_ruby_runtime_ruby_sysinit(uint8_t * arg, size_t arg0) {
void __wasm_export_exports_ruby_js_ruby_runtime_ruby_init(uint8_t * arg, size_t arg0) {
ext_list_string_t arg1 = (ext_list_string_t) { (ext_string_t*)(arg), (arg0) };
exports_ruby_js_ruby_runtime_ruby_sysinit(&arg1);
}

__attribute__((__export_name__("ruby:js/ruby-runtime#ruby-options")))
int32_t __wasm_export_exports_ruby_js_ruby_runtime_ruby_options(uint8_t * arg, size_t arg0) {
ext_list_string_t arg1 = (ext_list_string_t) { (ext_string_t*)(arg), (arg0) };
exports_ruby_js_ruby_runtime_own_rb_iseq_t ret = exports_ruby_js_ruby_runtime_ruby_options(&arg1);
return (ret).__handle;
}

__attribute__((__export_name__("ruby:js/ruby-runtime#ruby-script")))
void __wasm_export_exports_ruby_js_ruby_runtime_ruby_script(uint8_t * arg, size_t arg0) {
ext_string_t arg1 = (ext_string_t) { (uint8_t*)(arg), (arg0) };
exports_ruby_js_ruby_runtime_ruby_script(&arg1);
exports_ruby_js_ruby_runtime_ruby_init(&arg1);
}

__attribute__((__export_name__("ruby:js/ruby-runtime#ruby-init-loadpath")))
Expand Down
19 changes: 1 addition & 18 deletions packages/gems/js/ext/js/bindgen/ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,6 @@ typedef struct ruby_js_js_runtime_list_borrow_js_abi_value_t {
size_t len;
} ruby_js_js_runtime_list_borrow_js_abi_value_t;

typedef struct exports_ruby_js_ruby_runtime_own_rb_iseq_t {
int32_t __handle;
} exports_ruby_js_ruby_runtime_own_rb_iseq_t;

typedef struct exports_ruby_js_ruby_runtime_rb_iseq_t exports_ruby_js_ruby_runtime_rb_iseq_t;

typedef exports_ruby_js_ruby_runtime_rb_iseq_t* exports_ruby_js_ruby_runtime_borrow_rb_iseq_t;

typedef struct exports_ruby_js_ruby_runtime_own_rb_abi_value_t {
int32_t __handle;
} exports_ruby_js_ruby_runtime_own_rb_abi_value_t;
Expand Down Expand Up @@ -108,10 +100,7 @@ extern void ruby_js_js_runtime_throw_prohibit_rewind_exception(ext_string_t *mes

// Exported Functions from `ruby:js/ruby-runtime`
void exports_ruby_js_ruby_runtime_ruby_show_version(void);
void exports_ruby_js_ruby_runtime_ruby_init(void);
void exports_ruby_js_ruby_runtime_ruby_sysinit(ext_list_string_t *args);
exports_ruby_js_ruby_runtime_own_rb_iseq_t exports_ruby_js_ruby_runtime_ruby_options(ext_list_string_t *args);
void exports_ruby_js_ruby_runtime_ruby_script(ext_string_t *name);
void exports_ruby_js_ruby_runtime_ruby_init(ext_list_string_t *args);
void exports_ruby_js_ruby_runtime_ruby_init_loadpath(void);
void exports_ruby_js_ruby_runtime_rb_eval_string_protect(ext_string_t *str, exports_ruby_js_ruby_runtime_tuple2_own_rb_abi_value_s32_t *ret);
void exports_ruby_js_ruby_runtime_rb_funcallv_protect(exports_ruby_js_ruby_runtime_borrow_rb_abi_value_t recv, exports_ruby_js_ruby_runtime_rb_id_t mid, exports_ruby_js_ruby_runtime_list_borrow_rb_abi_value_t *args, exports_ruby_js_ruby_runtime_tuple2_own_rb_abi_value_s32_t *ret);
Expand All @@ -137,12 +126,6 @@ void ruby_js_js_runtime_raw_integer_free(ruby_js_js_runtime_raw_integer_t *ptr);

void ruby_js_js_runtime_list_borrow_js_abi_value_free(ruby_js_js_runtime_list_borrow_js_abi_value_t *ptr);

extern void exports_ruby_js_ruby_runtime_rb_iseq_drop_own(exports_ruby_js_ruby_runtime_own_rb_iseq_t handle);

extern exports_ruby_js_ruby_runtime_own_rb_iseq_t exports_ruby_js_ruby_runtime_rb_iseq_new(exports_ruby_js_ruby_runtime_rb_iseq_t *rep);
extern exports_ruby_js_ruby_runtime_rb_iseq_t* exports_ruby_js_ruby_runtime_rb_iseq_rep(exports_ruby_js_ruby_runtime_own_rb_iseq_t handle);
void exports_ruby_js_ruby_runtime_rb_iseq_destructor(exports_ruby_js_ruby_runtime_rb_iseq_t *rep);

extern void exports_ruby_js_ruby_runtime_rb_abi_value_drop_own(exports_ruby_js_ruby_runtime_own_rb_abi_value_t handle);

extern exports_ruby_js_ruby_runtime_own_rb_abi_value_t exports_ruby_js_ruby_runtime_rb_abi_value_new(exports_ruby_js_ruby_runtime_rb_abi_value_t *rep);
Expand Down
Binary file modified packages/gems/js/ext/js/bindgen/ext_component_type.o
Binary file not shown.
55 changes: 3 additions & 52 deletions packages/gems/js/ext/js/bindgen/legacy/rb-abi-guest.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,6 @@ size_t new_size
return ret;
}

__attribute__((import_module("canonical_abi"), import_name("resource_drop_rb-iseq")))
void __resource_rb_iseq_drop(uint32_t idx);

void rb_abi_guest_rb_iseq_free(rb_abi_guest_rb_iseq_t *ptr) {
__resource_rb_iseq_drop(ptr->idx);
}

__attribute__((import_module("canonical_abi"), import_name("resource_clone_rb-iseq")))
uint32_t __resource_rb_iseq_clone(uint32_t idx);

rb_abi_guest_rb_iseq_t rb_abi_guest_rb_iseq_clone(rb_abi_guest_rb_iseq_t *ptr) {
return (rb_abi_guest_rb_iseq_t){__resource_rb_iseq_clone(ptr->idx)};
}

__attribute__((import_module("canonical_abi"), import_name("resource_new_rb-iseq")))
uint32_t __resource_rb_iseq_new(uint32_t val);

rb_abi_guest_rb_iseq_t rb_abi_guest_rb_iseq_new(void *data) {
return (rb_abi_guest_rb_iseq_t){__resource_rb_iseq_new((uint32_t) data)};
}

__attribute__((import_module("canonical_abi"), import_name("resource_get_rb-iseq")))
uint32_t __resource_rb_iseq_get(uint32_t idx);

void* rb_abi_guest_rb_iseq_get(rb_abi_guest_rb_iseq_t *ptr) {
return (void*) __resource_rb_iseq_get(ptr->idx);
}

__attribute__((export_name("canonical_abi_drop_rb-iseq")))
void __resource_rb_iseq_dtor(uint32_t val) {
if (rb_abi_guest_rb_iseq_dtor)
rb_abi_guest_rb_iseq_dtor((void*) val);
}

__attribute__((import_module("canonical_abi"), import_name("resource_drop_rb-abi-value")))
void __resource_rb_abi_value_drop(uint32_t idx);

Expand Down Expand Up @@ -127,25 +93,10 @@ __attribute__((export_name("ruby-show-version: func() -> ()")))
void __wasm_export_rb_abi_guest_ruby_show_version(void) {
rb_abi_guest_ruby_show_version();
}
__attribute__((export_name("ruby-init: func() -> ()")))
void __wasm_export_rb_abi_guest_ruby_init(void) {
rb_abi_guest_ruby_init();
}
__attribute__((export_name("ruby-sysinit: func(args: list<string>) -> ()")))
void __wasm_export_rb_abi_guest_ruby_sysinit(int32_t arg, int32_t arg0) {
__attribute__((export_name("ruby-init: func(args: list<string>) -> ()")))
void __wasm_export_rb_abi_guest_ruby_init(int32_t arg, int32_t arg0) {
rb_abi_guest_list_string_t arg1 = (rb_abi_guest_list_string_t) { (rb_abi_guest_string_t*)(arg), (size_t)(arg0) };
rb_abi_guest_ruby_sysinit(&arg1);
}
__attribute__((export_name("ruby-options: func(args: list<string>) -> handle<rb-iseq>")))
int32_t __wasm_export_rb_abi_guest_ruby_options(int32_t arg, int32_t arg0) {
rb_abi_guest_list_string_t arg1 = (rb_abi_guest_list_string_t) { (rb_abi_guest_string_t*)(arg), (size_t)(arg0) };
rb_abi_guest_rb_iseq_t ret = rb_abi_guest_ruby_options(&arg1);
return (ret).idx;
}
__attribute__((export_name("ruby-script: func(name: string) -> ()")))
void __wasm_export_rb_abi_guest_ruby_script(int32_t arg, int32_t arg0) {
rb_abi_guest_string_t arg1 = (rb_abi_guest_string_t) { (char*)(arg), (size_t)(arg0) };
rb_abi_guest_ruby_script(&arg1);
rb_abi_guest_ruby_init(&arg1);
}
__attribute__((export_name("ruby-init-loadpath: func() -> ()")))
void __wasm_export_rb_abi_guest_ruby_init_loadpath(void) {
Expand Down
16 changes: 1 addition & 15 deletions packages/gems/js/ext/js/bindgen/legacy/rb-abi-guest.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,6 @@ extern "C"
#include <stdint.h>
#include <stdbool.h>

typedef struct {
uint32_t idx;
} rb_abi_guest_rb_iseq_t;
void rb_abi_guest_rb_iseq_free(rb_abi_guest_rb_iseq_t *ptr);
rb_abi_guest_rb_iseq_t rb_abi_guest_rb_iseq_clone(rb_abi_guest_rb_iseq_t *ptr);
rb_abi_guest_rb_iseq_t rb_abi_guest_rb_iseq_new(void *data);
void* rb_abi_guest_rb_iseq_get(rb_abi_guest_rb_iseq_t *ptr);

__attribute__((weak))
void rb_abi_guest_rb_iseq_dtor(void *data);

typedef struct {
uint32_t idx;
} rb_abi_guest_rb_abi_value_t;
Expand Down Expand Up @@ -56,10 +45,7 @@ extern "C"
} rb_abi_guest_list_rb_abi_value_t;
void rb_abi_guest_list_rb_abi_value_free(rb_abi_guest_list_rb_abi_value_t *ptr);
void rb_abi_guest_ruby_show_version(void);
void rb_abi_guest_ruby_init(void);
void rb_abi_guest_ruby_sysinit(rb_abi_guest_list_string_t *args);
rb_abi_guest_rb_iseq_t rb_abi_guest_ruby_options(rb_abi_guest_list_string_t *args);
void rb_abi_guest_ruby_script(rb_abi_guest_string_t *name);
void rb_abi_guest_ruby_init(rb_abi_guest_list_string_t *args);
void rb_abi_guest_ruby_init_loadpath(void);
void rb_abi_guest_rb_eval_string_protect(rb_abi_guest_string_t *str, rb_abi_guest_tuple2_rb_abi_value_s32_t *ret0);
void rb_abi_guest_rb_funcallv_protect(rb_abi_guest_rb_abi_value_t recv, rb_abi_guest_rb_id_t mid, rb_abi_guest_list_rb_abi_value_t *args, rb_abi_guest_tuple2_rb_abi_value_s32_t *ret0);
Expand Down
6 changes: 1 addition & 5 deletions packages/gems/js/ext/js/bindgen/legacy/rb-abi-guest.wit
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
resource rb-iseq
resource rb-abi-value
type rb-errno = s32
type rb-id = u32

ruby-show-version: func()
ruby-init: func()
ruby-sysinit: func(args: list<string>)
ruby-options: func(args: list<string>) -> rb-iseq
ruby-script: func(name: string)
ruby-init: func(args: list<string>)
ruby-init-loadpath: func()
rb-eval-string-protect: func(str: string) -> tuple<rb-abi-value, s32>
rb-funcallv-protect: func(recv: rb-abi-value, mid: rb-id, args: list<rb-abi-value>) -> tuple<rb-abi-value, s32>
Expand Down
1 change: 0 additions & 1 deletion packages/gems/js/ext/js/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ typedef exports_ruby_js_ruby_runtime_own_rb_abi_value_t
rb_abi_guest_own_rb_abi_value_t;
typedef exports_ruby_js_ruby_runtime_list_borrow_rb_abi_value_t
rb_abi_guest_list_rb_abi_value_t;
typedef exports_ruby_js_ruby_runtime_own_rb_iseq_t rb_abi_guest_rb_iseq_t;
typedef exports_ruby_js_ruby_runtime_rb_id_t rb_abi_guest_rb_id_t;
typedef exports_ruby_js_ruby_runtime_tuple2_own_rb_abi_value_s32_t
rb_abi_guest_tuple2_rb_abi_value_s32_t;
Expand Down
Loading

0 comments on commit 56b00f1

Please sign in to comment.