Skip to content

Commit 9c9e0ce

Browse files
Merge pull request #439 from ruby/katei/component-unit-test
Fix Component support to pass `test:unit`
2 parents c30aeed + c23451b commit 9c9e0ce

File tree

19 files changed

+405
-209
lines changed

19 files changed

+405
-209
lines changed

lib/ruby_wasm/packager/core.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,10 @@ def target
274274

275275
def derive_build
276276
return @build if @build
277-
__skip__ =
278-
build ||= RubyWasm::Build.new(name, **@packager.full_build_options, target: target)
277+
__skip__ = build ||= RubyWasm::Build.new(
278+
name, **@packager.full_build_options, target: target,
279+
wasi_vfs: @packager.features.support_component_model? ? nil : :default
280+
)
279281
build.crossruby.user_exts = user_exts(build)
280282
# Emscripten uses --global-base=1024 by default, but it conflicts with
281283
# --stack-first and -z stack-size since global-base 1024 is smaller than

packages/gems/js/ext/js/bindgen/ext.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ __attribute__((__import_module__("ruby:js/js-runtime"), __import_name__("bool-to
3030
extern int32_t __wasm_import_ruby_js_js_runtime_bool_to_js_bool(int32_t);
3131

3232
__attribute__((__import_module__("ruby:js/js-runtime"), __import_name__("proc-to-js-function")))
33-
extern int32_t __wasm_import_ruby_js_js_runtime_proc_to_js_function(int32_t);
33+
extern int32_t __wasm_import_ruby_js_js_runtime_proc_to_js_function(void);
3434

3535
__attribute__((__import_module__("ruby:js/js-runtime"), __import_name__("rb-object-to-js-rb-value")))
36-
extern int32_t __wasm_import_ruby_js_js_runtime_rb_object_to_js_rb_value(int32_t);
36+
extern int32_t __wasm_import_ruby_js_js_runtime_rb_object_to_js_rb_value(void);
3737

3838
__attribute__((__import_module__("ruby:js/js-runtime"), __import_name__("js-value-to-string")))
3939
extern void __wasm_import_ruby_js_js_runtime_js_value_to_string(int32_t, uint8_t *);
@@ -92,6 +92,7 @@ void __wasm_export_exports_ruby_js_ruby_runtime_rstring_ptr_post_return(uint8_t
9292

9393

9494

95+
9596
// Canonical ABI intrinsics
9697

9798
__attribute__((__weak__, __export_name__("cabi_realloc")))
@@ -301,13 +302,13 @@ ruby_js_js_runtime_own_js_abi_value_t ruby_js_js_runtime_bool_to_js_bool(bool va
301302
return (ruby_js_js_runtime_own_js_abi_value_t) { ret };
302303
}
303304

304-
ruby_js_js_runtime_own_js_abi_value_t ruby_js_js_runtime_proc_to_js_function(uint32_t value) {
305-
int32_t ret = __wasm_import_ruby_js_js_runtime_proc_to_js_function((int32_t) (value));
305+
ruby_js_js_runtime_own_js_abi_value_t ruby_js_js_runtime_proc_to_js_function(void) {
306+
int32_t ret = __wasm_import_ruby_js_js_runtime_proc_to_js_function();
306307
return (ruby_js_js_runtime_own_js_abi_value_t) { ret };
307308
}
308309

309-
ruby_js_js_runtime_own_js_abi_value_t ruby_js_js_runtime_rb_object_to_js_rb_value(uint32_t raw_rb_abi_value) {
310-
int32_t ret = __wasm_import_ruby_js_js_runtime_rb_object_to_js_rb_value((int32_t) (raw_rb_abi_value));
310+
ruby_js_js_runtime_own_js_abi_value_t ruby_js_js_runtime_rb_object_to_js_rb_value(void) {
311+
int32_t ret = __wasm_import_ruby_js_js_runtime_rb_object_to_js_rb_value();
311312
return (ruby_js_js_runtime_own_js_abi_value_t) { ret };
312313
}
313314

@@ -537,6 +538,12 @@ int32_t __wasm_export_exports_ruby_js_ruby_runtime_rb_set_should_prohibit_rewind
537538
return ret;
538539
}
539540

541+
__attribute__((__export_name__("ruby:js/ruby-runtime#export-rb-value-to-js")))
542+
int32_t __wasm_export_exports_ruby_js_ruby_runtime_export_rb_value_to_js(void) {
543+
exports_ruby_js_ruby_runtime_own_rb_abi_value_t ret = exports_ruby_js_ruby_runtime_export_rb_value_to_js();
544+
return (ret).__handle;
545+
}
546+
540547
// Ensure that the *_component_type.o object is linked in
541548

542549
extern void __component_type_object_force_link_ext(void);

packages/gems/js/ext/js/bindgen/ext.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ extern ruby_js_js_runtime_own_js_abi_value_t ruby_js_js_runtime_int_to_js_number
9292
extern ruby_js_js_runtime_own_js_abi_value_t ruby_js_js_runtime_float_to_js_number(double value);
9393
extern ruby_js_js_runtime_own_js_abi_value_t ruby_js_js_runtime_string_to_js_string(ext_string_t *value);
9494
extern ruby_js_js_runtime_own_js_abi_value_t ruby_js_js_runtime_bool_to_js_bool(bool value);
95-
extern ruby_js_js_runtime_own_js_abi_value_t ruby_js_js_runtime_proc_to_js_function(uint32_t value);
96-
extern ruby_js_js_runtime_own_js_abi_value_t ruby_js_js_runtime_rb_object_to_js_rb_value(uint32_t raw_rb_abi_value);
95+
extern ruby_js_js_runtime_own_js_abi_value_t ruby_js_js_runtime_proc_to_js_function(void);
96+
extern ruby_js_js_runtime_own_js_abi_value_t ruby_js_js_runtime_rb_object_to_js_rb_value(void);
9797
extern void ruby_js_js_runtime_js_value_to_string(ruby_js_js_runtime_borrow_js_abi_value_t value, ext_string_t *ret);
9898
extern void ruby_js_js_runtime_js_value_to_integer(ruby_js_js_runtime_borrow_js_abi_value_t value, ruby_js_js_runtime_raw_integer_t *ret);
9999
extern void ruby_js_js_runtime_export_js_value_to_host(ruby_js_js_runtime_borrow_js_abi_value_t value);
@@ -123,6 +123,7 @@ void exports_ruby_js_ruby_runtime_rb_vm_bugreport(void);
123123
bool exports_ruby_js_ruby_runtime_rb_gc_enable(void);
124124
bool exports_ruby_js_ruby_runtime_rb_gc_disable(void);
125125
bool exports_ruby_js_ruby_runtime_rb_set_should_prohibit_rewind(bool new_value);
126+
exports_ruby_js_ruby_runtime_own_rb_abi_value_t exports_ruby_js_ruby_runtime_export_rb_value_to_js(void);
126127

127128
// Helper Functions
128129

Binary file not shown.

packages/gems/js/ext/js/js-core.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,9 +438,14 @@ static VALUE _rb_js_import_from_js(VALUE obj) {
438438
* Returns +obj+ wrapped by JS class RbValue.
439439
*/
440440
static VALUE _rb_js_obj_wrap(VALUE obj, VALUE wrapping) {
441+
#if JS_ENABLE_COMPONENT_MODEL
442+
rb_abi_stage_rb_value_to_js(wrapping);
443+
return jsvalue_s_new(rb_js_abi_host_rb_object_to_js_rb_value());
444+
#else
441445
rb_abi_lend_object(wrapping);
442446
return jsvalue_s_new(
443447
rb_js_abi_host_rb_object_to_js_rb_value((uint32_t)wrapping));
448+
#endif
444449
}
445450

446451
/*
@@ -506,8 +511,13 @@ static VALUE _rb_js_false_to_js(VALUE obj) {
506511
* Returns +self+ as a JS::Object.
507512
*/
508513
static VALUE _rb_js_proc_to_js(VALUE obj) {
514+
#if JS_ENABLE_COMPONENT_MODEL
515+
rb_abi_stage_rb_value_to_js(obj);
516+
return jsvalue_s_new(ruby_js_js_runtime_proc_to_js_function());
517+
#else
509518
rb_abi_lend_object(obj);
510519
return jsvalue_s_new(rb_js_abi_host_proc_to_js_function((uint32_t)obj));
520+
#endif
511521
}
512522

513523
/*

packages/gems/js/ext/js/types.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,6 @@ typedef ext_list_string_t rb_abi_guest_list_string_t;
5555
ruby_js_js_runtime_string_to_js_string(val)
5656
# define rb_js_abi_host_bool_to_js_bool(val) \
5757
ruby_js_js_runtime_bool_to_js_bool(val)
58-
# define rb_js_abi_host_proc_to_js_function(val) \
59-
ruby_js_js_runtime_proc_to_js_function(val)
6058
# define rb_js_abi_host_import_js_value_from_host() \
6159
ruby_js_js_runtime_import_js_value_from_host()
6260
# define rb_js_abi_host_js_value_to_string(value, ret) \
@@ -88,6 +86,8 @@ typedef ext_list_string_t rb_abi_guest_list_string_t;
8886
# define RB_JS_ABI_HOST_JS_ABI_RESULT_FAILURE \
8987
RUBY_JS_JS_RUNTIME_JS_ABI_RESULT_FAILURE
9088

89+
void rb_abi_stage_rb_value_to_js(VALUE value);
90+
9191
#else
9292
# include "bindgen/legacy/rb-abi-guest.h"
9393
# include "bindgen/legacy/rb-js-abi-host.h"

packages/gems/js/ext/js/witapi-core.c

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,67 +340,113 @@ bool rb_abi_guest_rb_set_should_prohibit_rewind(bool value) {
340340
return old;
341341
}
342342

343+
static VALUE rb_abi_export_stage = Qnil;
344+
static rb_abi_guest_own_rb_abi_value_t rb_abi_export_rb_value_to_js(void) {
345+
VALUE staged = rb_abi_export_stage;
346+
rb_abi_export_stage = Qnil;
347+
rb_abi_lend_object(staged);
348+
return rb_abi_guest_rb_abi_value_new((void *)staged);
349+
}
350+
351+
void rb_abi_stage_rb_value_to_js(VALUE value) {
352+
assert(rb_abi_export_stage == Qnil &&
353+
"rb_abi_stage_rb_value_to_js: stage is not empty!?");
354+
rb_abi_export_stage = value;
355+
}
356+
343357
#ifdef JS_ENABLE_COMPONENT_MODEL
358+
359+
extern void __wasm_call_ctors(void);
360+
static inline void __wasm_call_ctors_if_needed(void) {
361+
static bool __wasm_call_ctors_done = false;
362+
if (!__wasm_call_ctors_done) {
363+
__wasm_call_ctors_done = true;
364+
__wasm_call_ctors();
365+
}
366+
}
367+
344368
// Exported Functions from `ruby:js/ruby-runtime`
345369
void exports_ruby_js_ruby_runtime_ruby_show_version(void) {
370+
__wasm_call_ctors_if_needed();
346371
rb_abi_guest_ruby_show_version();
347372
}
348-
void exports_ruby_js_ruby_runtime_ruby_init(void) { rb_abi_guest_ruby_init(); }
373+
void exports_ruby_js_ruby_runtime_ruby_init(void) {
374+
__wasm_call_ctors_if_needed();
375+
rb_abi_guest_ruby_init();
376+
}
349377
void exports_ruby_js_ruby_runtime_ruby_sysinit(ext_list_string_t *args) {
378+
__wasm_call_ctors_if_needed();
350379
rb_abi_guest_ruby_sysinit(args);
351380
}
352381
exports_ruby_js_ruby_runtime_own_rb_iseq_t
353382
exports_ruby_js_ruby_runtime_ruby_options(ext_list_string_t *args) {
383+
__wasm_call_ctors_if_needed();
354384
return rb_abi_guest_ruby_options(args);
355385
}
356386
void exports_ruby_js_ruby_runtime_ruby_script(ext_string_t *name) {
387+
__wasm_call_ctors_if_needed();
357388
rb_abi_guest_ruby_script(name);
358389
}
359390
void exports_ruby_js_ruby_runtime_ruby_init_loadpath(void) {
391+
__wasm_call_ctors_if_needed();
360392
rb_abi_guest_ruby_init_loadpath();
361393
}
362394
void exports_ruby_js_ruby_runtime_rb_eval_string_protect(
363395
ext_string_t *str,
364396
exports_ruby_js_ruby_runtime_tuple2_own_rb_abi_value_s32_t *ret) {
397+
__wasm_call_ctors_if_needed();
365398
rb_abi_guest_rb_eval_string_protect(str, ret);
366399
}
367400
void exports_ruby_js_ruby_runtime_rb_funcallv_protect(
368401
exports_ruby_js_ruby_runtime_borrow_rb_abi_value_t recv,
369402
exports_ruby_js_ruby_runtime_rb_id_t mid,
370403
exports_ruby_js_ruby_runtime_list_borrow_rb_abi_value_t *args,
371404
exports_ruby_js_ruby_runtime_tuple2_own_rb_abi_value_s32_t *ret) {
405+
__wasm_call_ctors_if_needed();
372406
rb_abi_guest_rb_funcallv_protect(recv, mid, args, ret);
373407
}
374408
exports_ruby_js_ruby_runtime_rb_id_t
375409
exports_ruby_js_ruby_runtime_rb_intern(ext_string_t *name) {
410+
__wasm_call_ctors_if_needed();
376411
return rb_abi_guest_rb_intern(name);
377412
}
378413
exports_ruby_js_ruby_runtime_own_rb_abi_value_t
379414
exports_ruby_js_ruby_runtime_rb_errinfo(void) {
415+
__wasm_call_ctors_if_needed();
380416
return rb_abi_guest_rb_errinfo();
381417
}
382418
void exports_ruby_js_ruby_runtime_rb_clear_errinfo(void) {
419+
__wasm_call_ctors_if_needed();
383420
rb_abi_guest_rb_clear_errinfo();
384421
}
385422
void exports_ruby_js_ruby_runtime_rstring_ptr(
386423
exports_ruby_js_ruby_runtime_borrow_rb_abi_value_t value,
387424
ext_string_t *ret) {
425+
__wasm_call_ctors_if_needed();
388426
rb_abi_guest_rstring_ptr(value, ret);
389427
}
390428
void exports_ruby_js_ruby_runtime_rb_vm_bugreport(void) {
429+
__wasm_call_ctors_if_needed();
391430
rb_abi_guest_rb_vm_bugreport();
392431
}
393432
bool exports_ruby_js_ruby_runtime_rb_gc_enable(void) {
433+
__wasm_call_ctors_if_needed();
394434
return rb_abi_guest_rb_gc_enable();
395435
}
396436
bool exports_ruby_js_ruby_runtime_rb_gc_disable(void) {
437+
__wasm_call_ctors_if_needed();
397438
return rb_abi_guest_rb_gc_disable();
398439
}
399440
bool exports_ruby_js_ruby_runtime_rb_set_should_prohibit_rewind(
400441
bool new_value) {
442+
__wasm_call_ctors_if_needed();
401443
return rb_abi_guest_rb_set_should_prohibit_rewind(new_value);
402444
}
403-
445+
exports_ruby_js_ruby_runtime_own_rb_abi_value_t
446+
exports_ruby_js_ruby_runtime_export_rb_value_to_js(void) {
447+
__wasm_call_ctors_if_needed();
448+
return rb_abi_export_rb_value_to_js();
449+
}
404450
#endif
405451

406452
void Init_witapi(void) {}

packages/gems/js/wit/js-runtime.wit

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ interface js-runtime {
1717
float-to-js-number: func(value: float64) -> js-abi-value;
1818
string-to-js-string: func(value: string) -> js-abi-value;
1919
bool-to-js-bool: func(value: bool) -> js-abi-value;
20-
proc-to-js-function: func(value: u32) -> js-abi-value;
21-
rb-object-to-js-rb-value: func(raw-rb-abi-value: u32) -> js-abi-value;
20+
proc-to-js-function: func() -> js-abi-value;
21+
rb-object-to-js-rb-value: func() -> js-abi-value;
2222

2323
js-value-to-string: func(value: borrow<js-abi-value>) -> string;
2424

packages/gems/js/wit/ruby-runtime.wit

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,12 @@ interface ruby-runtime {
3232
// XXX: Do we really need them?
3333
// wrap-js-value: func(value: js-abi-value) -> rb-abi-value;
3434
// to-js-value: func(value: borrow<rb-abi-value>) -> js-abi-value;
35+
36+
// Transfer the value from Ruby to JS
37+
//
38+
// 1. Ruby side registers the value in the stage
39+
// 2. Ruby side calls JS's `import-rb-value-from-rb()`
40+
// 3. `import-rb-value-from-rb()` calls `export-rb-value-to-js()`
41+
// 4. `export-rb-value-to-js()` returns the staged value
42+
export-rb-value-to-js: func() -> rb-abi-value;
3543
}

packages/npm-packages/ruby-wasm-wasi/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"test:e2e:integrations": "playwright test -c test-e2e/playwright.integrations.config.ts",
4848
"serve:example": "BUNDLE_GEMFILE=../../../Gemfile bundle exec ruby -run -e httpd ./example -p 8085",
4949
"format": "prettier --write .",
50-
"build:static": "./tools/pack-bindgen-src.sh ./dist",
50+
"build:static": "./tools/pack-bindgen-src.rb ./dist",
5151
"build:rollup": "rollup -c rollup.config.mjs",
5252
"build:tsc": "tsc -p tsconfig.json && tsc -p tsconfig.cjs.json",
5353
"build": "npm run build:rollup && npm run build:tsc && npm run build:static && ./tools/post-build.sh ./dist"

0 commit comments

Comments
 (0)