@@ -2,6 +2,7 @@ import * as fs from "fs/promises";
2
2
import * as path from "path" ;
3
3
import { WASI } from "wasi" ;
4
4
import { RubyVM } from "../src/index" ;
5
+ import * as preview2Shim from "@bytecodealliance/preview2-shim"
5
6
6
7
const rubyModule = ( async ( ) => {
7
8
let binaryPath ;
@@ -19,7 +20,7 @@ const rubyModule = (async () => {
19
20
return await WebAssembly . compile ( binary . buffer ) ;
20
21
} ) ( ) ;
21
22
22
- const initRubyVM = async ( { suppressStderr } = { suppressStderr : false } ) => {
23
+ const initModuleRubyVM = async ( { suppressStderr } = { suppressStderr : false } ) => {
23
24
let preopens = { } ;
24
25
if ( process . env . RUBY_ROOT ) {
25
26
preopens [ "/usr" ] = path . join ( process . env . RUBY_ROOT , "./usr" ) ;
@@ -51,6 +52,66 @@ const initRubyVM = async ({ suppressStderr } = { suppressStderr: false }) => {
51
52
return vm ;
52
53
} ;
53
54
55
+ const moduleCache = new Map ( ) ;
56
+ async function initComponentRubyVM ( { suppressStderr } = { suppressStderr : false } ) {
57
+ const pkgPath = process . env . RUBY_NPM_PACKAGE_ROOT
58
+ if ( ! pkgPath ) {
59
+ throw new Error ( "RUBY_NPM_PACKAGE_ROOT must be set" ) ;
60
+ }
61
+ const componentJsPath = path . resolve ( pkgPath , "dist/component/ruby.component.js" ) ;
62
+ const { instantiate } = await import ( componentJsPath ) ;
63
+ const getCoreModule = async ( relativePath ) => {
64
+ const coreModulePath = path . resolve ( pkgPath , "dist/component" , relativePath ) ;
65
+ if ( moduleCache . has ( coreModulePath ) ) {
66
+ return moduleCache . get ( coreModulePath ) ;
67
+ }
68
+ const buffer = await fs . readFile ( coreModulePath ) ;
69
+ const module = WebAssembly . compile ( buffer ) ;
70
+ moduleCache . set ( coreModulePath , module ) ;
71
+ return module ;
72
+ }
73
+ const vm = await RubyVM . _instantiate ( async ( jsRuntime ) => {
74
+ const { cli, clocks, filesystem, io, random, sockets } = preview2Shim ;
75
+ filesystem . _setPreopens ( {
76
+ "/usr" : path . join ( process . env . RUBY_BUILD_ROOT , "usr" ) ,
77
+ "/bundle" : path . join ( process . env . RUBY_BUILD_ROOT , "bundle" ) ,
78
+ } )
79
+ cli . _setArgs ( [ "ruby.wasm" ] . concat ( process . argv . slice ( 2 ) ) ) ;
80
+ cli . _setCwd ( "/" )
81
+ const root = await instantiate ( getCoreModule , {
82
+ "ruby:js/js-runtime" : jsRuntime ,
83
+ "wasi:cli/environment" : cli . environment ,
84
+ "wasi:cli/exit" : cli . exit ,
85
+ "wasi:cli/stderr" : cli . stderr ,
86
+ "wasi:cli/stdin" : cli . stdin ,
87
+ "wasi:cli/stdout" : cli . stdout ,
88
+ "wasi:cli/terminal-input" : cli . terminalInput ,
89
+ "wasi:cli/terminal-output" : cli . terminalOutput ,
90
+ "wasi:cli/terminal-stderr" : cli . terminalStderr ,
91
+ "wasi:cli/terminal-stdin" : cli . terminalStdin ,
92
+ "wasi:cli/terminal-stdout" : cli . terminalStdout ,
93
+ "wasi:clocks/monotonic-clock" : clocks . monotonicClock ,
94
+ "wasi:clocks/wall-clock" : clocks . wallClock ,
95
+ "wasi:filesystem/preopens" : filesystem . preopens ,
96
+ "wasi:filesystem/types" : filesystem . types ,
97
+ "wasi:io/error" : io . error ,
98
+ "wasi:io/poll" : io . poll ,
99
+ "wasi:io/streams" : io . streams ,
100
+ "wasi:random/random" : random . random ,
101
+ "wasi:sockets/tcp" : sockets . tcp ,
102
+ } )
103
+ return root . rubyRuntime ;
104
+ } , { } )
105
+ return vm ;
106
+ }
107
+
108
+ const initRubyVM = async ( { suppressStderr } = { suppressStderr : false } ) => {
109
+ if ( process . env . ENABLE_COMPONENT_TESTS && process . env . ENABLE_COMPONENT_TESTS !== 'false' ) {
110
+ return initComponentRubyVM ( { suppressStderr } ) ;
111
+ }
112
+ return initModuleRubyVM ( { suppressStderr } ) ;
113
+ }
114
+
54
115
class RubyVersion {
55
116
constructor ( version ) {
56
117
this . version = version ;
0 commit comments