File tree Expand file tree Collapse file tree 3 files changed +37
-2
lines changed
packages/npm-packages/ruby-wasm-wasi Expand file tree Collapse file tree 3 files changed +37
-2
lines changed Original file line number Diff line number Diff line change @@ -146,7 +146,7 @@ export class RubyVM {
146146 "\n" +
147147 "Please check your call stack and make sure that you are **not** doing any of the following inside the nested Ruby frame:\n" +
148148 " 1. Switching fibers (e.g. Fiber#resume, Fiber.yield, and Fiber#transfer)\n" +
149- " Note that JS::Object#await switches fibers internally\n" +
149+ " Note that `evalAsync` JS API switches fibers internally\n" +
150150 " 2. Raising uncaught exceptions\n" +
151151 " Please catch all exceptions inside the nested operation\n" +
152152 " 3. Calling Continuation APIs\n"
Original file line number Diff line number Diff line change @@ -14,13 +14,14 @@ const rubyModule = (async () => {
1414 return await WebAssembly . compile ( binary . buffer ) ;
1515} ) ( ) ;
1616
17- export const initRubyVM = async ( ) => {
17+ export const initRubyVM = async ( { suppressStderr } = { suppressStderr : false } ) => {
1818 let preopens = { } ;
1919 if ( process . env . RUBY_ROOT ) {
2020 preopens [ "/usr" ] = path . join ( process . env . RUBY_ROOT , "./usr" ) ;
2121 }
2222 const wasi = new WASI ( {
2323 args : [ "ruby.wasm" ] . concat ( process . argv . slice ( 2 ) ) ,
24+ stderr : suppressStderr ? 0 : 2 ,
2425 preopens,
2526 } ) ;
2627
Original file line number Diff line number Diff line change @@ -139,6 +139,40 @@ eval:11:in \`<main>'`);
139139 } ) . toThrowError ( "Ruby APIs that may rewind the VM stack are prohibited" ) ;
140140 } ) ;
141141
142+ test . each ( [
143+ `JS::RubyVM.evalAsync("")` ,
144+ ] ) ( "nested VM rewinding operation should throw fatal error (async)" , async ( code ) => {
145+ // Supress bugreport message triggered by the fatal error inside evalAsync
146+ const vm = await initRubyVM ( { suppressStderr : true } ) ;
147+ const setVM = vm . eval ( `proc { |vm| JS::RubyVM = vm }` ) ;
148+ setVM . call ( "call" , vm . wrap ( vm ) ) ;
149+
150+ // HACK: We need to capture all promises to avoid unhandled promise rejection
151+ const promises : Promise < any > [ ] = [ ]
152+ const _Promise = global . Promise
153+ const spy = jest . spyOn ( global , "Promise" )
154+ . mockImplementation ( ( future ) => {
155+ const promise = new _Promise ( future )
156+ promises . push ( promise )
157+ return promise
158+ } )
159+
160+ vm . evalAsync ( code )
161+
162+ const rejections : Error [ ] = [ ]
163+ for ( const promise of promises ) {
164+ try {
165+ await promise
166+ } catch ( e ) {
167+ rejections . push ( e )
168+ }
169+ }
170+
171+ spy . mockReset ( )
172+
173+ expect ( rejections [ 0 ] . message ) . toMatch ( "Ruby APIs that may rewind the VM stack are prohibited" )
174+ } ) ;
175+
142176 test ( "caught raise in nested eval is ok" , async ( ) => {
143177 const vm = await initRubyVM ( ) ;
144178 const setVM = vm . eval ( `proc { |vm| JS::RubyVM = vm }` ) ;
You can’t perform that action at this time.
0 commit comments