@@ -32,16 +32,24 @@ export class RubyVM {
3232 private exceptionFormatter : RbExceptionFormatter ;
3333 private interfaceState : RbAbiInterfaceState = {
3434 hasJSFrameAfterRbFrame : false ,
35- }
35+ } ;
3636
3737 constructor ( ) {
3838 // Wrap exported functions from Ruby VM to prohibit nested VM operation
3939 // if the call stack has sandwitched JS frames like JS -> Ruby -> JS -> Ruby.
4040 const proxyExports = ( exports : RbAbi . RbAbiGuest ) => {
41- const excludedMethods : ( keyof RbAbi . RbAbiGuest ) [ ] = [ "addToImports" , "instantiate" , "rbSetShouldProhibitRewind" , "rbGcDisable" , "rbGcEnable" ] ;
41+ const excludedMethods : ( keyof RbAbi . RbAbiGuest ) [ ] = [
42+ "addToImports" ,
43+ "instantiate" ,
44+ "rbSetShouldProhibitRewind" ,
45+ "rbGcDisable" ,
46+ "rbGcEnable" ,
47+ ] ;
4248 const excluded = [ "constructor" ] . concat ( excludedMethods ) ;
4349 // wrap all methods in RbAbi.RbAbiGuest class
44- for ( const key of Object . getOwnPropertyNames ( RbAbi . RbAbiGuest . prototype ) ) {
50+ for ( const key of Object . getOwnPropertyNames (
51+ RbAbi . RbAbiGuest . prototype
52+ ) ) {
4553 if ( excluded . includes ( key ) ) {
4654 continue ;
4755 }
@@ -50,22 +58,23 @@ export class RubyVM {
5058 exports [ key ] = ( ...args : any [ ] ) => {
5159 const isNestedVMCall = this . interfaceState . hasJSFrameAfterRbFrame ;
5260 if ( isNestedVMCall ) {
53- const oldShouldProhibitRewind = this . guest . rbSetShouldProhibitRewind ( true )
54- const oldIsDisabledGc = this . guest . rbGcDisable ( )
55- const result = Reflect . apply ( value , exports , args )
56- this . guest . rbSetShouldProhibitRewind ( oldShouldProhibitRewind )
61+ const oldShouldProhibitRewind =
62+ this . guest . rbSetShouldProhibitRewind ( true ) ;
63+ const oldIsDisabledGc = this . guest . rbGcDisable ( ) ;
64+ const result = Reflect . apply ( value , exports , args ) ;
65+ this . guest . rbSetShouldProhibitRewind ( oldShouldProhibitRewind ) ;
5766 if ( ! oldIsDisabledGc ) {
58- this . guest . rbGcEnable ( )
67+ this . guest . rbGcEnable ( ) ;
5968 }
6069 return result ;
6170 } else {
62- return Reflect . apply ( value , exports , args )
71+ return Reflect . apply ( value , exports , args ) ;
6372 }
64- }
73+ } ;
6574 }
6675 }
6776 return exports ;
68- }
77+ } ;
6978 this . guest = proxyExports ( new RbAbi . RbAbiGuest ( ) ) ;
7079 this . transport = new JsValueTransport ( ) ;
7180 this . exceptionFormatter = new RbExceptionFormatter ( ) ;
@@ -121,25 +130,29 @@ export class RubyVM {
121130 } ;
122131 }
123132 imports [ "rb-js-abi-host" ] = {
124- rb_wasm_throw_prohibit_rewind_exception : ( messagePtr : number , messageLen : number ) => {
133+ rb_wasm_throw_prohibit_rewind_exception : (
134+ messagePtr : number ,
135+ messageLen : number
136+ ) => {
125137 const memory = this . instance . exports . memory as WebAssembly . Memory ;
126138 const str = new TextDecoder ( ) . decode (
127139 new Uint8Array ( memory . buffer , messagePtr , messageLen )
128140 ) ;
129141 throw new RbFatalError (
130- "Ruby APIs that may rewind the VM stack are prohibited under nested VM operation " + `(${ str } )\n`
131- + "Nested VM operation means that the call stack has sandwitched JS frames like JS -> Ruby -> JS -> Ruby "
132- + "caused by something like `window.rubyVM.eval(\"JS.global[:rubyVM].eval('Fiber.yield')\")`\n"
133- + "\n"
134- + "Please check your call stack and make sure that you are **not** doing any of the following inside the nested Ruby frame:\n"
135- + " 1. Switching fibers (e.g. Fiber#resume, Fiber.yield, and Fiber#transfer)\n"
136- + " Note that JS::Object#await switches fibers internally\n"
137- + " 2. Raising uncaught exceptions\n"
138- + " Please catch all exceptions inside the nested operation\n"
139- + " 3. Calling Continuation APIs\n"
142+ "Ruby APIs that may rewind the VM stack are prohibited under nested VM operation " +
143+ `(${ str } )\n` +
144+ "Nested VM operation means that the call stack has sandwitched JS frames like JS -> Ruby -> JS -> Ruby " +
145+ "caused by something like `window.rubyVM.eval(\"JS.global[:rubyVM].eval('Fiber.yield')\")`\n" +
146+ "\n" +
147+ "Please check your call stack and make sure that you are **not** doing any of the following inside the nested Ruby frame:\n" +
148+ " 1. Switching fibers (e.g. Fiber#resume, Fiber.yield, and Fiber#transfer)\n" +
149+ " Note that JS::Object#await switches fibers internally\n" +
150+ " 2. Raising uncaught exceptions\n" +
151+ " Please catch all exceptions inside the nested operation\n" +
152+ " 3. Calling Continuation APIs\n"
140153 ) ;
141- }
142- }
154+ } ,
155+ } ;
143156 // NOTE: The GC may collect objects that are still referenced by Wasm
144157 // locals because Asyncify cannot scan the Wasm stack above the JS frame.
145158 // So we need to keep track whether the JS frame is sandwitched by Ruby
@@ -153,7 +166,7 @@ export class RubyVM {
153166 const result = Reflect . apply ( value , imports , args ) ;
154167 this . interfaceState . hasJSFrameAfterRbFrame = oldValue ;
155168 return result ;
156- }
169+ } ;
157170 }
158171 }
159172 return imports ;
@@ -377,9 +390,9 @@ type RbAbiInterfaceState = {
377390 /**
378391 * Track if the last JS frame that was created by a Ruby frame
379392 * to determine if we have a sandwitched JS frame between Ruby frames.
380- **/
393+ **/
381394 hasJSFrameAfterRbFrame : boolean ;
382- }
395+ } ;
383396
384397/**
385398 * Export a JS value held by the Ruby VM to the JS environment.
0 commit comments