@@ -2,6 +2,7 @@ import * as fs from "fs/promises";
22import * as path from "path" ;
33import { WASI } from "wasi" ;
44import { RubyVM } from "../src/index" ;
5+ import * as preview2Shim from "@bytecodealliance/preview2-shim"
56
67const rubyModule = ( async ( ) => {
78 let binaryPath ;
@@ -19,7 +20,7 @@ const rubyModule = (async () => {
1920 return await WebAssembly . compile ( binary . buffer ) ;
2021} ) ( ) ;
2122
22- const initRubyVM = async ( { suppressStderr } = { suppressStderr : false } ) => {
23+ const initModuleRubyVM = async ( { suppressStderr } = { suppressStderr : false } ) => {
2324 let preopens = { } ;
2425 if ( process . env . RUBY_ROOT ) {
2526 preopens [ "/usr" ] = path . join ( process . env . RUBY_ROOT , "./usr" ) ;
@@ -51,6 +52,66 @@ const initRubyVM = async ({ suppressStderr } = { suppressStderr: false }) => {
5152 return vm ;
5253} ;
5354
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+
54115class RubyVersion {
55116 constructor ( version ) {
56117 this . version = version ;
0 commit comments