@ruby/head-wasm-wasi 2.5.1 → 2.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/browser.script.iife.js +183 -68
  2. package/dist/browser.script.umd.js +181 -66
  3. package/dist/browser.umd.js +181 -66
  4. package/dist/component/interfaces/ruby-js-js-runtime.d.ts +45 -0
  5. package/dist/component/interfaces/ruby-js-ruby-runtime.d.ts +31 -0
  6. package/dist/component/interfaces/wasi-cli-environment.d.ts +3 -0
  7. package/dist/component/interfaces/wasi-cli-exit.d.ts +4 -0
  8. package/dist/component/interfaces/wasi-cli-stderr.d.ts +5 -0
  9. package/dist/component/interfaces/wasi-cli-stdin.d.ts +5 -0
  10. package/dist/component/interfaces/wasi-cli-stdout.d.ts +5 -0
  11. package/dist/component/interfaces/wasi-cli-terminal-input.d.ts +6 -0
  12. package/dist/component/interfaces/wasi-cli-terminal-output.d.ts +6 -0
  13. package/dist/component/interfaces/wasi-cli-terminal-stderr.d.ts +5 -0
  14. package/dist/component/interfaces/wasi-cli-terminal-stdin.d.ts +5 -0
  15. package/dist/component/interfaces/wasi-cli-terminal-stdout.d.ts +5 -0
  16. package/dist/component/interfaces/wasi-clocks-monotonic-clock.d.ts +10 -0
  17. package/dist/component/interfaces/wasi-clocks-wall-clock.d.ts +8 -0
  18. package/dist/component/interfaces/wasi-filesystem-preopens.d.ts +5 -0
  19. package/dist/component/interfaces/wasi-filesystem-types.d.ts +205 -0
  20. package/dist/component/interfaces/wasi-io-error.d.ts +6 -0
  21. package/dist/component/interfaces/wasi-io-poll.d.ts +7 -0
  22. package/dist/component/interfaces/wasi-io-streams.d.ts +30 -0
  23. package/dist/component/interfaces/wasi-random-random.d.ts +3 -0
  24. package/dist/component/package.json +1 -0
  25. package/dist/component/ruby.component.core.wasm +0 -0
  26. package/dist/component/ruby.component.core2.wasm +0 -0
  27. package/dist/component/ruby.component.core3.wasm +0 -0
  28. package/dist/component/ruby.component.core4.wasm +0 -0
  29. package/dist/component/ruby.component.d.ts +71 -0
  30. package/dist/component/ruby.component.js +7523 -0
  31. package/dist/index.umd.js +169 -63
  32. package/dist/ruby+stdlib.wasm +0 -0
  33. package/dist/ruby.debug+stdlib.wasm +0 -0
  34. package/dist/ruby.wasm +0 -0
  35. package/package.json +2 -2
@@ -49,11 +49,15 @@ Please replace your \`require('ruby-head-wasm-wasi/dist/browser.script.umd');\`
49
49
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
50
50
  };
51
51
 
52
- const CLOCKID_REALTIME=0;const CLOCKID_MONOTONIC=1;const ERRNO_SUCCESS=0;const ERRNO_BADF=8;const ERRNO_NOSYS=52;class Iovec{static read_bytes(view,ptr){const iovec=new Iovec;iovec.buf=view.getUint32(ptr,true);iovec.buf_len=view.getUint32(ptr+4,true);return iovec}static read_bytes_array(view,ptr,len){const iovecs=[];for(let i=0;i<len;i++){iovecs.push(Iovec.read_bytes(view,ptr+8*i));}return iovecs}}class Ciovec{static read_bytes(view,ptr){const iovec=new Ciovec;iovec.buf=view.getUint32(ptr,true);iovec.buf_len=view.getUint32(ptr+4,true);return iovec}static read_bytes_array(view,ptr,len){const iovecs=[];for(let i=0;i<len;i++){iovecs.push(Ciovec.read_bytes(view,ptr+8*i));}return iovecs}}
52
+ const CLOCKID_REALTIME=0;const CLOCKID_MONOTONIC=1;const ERRNO_SUCCESS=0;const ERRNO_BADF=8;const ERRNO_EXIST=20;const ERRNO_INVAL=28;const ERRNO_ISDIR=31;const ERRNO_NAMETOOLONG=37;const ERRNO_NOENT=44;const ERRNO_NOSYS=52;const ERRNO_NOTDIR=54;const ERRNO_NOTEMPTY=55;const ERRNO_NOTSUP=58;const ERRNO_PERM=63;const ERRNO_NOTCAPABLE=76;const RIGHTS_FD_WRITE=1<<6;class Iovec{static read_bytes(view,ptr){const iovec=new Iovec;iovec.buf=view.getUint32(ptr,true);iovec.buf_len=view.getUint32(ptr+4,true);return iovec}static read_bytes_array(view,ptr,len){const iovecs=[];for(let i=0;i<len;i++){iovecs.push(Iovec.read_bytes(view,ptr+8*i));}return iovecs}}class Ciovec{static read_bytes(view,ptr){const iovec=new Ciovec;iovec.buf=view.getUint32(ptr,true);iovec.buf_len=view.getUint32(ptr+4,true);return iovec}static read_bytes_array(view,ptr,len){const iovecs=[];for(let i=0;i<len;i++){iovecs.push(Ciovec.read_bytes(view,ptr+8*i));}return iovecs}}const WHENCE_SET=0;const WHENCE_CUR=1;const WHENCE_END=2;const FILETYPE_DIRECTORY=3;const FILETYPE_REGULAR_FILE=4;class Dirent{head_length(){return 24}name_length(){return this.dir_name.byteLength}write_head_bytes(view,ptr){view.setBigUint64(ptr,this.d_next,true);view.setBigUint64(ptr+8,this.d_ino,true);view.setUint32(ptr+16,this.dir_name.length,true);view.setUint8(ptr+20,this.d_type);}write_name_bytes(view8,ptr,buf_len){view8.set(this.dir_name.slice(0,Math.min(this.dir_name.byteLength,buf_len)),ptr);}constructor(next_cookie,name,type){this.d_ino=0n;const encoded_name=new TextEncoder().encode(name);this.d_next=next_cookie;this.d_namlen=encoded_name.byteLength;this.d_type=type;this.dir_name=encoded_name;}}const FDFLAGS_APPEND=1<<0;class Fdstat{write_bytes(view,ptr){view.setUint8(ptr,this.fs_filetype);view.setUint16(ptr+2,this.fs_flags,true);view.setBigUint64(ptr+8,this.fs_rights_base,true);view.setBigUint64(ptr+16,this.fs_rights_inherited,true);}constructor(filetype,flags){this.fs_rights_base=0n;this.fs_rights_inherited=0n;this.fs_filetype=filetype;this.fs_flags=flags;}}const OFLAGS_CREAT=1<<0;const OFLAGS_DIRECTORY=1<<1;const OFLAGS_EXCL=1<<2;const OFLAGS_TRUNC=1<<3;class Filestat{write_bytes(view,ptr){view.setBigUint64(ptr,this.dev,true);view.setBigUint64(ptr+8,this.ino,true);view.setUint8(ptr+16,this.filetype);view.setBigUint64(ptr+24,this.nlink,true);view.setBigUint64(ptr+32,this.size,true);view.setBigUint64(ptr+38,this.atim,true);view.setBigUint64(ptr+46,this.mtim,true);view.setBigUint64(ptr+52,this.ctim,true);}constructor(filetype,size){this.dev=0n;this.ino=0n;this.nlink=0n;this.atim=0n;this.mtim=0n;this.ctim=0n;this.filetype=filetype;this.size=size;}}const PREOPENTYPE_DIR=0;class PrestatDir{write_bytes(view,ptr){view.setUint32(ptr,this.pr_name.byteLength,true);}constructor(name){this.pr_name=new TextEncoder().encode(name);}}class Prestat{static dir(name){const prestat=new Prestat;prestat.tag=PREOPENTYPE_DIR;prestat.inner=new PrestatDir(name);return prestat}write_bytes(view,ptr){view.setUint32(ptr,this.tag,true);this.inner.write_bytes(view,ptr+4);}}
53
53
 
54
54
  let Debug=class Debug{enable(enabled){this.log=createLogger(enabled===undefined?true:enabled,this.prefix);}get enabled(){return this.isEnabled}constructor(isEnabled){this.isEnabled=isEnabled;this.prefix="wasi:";this.enable(isEnabled);}};function createLogger(enabled,prefix){if(enabled){const a=console.log.bind(console,"%c%s","color: #265BA0",prefix);return a}else {return ()=>{}}}const debug=new Debug(false);
55
55
 
56
- class WASIProcExit extends Error{constructor(code){super("exit with exit code "+code);this.code=code;}}let WASI=class WASI{start(instance){this.inst=instance;try{instance.exports._start();return 0}catch(e){if(e instanceof WASIProcExit){return e.code}else {throw e}}}initialize(instance){this.inst=instance;instance.exports._initialize();}constructor(args,env,fds,options={}){this.args=[];this.env=[];this.fds=[];debug.enable(options.debug);this.args=args;this.env=env;this.fds=fds;const self=this;this.wasiImport={args_sizes_get(argc,argv_buf_size){const buffer=new DataView(self.inst.exports.memory.buffer);buffer.setUint32(argc,self.args.length,true);let buf_size=0;for(const arg of self.args){buf_size+=arg.length+1;}buffer.setUint32(argv_buf_size,buf_size,true);debug.log(buffer.getUint32(argc,true),buffer.getUint32(argv_buf_size,true));return 0},args_get(argv,argv_buf){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);const orig_argv_buf=argv_buf;for(let i=0;i<self.args.length;i++){buffer.setUint32(argv,argv_buf,true);argv+=4;const arg=new TextEncoder().encode(self.args[i]);buffer8.set(arg,argv_buf);buffer.setUint8(argv_buf+arg.length,0);argv_buf+=arg.length+1;}if(debug.enabled){debug.log(new TextDecoder("utf-8").decode(buffer8.slice(orig_argv_buf,argv_buf)));}return 0},environ_sizes_get(environ_count,environ_size){const buffer=new DataView(self.inst.exports.memory.buffer);buffer.setUint32(environ_count,self.env.length,true);let buf_size=0;for(const environ of self.env){buf_size+=environ.length+1;}buffer.setUint32(environ_size,buf_size,true);debug.log(buffer.getUint32(environ_count,true),buffer.getUint32(environ_size,true));return 0},environ_get(environ,environ_buf){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);const orig_environ_buf=environ_buf;for(let i=0;i<self.env.length;i++){buffer.setUint32(environ,environ_buf,true);environ+=4;const e=new TextEncoder().encode(self.env[i]);buffer8.set(e,environ_buf);buffer.setUint8(environ_buf+e.length,0);environ_buf+=e.length+1;}if(debug.enabled){debug.log(new TextDecoder("utf-8").decode(buffer8.slice(orig_environ_buf,environ_buf)));}return 0},clock_res_get(id,res_ptr){let resolutionValue;switch(id){case CLOCKID_MONOTONIC:{resolutionValue=5000n;break}case CLOCKID_REALTIME:{resolutionValue=1000000n;break}default:return ERRNO_NOSYS}const view=new DataView(self.inst.exports.memory.buffer);view.setBigUint64(res_ptr,resolutionValue,true);return ERRNO_SUCCESS},clock_time_get(id,precision,time){const buffer=new DataView(self.inst.exports.memory.buffer);if(id===CLOCKID_REALTIME){buffer.setBigUint64(time,BigInt(new Date().getTime())*1000000n,true);}else if(id==CLOCKID_MONOTONIC){let monotonic_time;try{monotonic_time=BigInt(Math.round(performance.now()*1e6));}catch(e){monotonic_time=0n;}buffer.setBigUint64(time,monotonic_time,true);}else {buffer.setBigUint64(time,0n,true);}return 0},fd_advise(fd,offset,len,advice){if(self.fds[fd]!=undefined){return self.fds[fd].fd_advise(offset,len,advice)}else {return ERRNO_BADF}},fd_allocate(fd,offset,len){if(self.fds[fd]!=undefined){return self.fds[fd].fd_allocate(offset,len)}else {return ERRNO_BADF}},fd_close(fd){if(self.fds[fd]!=undefined){const ret=self.fds[fd].fd_close();self.fds[fd]=undefined;return ret}else {return ERRNO_BADF}},fd_datasync(fd){if(self.fds[fd]!=undefined){return self.fds[fd].fd_datasync()}else {return ERRNO_BADF}},fd_fdstat_get(fd,fdstat_ptr){if(self.fds[fd]!=undefined){const{ret,fdstat}=self.fds[fd].fd_fdstat_get();if(fdstat!=null){fdstat.write_bytes(new DataView(self.inst.exports.memory.buffer),fdstat_ptr);}return ret}else {return ERRNO_BADF}},fd_fdstat_set_flags(fd,flags){if(self.fds[fd]!=undefined){return self.fds[fd].fd_fdstat_set_flags(flags)}else {return ERRNO_BADF}},fd_fdstat_set_rights(fd,fs_rights_base,fs_rights_inheriting){if(self.fds[fd]!=undefined){return self.fds[fd].fd_fdstat_set_rights(fs_rights_base,fs_rights_inheriting)}else {return ERRNO_BADF}},fd_filestat_get(fd,filestat_ptr){if(self.fds[fd]!=undefined){const{ret,filestat}=self.fds[fd].fd_filestat_get();if(filestat!=null){filestat.write_bytes(new DataView(self.inst.exports.memory.buffer),filestat_ptr);}return ret}else {return ERRNO_BADF}},fd_filestat_set_size(fd,size){if(self.fds[fd]!=undefined){return self.fds[fd].fd_filestat_set_size(size)}else {return ERRNO_BADF}},fd_filestat_set_times(fd,atim,mtim,fst_flags){if(self.fds[fd]!=undefined){return self.fds[fd].fd_filestat_set_times(atim,mtim,fst_flags)}else {return ERRNO_BADF}},fd_pread(fd,iovs_ptr,iovs_len,offset,nread_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const iovecs=Iovec.read_bytes_array(buffer,iovs_ptr,iovs_len);const{ret,nread}=self.fds[fd].fd_pread(buffer8,iovecs,offset);buffer.setUint32(nread_ptr,nread,true);return ret}else {return ERRNO_BADF}},fd_prestat_get(fd,buf_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const{ret,prestat}=self.fds[fd].fd_prestat_get();if(prestat!=null){prestat.write_bytes(buffer,buf_ptr);}return ret}else {return ERRNO_BADF}},fd_prestat_dir_name(fd,path_ptr,path_len){if(self.fds[fd]!=undefined){const{ret,prestat_dir_name}=self.fds[fd].fd_prestat_dir_name();if(prestat_dir_name!=null){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);buffer8.set(prestat_dir_name,path_ptr);}return ret}else {return ERRNO_BADF}},fd_pwrite(fd,iovs_ptr,iovs_len,offset,nwritten_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const iovecs=Ciovec.read_bytes_array(buffer,iovs_ptr,iovs_len);const{ret,nwritten}=self.fds[fd].fd_pwrite(buffer8,iovecs,offset);buffer.setUint32(nwritten_ptr,nwritten,true);return ret}else {return ERRNO_BADF}},fd_read(fd,iovs_ptr,iovs_len,nread_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const iovecs=Iovec.read_bytes_array(buffer,iovs_ptr,iovs_len);const{ret,nread}=self.fds[fd].fd_read(buffer8,iovecs);buffer.setUint32(nread_ptr,nread,true);return ret}else {return ERRNO_BADF}},fd_readdir(fd,buf,buf_len,cookie,bufused_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){let bufused=0;while(true){const{ret,dirent}=self.fds[fd].fd_readdir_single(cookie);if(ret!=0){buffer.setUint32(bufused_ptr,bufused,true);return ret}if(dirent==null){break}if(buf_len-bufused<dirent.head_length()){bufused=buf_len;break}const head_bytes=new ArrayBuffer(dirent.head_length());dirent.write_head_bytes(new DataView(head_bytes),0);buffer8.set(new Uint8Array(head_bytes).slice(0,Math.min(head_bytes.byteLength,buf_len-bufused)),buf);buf+=dirent.head_length();bufused+=dirent.head_length();if(buf_len-bufused<dirent.name_length()){bufused=buf_len;break}dirent.write_name_bytes(buffer8,buf,buf_len-bufused);buf+=dirent.name_length();bufused+=dirent.name_length();cookie=dirent.d_next;}buffer.setUint32(bufused_ptr,bufused,true);return 0}else {return ERRNO_BADF}},fd_renumber(fd,to){if(self.fds[fd]!=undefined&&self.fds[to]!=undefined){const ret=self.fds[to].fd_close();if(ret!=0){return ret}self.fds[to]=self.fds[fd];self.fds[fd]=undefined;return 0}else {return ERRNO_BADF}},fd_seek(fd,offset,whence,offset_out_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const{ret,offset:offset_out}=self.fds[fd].fd_seek(offset,whence);buffer.setBigInt64(offset_out_ptr,offset_out,true);return ret}else {return ERRNO_BADF}},fd_sync(fd){if(self.fds[fd]!=undefined){return self.fds[fd].fd_sync()}else {return ERRNO_BADF}},fd_tell(fd,offset_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const{ret,offset}=self.fds[fd].fd_tell();buffer.setBigUint64(offset_ptr,offset,true);return ret}else {return ERRNO_BADF}},fd_write(fd,iovs_ptr,iovs_len,nwritten_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const iovecs=Ciovec.read_bytes_array(buffer,iovs_ptr,iovs_len);const{ret,nwritten}=self.fds[fd].fd_write(buffer8,iovecs);buffer.setUint32(nwritten_ptr,nwritten,true);return ret}else {return ERRNO_BADF}},path_create_directory(fd,path_ptr,path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));return self.fds[fd].path_create_directory(path)}},path_filestat_get(fd,flags,path_ptr,path_len,filestat_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));const{ret,filestat}=self.fds[fd].path_filestat_get(flags,path);if(filestat!=null){filestat.write_bytes(buffer,filestat_ptr);}return ret}else {return ERRNO_BADF}},path_filestat_set_times(fd,flags,path_ptr,path_len,atim,mtim,fst_flags){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));return self.fds[fd].path_filestat_set_times(flags,path,atim,mtim,fst_flags)}else {return ERRNO_BADF}},path_link(old_fd,old_flags,old_path_ptr,old_path_len,new_fd,new_path_ptr,new_path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[old_fd]!=undefined&&self.fds[new_fd]!=undefined){const old_path=new TextDecoder("utf-8").decode(buffer8.slice(old_path_ptr,old_path_ptr+old_path_len));const new_path=new TextDecoder("utf-8").decode(buffer8.slice(new_path_ptr,new_path_ptr+new_path_len));return self.fds[new_fd].path_link(old_fd,old_flags,old_path,new_path)}else {return ERRNO_BADF}},path_open(fd,dirflags,path_ptr,path_len,oflags,fs_rights_base,fs_rights_inheriting,fd_flags,opened_fd_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));debug.log(path);const{ret,fd_obj}=self.fds[fd].path_open(dirflags,path,oflags,fs_rights_base,fs_rights_inheriting,fd_flags);if(ret!=0){return ret}self.fds.push(fd_obj);const opened_fd=self.fds.length-1;buffer.setUint32(opened_fd_ptr,opened_fd,true);return 0}else {return ERRNO_BADF}},path_readlink(fd,path_ptr,path_len,buf_ptr,buf_len,nread_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));debug.log(path);const{ret,data}=self.fds[fd].path_readlink(path);if(data!=null){const data_buf=new TextEncoder().encode(data);if(data_buf.length>buf_len){buffer.setUint32(nread_ptr,0,true);return ERRNO_BADF}buffer8.set(data_buf,buf_ptr);buffer.setUint32(nread_ptr,data_buf.length,true);}return ret}else {return ERRNO_BADF}},path_remove_directory(fd,path_ptr,path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));return self.fds[fd].path_remove_directory(path)}else {return ERRNO_BADF}},path_rename(fd,old_path_ptr,old_path_len,new_fd,new_path_ptr,new_path_len){throw "FIXME what is the best abstraction for this?"},path_symlink(old_path_ptr,old_path_len,fd,new_path_ptr,new_path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const old_path=new TextDecoder("utf-8").decode(buffer8.slice(old_path_ptr,old_path_ptr+old_path_len));const new_path=new TextDecoder("utf-8").decode(buffer8.slice(new_path_ptr,new_path_ptr+new_path_len));return self.fds[fd].path_symlink(old_path,new_path)}else {return ERRNO_BADF}},path_unlink_file(fd,path_ptr,path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));return self.fds[fd].path_unlink_file(path)}else {return ERRNO_BADF}},poll_oneoff(in_,out,nsubscriptions){throw "async io not supported"},proc_exit(exit_code){throw new WASIProcExit(exit_code)},proc_raise(sig){throw "raised signal "+sig},sched_yield(){},random_get(buf,buf_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);for(let i=0;i<buf_len;i++){buffer8[buf+i]=Math.random()*256|0;}},sock_recv(fd,ri_data,ri_flags){throw "sockets not supported"},sock_send(fd,si_data,si_flags){throw "sockets not supported"},sock_shutdown(fd,how){throw "sockets not supported"},sock_accept(fd,flags){throw "sockets not supported"}};}};
56
+ class WASIProcExit extends Error{constructor(code){super("exit with exit code "+code);this.code=code;}}let WASI=class WASI{start(instance){this.inst=instance;try{instance.exports._start();return 0}catch(e){if(e instanceof WASIProcExit){return e.code}else {throw e}}}initialize(instance){this.inst=instance;if(instance.exports._initialize){instance.exports._initialize();}}constructor(args,env,fds,options={}){this.args=[];this.env=[];this.fds=[];debug.enable(options.debug);this.args=args;this.env=env;this.fds=fds;const self=this;this.wasiImport={args_sizes_get(argc,argv_buf_size){const buffer=new DataView(self.inst.exports.memory.buffer);buffer.setUint32(argc,self.args.length,true);let buf_size=0;for(const arg of self.args){buf_size+=arg.length+1;}buffer.setUint32(argv_buf_size,buf_size,true);debug.log(buffer.getUint32(argc,true),buffer.getUint32(argv_buf_size,true));return 0},args_get(argv,argv_buf){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);const orig_argv_buf=argv_buf;for(let i=0;i<self.args.length;i++){buffer.setUint32(argv,argv_buf,true);argv+=4;const arg=new TextEncoder().encode(self.args[i]);buffer8.set(arg,argv_buf);buffer.setUint8(argv_buf+arg.length,0);argv_buf+=arg.length+1;}if(debug.enabled){debug.log(new TextDecoder("utf-8").decode(buffer8.slice(orig_argv_buf,argv_buf)));}return 0},environ_sizes_get(environ_count,environ_size){const buffer=new DataView(self.inst.exports.memory.buffer);buffer.setUint32(environ_count,self.env.length,true);let buf_size=0;for(const environ of self.env){buf_size+=environ.length+1;}buffer.setUint32(environ_size,buf_size,true);debug.log(buffer.getUint32(environ_count,true),buffer.getUint32(environ_size,true));return 0},environ_get(environ,environ_buf){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);const orig_environ_buf=environ_buf;for(let i=0;i<self.env.length;i++){buffer.setUint32(environ,environ_buf,true);environ+=4;const e=new TextEncoder().encode(self.env[i]);buffer8.set(e,environ_buf);buffer.setUint8(environ_buf+e.length,0);environ_buf+=e.length+1;}if(debug.enabled){debug.log(new TextDecoder("utf-8").decode(buffer8.slice(orig_environ_buf,environ_buf)));}return 0},clock_res_get(id,res_ptr){let resolutionValue;switch(id){case CLOCKID_MONOTONIC:{resolutionValue=5000n;break}case CLOCKID_REALTIME:{resolutionValue=1000000n;break}default:return ERRNO_NOSYS}const view=new DataView(self.inst.exports.memory.buffer);view.setBigUint64(res_ptr,resolutionValue,true);return ERRNO_SUCCESS},clock_time_get(id,precision,time){const buffer=new DataView(self.inst.exports.memory.buffer);if(id===CLOCKID_REALTIME){buffer.setBigUint64(time,BigInt(new Date().getTime())*1000000n,true);}else if(id==CLOCKID_MONOTONIC){let monotonic_time;try{monotonic_time=BigInt(Math.round(performance.now()*1e6));}catch(e){monotonic_time=0n;}buffer.setBigUint64(time,monotonic_time,true);}else {buffer.setBigUint64(time,0n,true);}return 0},fd_advise(fd,offset,len,advice){if(self.fds[fd]!=undefined){return ERRNO_SUCCESS}else {return ERRNO_BADF}},fd_allocate(fd,offset,len){if(self.fds[fd]!=undefined){return self.fds[fd].fd_allocate(offset,len)}else {return ERRNO_BADF}},fd_close(fd){if(self.fds[fd]!=undefined){const ret=self.fds[fd].fd_close();self.fds[fd]=undefined;return ret}else {return ERRNO_BADF}},fd_datasync(fd){if(self.fds[fd]!=undefined){return self.fds[fd].fd_sync()}else {return ERRNO_BADF}},fd_fdstat_get(fd,fdstat_ptr){if(self.fds[fd]!=undefined){const{ret,fdstat}=self.fds[fd].fd_fdstat_get();if(fdstat!=null){fdstat.write_bytes(new DataView(self.inst.exports.memory.buffer),fdstat_ptr);}return ret}else {return ERRNO_BADF}},fd_fdstat_set_flags(fd,flags){if(self.fds[fd]!=undefined){return self.fds[fd].fd_fdstat_set_flags(flags)}else {return ERRNO_BADF}},fd_fdstat_set_rights(fd,fs_rights_base,fs_rights_inheriting){if(self.fds[fd]!=undefined){return self.fds[fd].fd_fdstat_set_rights(fs_rights_base,fs_rights_inheriting)}else {return ERRNO_BADF}},fd_filestat_get(fd,filestat_ptr){if(self.fds[fd]!=undefined){const{ret,filestat}=self.fds[fd].fd_filestat_get();if(filestat!=null){filestat.write_bytes(new DataView(self.inst.exports.memory.buffer),filestat_ptr);}return ret}else {return ERRNO_BADF}},fd_filestat_set_size(fd,size){if(self.fds[fd]!=undefined){return self.fds[fd].fd_filestat_set_size(size)}else {return ERRNO_BADF}},fd_filestat_set_times(fd,atim,mtim,fst_flags){if(self.fds[fd]!=undefined){return self.fds[fd].fd_filestat_set_times(atim,mtim,fst_flags)}else {return ERRNO_BADF}},fd_pread(fd,iovs_ptr,iovs_len,offset,nread_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const iovecs=Iovec.read_bytes_array(buffer,iovs_ptr,iovs_len);let nread=0;for(const iovec of iovecs){const{ret,data}=self.fds[fd].fd_pread(iovec.buf_len,offset);if(ret!=ERRNO_SUCCESS){buffer.setUint32(nread_ptr,nread,true);return ret}buffer8.set(data,iovec.buf);nread+=data.length;offset+=BigInt(data.length);if(data.length!=iovec.buf_len){break}}buffer.setUint32(nread_ptr,nread,true);return ERRNO_SUCCESS}else {return ERRNO_BADF}},fd_prestat_get(fd,buf_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const{ret,prestat}=self.fds[fd].fd_prestat_get();if(prestat!=null){prestat.write_bytes(buffer,buf_ptr);}return ret}else {return ERRNO_BADF}},fd_prestat_dir_name(fd,path_ptr,path_len){if(self.fds[fd]!=undefined){const{ret,prestat}=self.fds[fd].fd_prestat_get();if(prestat==null){return ret}const prestat_dir_name=prestat.inner.pr_name;const buffer8=new Uint8Array(self.inst.exports.memory.buffer);buffer8.set(prestat_dir_name.slice(0,path_len),path_ptr);return prestat_dir_name.byteLength>path_len?ERRNO_NAMETOOLONG:ERRNO_SUCCESS}else {return ERRNO_BADF}},fd_pwrite(fd,iovs_ptr,iovs_len,offset,nwritten_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const iovecs=Ciovec.read_bytes_array(buffer,iovs_ptr,iovs_len);let nwritten=0;for(const iovec of iovecs){const data=buffer8.slice(iovec.buf,iovec.buf+iovec.buf_len);const{ret,nwritten:nwritten_part}=self.fds[fd].fd_pwrite(data,offset);if(ret!=ERRNO_SUCCESS){buffer.setUint32(nwritten_ptr,nwritten,true);return ret}nwritten+=nwritten_part;offset+=BigInt(nwritten_part);if(nwritten_part!=data.byteLength){break}}buffer.setUint32(nwritten_ptr,nwritten,true);return ERRNO_SUCCESS}else {return ERRNO_BADF}},fd_read(fd,iovs_ptr,iovs_len,nread_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const iovecs=Iovec.read_bytes_array(buffer,iovs_ptr,iovs_len);let nread=0;for(const iovec of iovecs){const{ret,data}=self.fds[fd].fd_read(iovec.buf_len);if(ret!=ERRNO_SUCCESS){buffer.setUint32(nread_ptr,nread,true);return ret}buffer8.set(data,iovec.buf);nread+=data.length;if(data.length!=iovec.buf_len){break}}buffer.setUint32(nread_ptr,nread,true);return ERRNO_SUCCESS}else {return ERRNO_BADF}},fd_readdir(fd,buf,buf_len,cookie,bufused_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){let bufused=0;while(true){const{ret,dirent}=self.fds[fd].fd_readdir_single(cookie);if(ret!=0){buffer.setUint32(bufused_ptr,bufused,true);return ret}if(dirent==null){break}if(buf_len-bufused<dirent.head_length()){bufused=buf_len;break}const head_bytes=new ArrayBuffer(dirent.head_length());dirent.write_head_bytes(new DataView(head_bytes),0);buffer8.set(new Uint8Array(head_bytes).slice(0,Math.min(head_bytes.byteLength,buf_len-bufused)),buf);buf+=dirent.head_length();bufused+=dirent.head_length();if(buf_len-bufused<dirent.name_length()){bufused=buf_len;break}dirent.write_name_bytes(buffer8,buf,buf_len-bufused);buf+=dirent.name_length();bufused+=dirent.name_length();cookie=dirent.d_next;}buffer.setUint32(bufused_ptr,bufused,true);return 0}else {return ERRNO_BADF}},fd_renumber(fd,to){if(self.fds[fd]!=undefined&&self.fds[to]!=undefined){const ret=self.fds[to].fd_close();if(ret!=0){return ret}self.fds[to]=self.fds[fd];self.fds[fd]=undefined;return 0}else {return ERRNO_BADF}},fd_seek(fd,offset,whence,offset_out_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const{ret,offset:offset_out}=self.fds[fd].fd_seek(offset,whence);buffer.setBigInt64(offset_out_ptr,offset_out,true);return ret}else {return ERRNO_BADF}},fd_sync(fd){if(self.fds[fd]!=undefined){return self.fds[fd].fd_sync()}else {return ERRNO_BADF}},fd_tell(fd,offset_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const{ret,offset}=self.fds[fd].fd_tell();buffer.setBigUint64(offset_ptr,offset,true);return ret}else {return ERRNO_BADF}},fd_write(fd,iovs_ptr,iovs_len,nwritten_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const iovecs=Ciovec.read_bytes_array(buffer,iovs_ptr,iovs_len);let nwritten=0;for(const iovec of iovecs){const data=buffer8.slice(iovec.buf,iovec.buf+iovec.buf_len);const{ret,nwritten:nwritten_part}=self.fds[fd].fd_write(data);if(ret!=ERRNO_SUCCESS){buffer.setUint32(nwritten_ptr,nwritten,true);return ret}nwritten+=nwritten_part;if(nwritten_part!=data.byteLength){break}}buffer.setUint32(nwritten_ptr,nwritten,true);return ERRNO_SUCCESS}else {return ERRNO_BADF}},path_create_directory(fd,path_ptr,path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));return self.fds[fd].path_create_directory(path)}else {return ERRNO_BADF}},path_filestat_get(fd,flags,path_ptr,path_len,filestat_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));const{ret,filestat}=self.fds[fd].path_filestat_get(flags,path);if(filestat!=null){filestat.write_bytes(buffer,filestat_ptr);}return ret}else {return ERRNO_BADF}},path_filestat_set_times(fd,flags,path_ptr,path_len,atim,mtim,fst_flags){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));return self.fds[fd].path_filestat_set_times(flags,path,atim,mtim,fst_flags)}else {return ERRNO_BADF}},path_link(old_fd,old_flags,old_path_ptr,old_path_len,new_fd,new_path_ptr,new_path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[old_fd]!=undefined&&self.fds[new_fd]!=undefined){const old_path=new TextDecoder("utf-8").decode(buffer8.slice(old_path_ptr,old_path_ptr+old_path_len));const new_path=new TextDecoder("utf-8").decode(buffer8.slice(new_path_ptr,new_path_ptr+new_path_len));const{ret,inode_obj}=self.fds[old_fd].path_lookup(old_path,old_flags);if(inode_obj==null){return ret}return self.fds[new_fd].path_link(new_path,inode_obj,false)}else {return ERRNO_BADF}},path_open(fd,dirflags,path_ptr,path_len,oflags,fs_rights_base,fs_rights_inheriting,fd_flags,opened_fd_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));debug.log(path);const{ret,fd_obj}=self.fds[fd].path_open(dirflags,path,oflags,fs_rights_base,fs_rights_inheriting,fd_flags);if(ret!=0){return ret}self.fds.push(fd_obj);const opened_fd=self.fds.length-1;buffer.setUint32(opened_fd_ptr,opened_fd,true);return 0}else {return ERRNO_BADF}},path_readlink(fd,path_ptr,path_len,buf_ptr,buf_len,nread_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));debug.log(path);const{ret,data}=self.fds[fd].path_readlink(path);if(data!=null){const data_buf=new TextEncoder().encode(data);if(data_buf.length>buf_len){buffer.setUint32(nread_ptr,0,true);return ERRNO_BADF}buffer8.set(data_buf,buf_ptr);buffer.setUint32(nread_ptr,data_buf.length,true);}return ret}else {return ERRNO_BADF}},path_remove_directory(fd,path_ptr,path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));return self.fds[fd].path_remove_directory(path)}else {return ERRNO_BADF}},path_rename(fd,old_path_ptr,old_path_len,new_fd,new_path_ptr,new_path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined&&self.fds[new_fd]!=undefined){const old_path=new TextDecoder("utf-8").decode(buffer8.slice(old_path_ptr,old_path_ptr+old_path_len));const new_path=new TextDecoder("utf-8").decode(buffer8.slice(new_path_ptr,new_path_ptr+new_path_len));let{ret,inode_obj}=self.fds[fd].path_unlink(old_path);if(inode_obj==null){return ret}ret=self.fds[new_fd].path_link(new_path,inode_obj,true);if(ret!=ERRNO_SUCCESS){if(self.fds[fd].path_link(old_path,inode_obj,true)!=ERRNO_SUCCESS){throw "path_link should always return success when relinking an inode back to the original place"}}return ret}else {return ERRNO_BADF}},path_symlink(old_path_ptr,old_path_len,fd,new_path_ptr,new_path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){new TextDecoder("utf-8").decode(buffer8.slice(old_path_ptr,old_path_ptr+old_path_len));new TextDecoder("utf-8").decode(buffer8.slice(new_path_ptr,new_path_ptr+new_path_len));return ERRNO_NOTSUP}else {return ERRNO_BADF}},path_unlink_file(fd,path_ptr,path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));return self.fds[fd].path_unlink_file(path)}else {return ERRNO_BADF}},poll_oneoff(in_,out,nsubscriptions){throw "async io not supported"},proc_exit(exit_code){throw new WASIProcExit(exit_code)},proc_raise(sig){throw "raised signal "+sig},sched_yield(){},random_get(buf,buf_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);for(let i=0;i<buf_len;i++){buffer8[buf+i]=Math.random()*256|0;}},sock_recv(fd,ri_data,ri_flags){throw "sockets not supported"},sock_send(fd,si_data,si_flags){throw "sockets not supported"},sock_shutdown(fd,how){throw "sockets not supported"},sock_accept(fd,flags){throw "sockets not supported"}};}};
57
+
58
+ class Fd{fd_allocate(offset,len){return ERRNO_NOTSUP}fd_close(){return 0}fd_fdstat_get(){return {ret:ERRNO_NOTSUP,fdstat:null}}fd_fdstat_set_flags(flags){return ERRNO_NOTSUP}fd_fdstat_set_rights(fs_rights_base,fs_rights_inheriting){return ERRNO_NOTSUP}fd_filestat_get(){return {ret:ERRNO_NOTSUP,filestat:null}}fd_filestat_set_size(size){return ERRNO_NOTSUP}fd_filestat_set_times(atim,mtim,fst_flags){return ERRNO_NOTSUP}fd_pread(size,offset){return {ret:ERRNO_NOTSUP,data:new Uint8Array}}fd_prestat_get(){return {ret:ERRNO_NOTSUP,prestat:null}}fd_pwrite(data,offset){return {ret:ERRNO_NOTSUP,nwritten:0}}fd_read(size){return {ret:ERRNO_NOTSUP,data:new Uint8Array}}fd_readdir_single(cookie){return {ret:ERRNO_NOTSUP,dirent:null}}fd_seek(offset,whence){return {ret:ERRNO_NOTSUP,offset:0n}}fd_sync(){return 0}fd_tell(){return {ret:ERRNO_NOTSUP,offset:0n}}fd_write(data){return {ret:ERRNO_NOTSUP,nwritten:0}}path_create_directory(path){return ERRNO_NOTSUP}path_filestat_get(flags,path){return {ret:ERRNO_NOTSUP,filestat:null}}path_filestat_set_times(flags,path,atim,mtim,fst_flags){return ERRNO_NOTSUP}path_link(path,inode,allow_dir){return ERRNO_NOTSUP}path_unlink(path){return {ret:ERRNO_NOTSUP,inode_obj:null}}path_lookup(path,dirflags){return {ret:ERRNO_NOTSUP,inode_obj:null}}path_open(dirflags,path,oflags,fs_rights_base,fs_rights_inheriting,fd_flags){return {ret:ERRNO_NOTDIR,fd_obj:null}}path_readlink(path){return {ret:ERRNO_NOTSUP,data:null}}path_remove_directory(path){return ERRNO_NOTSUP}path_rename(old_path,new_fd,new_path){return ERRNO_NOTSUP}path_unlink_file(path){return ERRNO_NOTSUP}}class Inode{}
59
+
60
+ class OpenFile extends Fd{fd_allocate(offset,len){if(this.file.size>offset+len);else {const new_data=new Uint8Array(Number(offset+len));new_data.set(this.file.data,0);this.file.data=new_data;}return ERRNO_SUCCESS}fd_fdstat_get(){return {ret:0,fdstat:new Fdstat(FILETYPE_REGULAR_FILE,0)}}fd_filestat_set_size(size){if(this.file.size>size){this.file.data=new Uint8Array(this.file.data.buffer.slice(0,Number(size)));}else {const new_data=new Uint8Array(Number(size));new_data.set(this.file.data,0);this.file.data=new_data;}return ERRNO_SUCCESS}fd_read(size){const slice=this.file.data.slice(Number(this.file_pos),Number(this.file_pos+BigInt(size)));this.file_pos+=BigInt(slice.length);return {ret:0,data:slice}}fd_pread(size,offset){const slice=this.file.data.slice(Number(offset),Number(offset+BigInt(size)));return {ret:0,data:slice}}fd_seek(offset,whence){let calculated_offset;switch(whence){case WHENCE_SET:calculated_offset=offset;break;case WHENCE_CUR:calculated_offset=this.file_pos+offset;break;case WHENCE_END:calculated_offset=BigInt(this.file.data.byteLength)+offset;break;default:return {ret:ERRNO_INVAL,offset:0n}}if(calculated_offset<0){return {ret:ERRNO_INVAL,offset:0n}}this.file_pos=calculated_offset;return {ret:0,offset:this.file_pos}}fd_tell(){return {ret:0,offset:this.file_pos}}fd_write(data){if(this.file.readonly)return {ret:ERRNO_BADF,nwritten:0};if(this.file_pos+BigInt(data.byteLength)>this.file.size){const old=this.file.data;this.file.data=new Uint8Array(Number(this.file_pos+BigInt(data.byteLength)));this.file.data.set(old);}this.file.data.set(data,Number(this.file_pos));this.file_pos+=BigInt(data.byteLength);return {ret:0,nwritten:data.byteLength}}fd_pwrite(data,offset){if(this.file.readonly)return {ret:ERRNO_BADF,nwritten:0};if(offset+BigInt(data.byteLength)>this.file.size){const old=this.file.data;this.file.data=new Uint8Array(Number(offset+BigInt(data.byteLength)));this.file.data.set(old);}this.file.data.set(data,Number(offset));return {ret:0,nwritten:data.byteLength}}fd_filestat_get(){return {ret:0,filestat:this.file.stat()}}constructor(file){super();this.file_pos=0n;this.file=file;}}class OpenDirectory extends Fd{fd_seek(offset,whence){return {ret:ERRNO_BADF,offset:0n}}fd_tell(){return {ret:ERRNO_BADF,offset:0n}}fd_allocate(offset,len){return ERRNO_BADF}fd_fdstat_get(){return {ret:0,fdstat:new Fdstat(FILETYPE_DIRECTORY,0)}}fd_readdir_single(cookie){if(debug.enabled){debug.log("readdir_single",cookie);debug.log(cookie,this.dir.contents.keys());}if(cookie==0n){return {ret:ERRNO_SUCCESS,dirent:new Dirent(1n,".",FILETYPE_DIRECTORY)}}else if(cookie==1n){return {ret:ERRNO_SUCCESS,dirent:new Dirent(2n,"..",FILETYPE_DIRECTORY)}}if(cookie>=BigInt(this.dir.contents.size)+2n){return {ret:0,dirent:null}}const[name,entry]=Array.from(this.dir.contents.entries())[Number(cookie-2n)];return {ret:0,dirent:new Dirent(cookie+1n,name,entry.stat().filetype)}}path_filestat_get(flags,path_str){const{ret:path_err,path}=Path.from(path_str);if(path==null){return {ret:path_err,filestat:null}}const{ret,entry}=this.dir.get_entry_for_path(path);if(entry==null){return {ret,filestat:null}}return {ret:0,filestat:entry.stat()}}path_lookup(path_str,dirflags){const{ret:path_ret,path}=Path.from(path_str);if(path==null){return {ret:path_ret,inode_obj:null}}const{ret,entry}=this.dir.get_entry_for_path(path);if(entry==null){return {ret,inode_obj:null}}return {ret:ERRNO_SUCCESS,inode_obj:entry}}path_open(dirflags,path_str,oflags,fs_rights_base,fs_rights_inheriting,fd_flags){const{ret:path_ret,path}=Path.from(path_str);if(path==null){return {ret:path_ret,fd_obj:null}}let{ret,entry}=this.dir.get_entry_for_path(path);if(entry==null){if(ret!=ERRNO_NOENT){return {ret,fd_obj:null}}if((oflags&OFLAGS_CREAT)==OFLAGS_CREAT){const{ret,entry:new_entry}=this.dir.create_entry_for_path(path_str,(oflags&OFLAGS_DIRECTORY)==OFLAGS_DIRECTORY);if(new_entry==null){return {ret,fd_obj:null}}entry=new_entry;}else {return {ret:ERRNO_NOENT,fd_obj:null}}}else if((oflags&OFLAGS_EXCL)==OFLAGS_EXCL){return {ret:ERRNO_EXIST,fd_obj:null}}if((oflags&OFLAGS_DIRECTORY)==OFLAGS_DIRECTORY&&entry.stat().filetype!==FILETYPE_DIRECTORY){return {ret:ERRNO_NOTDIR,fd_obj:null}}return entry.path_open(oflags,fs_rights_base,fd_flags)}path_create_directory(path){return this.path_open(0,path,OFLAGS_CREAT|OFLAGS_DIRECTORY,0n,0n,0).ret}path_link(path_str,inode,allow_dir){const{ret:path_ret,path}=Path.from(path_str);if(path==null){return path_ret}if(path.is_dir){return ERRNO_NOENT}const{ret:parent_ret,parent_entry,filename,entry}=this.dir.get_parent_dir_and_entry_for_path(path,true);if(parent_entry==null||filename==null){return parent_ret}if(entry!=null){const source_is_dir=inode.stat().filetype==FILETYPE_DIRECTORY;const target_is_dir=entry.stat().filetype==FILETYPE_DIRECTORY;if(source_is_dir&&target_is_dir){if(allow_dir&&entry instanceof Directory){if(entry.contents.size==0);else {return ERRNO_NOTEMPTY}}else {return ERRNO_EXIST}}else if(source_is_dir&&!target_is_dir){return ERRNO_NOTDIR}else if(!source_is_dir&&target_is_dir){return ERRNO_ISDIR}else if(inode.stat().filetype==FILETYPE_REGULAR_FILE&&entry.stat().filetype==FILETYPE_REGULAR_FILE);else {return ERRNO_EXIST}}if(!allow_dir&&inode.stat().filetype==FILETYPE_DIRECTORY){return ERRNO_PERM}parent_entry.contents.set(filename,inode);return ERRNO_SUCCESS}path_unlink(path_str){const{ret:path_ret,path}=Path.from(path_str);if(path==null){return {ret:path_ret,inode_obj:null}}const{ret:parent_ret,parent_entry,filename,entry}=this.dir.get_parent_dir_and_entry_for_path(path,true);if(parent_entry==null||filename==null){return {ret:parent_ret,inode_obj:null}}if(entry==null){return {ret:ERRNO_NOENT,inode_obj:null}}parent_entry.contents.delete(filename);return {ret:ERRNO_SUCCESS,inode_obj:entry}}path_unlink_file(path_str){const{ret:path_ret,path}=Path.from(path_str);if(path==null){return path_ret}const{ret:parent_ret,parent_entry,filename,entry}=this.dir.get_parent_dir_and_entry_for_path(path,false);if(parent_entry==null||filename==null||entry==null){return parent_ret}if(entry.stat().filetype===FILETYPE_DIRECTORY){return ERRNO_ISDIR}parent_entry.contents.delete(filename);return ERRNO_SUCCESS}path_remove_directory(path_str){const{ret:path_ret,path}=Path.from(path_str);if(path==null){return path_ret}const{ret:parent_ret,parent_entry,filename,entry}=this.dir.get_parent_dir_and_entry_for_path(path,false);if(parent_entry==null||filename==null||entry==null){return parent_ret}if(!(entry instanceof Directory)||entry.stat().filetype!==FILETYPE_DIRECTORY){return ERRNO_NOTDIR}if(entry.contents.size!==0){return ERRNO_NOTEMPTY}if(!parent_entry.contents.delete(filename)){return ERRNO_NOENT}return ERRNO_SUCCESS}fd_filestat_get(){return {ret:0,filestat:this.dir.stat()}}fd_filestat_set_size(size){return ERRNO_BADF}fd_read(size){return {ret:ERRNO_BADF,data:new Uint8Array}}fd_pread(size,offset){return {ret:ERRNO_BADF,data:new Uint8Array}}fd_write(data){return {ret:ERRNO_BADF,nwritten:0}}fd_pwrite(data,offset){return {ret:ERRNO_BADF,nwritten:0}}constructor(dir){super();this.dir=dir;}}class PreopenDirectory extends OpenDirectory{fd_prestat_get(){return {ret:0,prestat:Prestat.dir(this.prestat_name)}}constructor(name,contents){super(new Directory(contents));this.prestat_name=name;}}class File extends Inode{path_open(oflags,fs_rights_base,fd_flags){if(this.readonly&&(fs_rights_base&BigInt(RIGHTS_FD_WRITE))==BigInt(RIGHTS_FD_WRITE)){return {ret:ERRNO_PERM,fd_obj:null}}if((oflags&OFLAGS_TRUNC)==OFLAGS_TRUNC){if(this.readonly)return {ret:ERRNO_PERM,fd_obj:null};this.data=new Uint8Array([]);}const file=new OpenFile(this);if(fd_flags&FDFLAGS_APPEND)file.fd_seek(0n,WHENCE_END);return {ret:ERRNO_SUCCESS,fd_obj:file}}get size(){return BigInt(this.data.byteLength)}stat(){return new Filestat(FILETYPE_REGULAR_FILE,this.size)}constructor(data,options){super();this.data=new Uint8Array(data);this.readonly=!!options?.readonly;}}let Path=class Path{static from(path){const self=new Path;self.is_dir=path.endsWith("/");if(path.startsWith("/")){return {ret:ERRNO_NOTCAPABLE,path:null}}if(path.includes("\x00")){return {ret:ERRNO_INVAL,path:null}}for(const component of path.split("/")){if(component===""||component==="."){continue}if(component===".."){if(self.parts.pop()==undefined){return {ret:ERRNO_NOTCAPABLE,path:null}}continue}self.parts.push(component);}return {ret:ERRNO_SUCCESS,path:self}}to_path_string(){let s=this.parts.join("/");if(this.is_dir){s+="/";}return s}constructor(){this.parts=[];this.is_dir=false;}};class Directory extends Inode{path_open(oflags,fs_rights_base,fd_flags){return {ret:ERRNO_SUCCESS,fd_obj:new OpenDirectory(this)}}stat(){return new Filestat(FILETYPE_DIRECTORY,0n)}get_entry_for_path(path){let entry=this;for(const component of path.parts){if(!(entry instanceof Directory)){return {ret:ERRNO_NOTDIR,entry:null}}const child=entry.contents.get(component);if(child!==undefined){entry=child;}else {debug.log(component);return {ret:ERRNO_NOENT,entry:null}}}if(path.is_dir){if(entry.stat().filetype!=FILETYPE_DIRECTORY){return {ret:ERRNO_NOTDIR,entry:null}}}return {ret:ERRNO_SUCCESS,entry}}get_parent_dir_and_entry_for_path(path,allow_undefined){const filename=path.parts.pop();if(filename===undefined){return {ret:ERRNO_INVAL,parent_entry:null,filename:null,entry:null}}const{ret:entry_ret,entry:parent_entry}=this.get_entry_for_path(path);if(parent_entry==null){return {ret:entry_ret,parent_entry:null,filename:null,entry:null}}if(!(parent_entry instanceof Directory)){return {ret:ERRNO_NOTDIR,parent_entry:null,filename:null,entry:null}}const entry=parent_entry.contents.get(filename);if(entry===undefined){if(!allow_undefined){return {ret:ERRNO_NOENT,parent_entry:null,filename:null,entry:null}}else {return {ret:ERRNO_SUCCESS,parent_entry,filename,entry:null}}}if(path.is_dir){if(entry.stat().filetype!=FILETYPE_DIRECTORY){return {ret:ERRNO_NOTDIR,parent_entry:null,filename:null,entry:null}}}return {ret:ERRNO_SUCCESS,parent_entry,filename,entry}}create_entry_for_path(path_str,is_dir){const{ret:path_ret,path}=Path.from(path_str);if(path==null){return {ret:path_ret,entry:null}}let{ret:parent_ret,parent_entry,filename,entry}=this.get_parent_dir_and_entry_for_path(path,true);if(parent_entry==null||filename==null){return {ret:parent_ret,entry:null}}if(entry!=null){return {ret:ERRNO_EXIST,entry:null}}debug.log("create",path);let new_child;if(!is_dir){new_child=new File(new ArrayBuffer(0));}else {new_child=new Directory(new Map);}parent_entry.contents.set(filename,new_child);entry=new_child;return {ret:ERRNO_SUCCESS,entry}}constructor(contents){super();if(contents instanceof Array){this.contents=new Map(contents);}else {this.contents=contents;}}}
57
61
 
58
62
  /**
59
63
  * Create a console printer that can be used as an overlay of WASI imports.
@@ -551,13 +555,13 @@ Please replace your \`require('ruby-head-wasm-wasi/dist/browser.script.umd');\`
551
555
  data_view(memory).setInt32(arg1 + 4, len0, true);
552
556
  data_view(memory).setInt32(arg1 + 0, ptr0, true);
553
557
  };
554
- imports["rb-js-abi-host"]["js-value-to-integer: func(value: handle<js-abi-value>) -> variant { f64(float64), bignum(string) }"] = function(arg0, arg1) {
558
+ imports["rb-js-abi-host"]["js-value-to-integer: func(value: handle<js-abi-value>) -> variant { as-float(float64), bignum(string) }"] = function(arg0, arg1) {
555
559
  const memory = get_export("memory");
556
560
  const realloc = get_export("cabi_realloc");
557
561
  const ret0 = obj.jsValueToInteger(resources0.get(arg0));
558
562
  const variant1 = ret0;
559
563
  switch (variant1.tag) {
560
- case "f64": {
564
+ case "as-float": {
561
565
  const e = variant1.val;
562
566
  data_view(memory).setInt8(arg1 + 0, 0, true);
563
567
  data_view(memory).setFloat64(arg1 + 8, +e, true);
@@ -753,6 +757,72 @@ Please replace your \`require('ruby-head-wasm-wasi/dist/browser.script.umd');\`
753
757
  };
754
758
  }
755
759
 
760
+ class LegacyBinding extends RbAbiGuest {
761
+ async setInstance(instance) {
762
+ await this.instantiate(instance);
763
+ }
764
+ }
765
+ class ComponentBinding {
766
+ constructor() { }
767
+ setUnderlying(underlying) {
768
+ this.underlying = underlying;
769
+ }
770
+ rubyShowVersion() {
771
+ this.underlying.rubyShowVersion();
772
+ }
773
+ rubyInit() {
774
+ this.underlying.rubyInit();
775
+ }
776
+ rubySysinit(args) {
777
+ this.underlying.rubySysinit(args);
778
+ }
779
+ rubyOptions(args) {
780
+ this.underlying.rubyOptions(args);
781
+ }
782
+ rubyScript(name) {
783
+ this.underlying.rubyScript(name);
784
+ }
785
+ rubyInitLoadpath() {
786
+ this.underlying.rubyInitLoadpath();
787
+ }
788
+ rbEvalStringProtect(str) {
789
+ return this.underlying.rbEvalStringProtect(str);
790
+ }
791
+ rbFuncallvProtect(recv, mid, args) {
792
+ return this.underlying.rbFuncallvProtect(recv, mid, args);
793
+ }
794
+ rbIntern(name) {
795
+ return this.underlying.rbIntern(name);
796
+ }
797
+ rbErrinfo() {
798
+ return this.underlying.rbErrinfo();
799
+ }
800
+ rbClearErrinfo() {
801
+ return this.underlying.rbClearErrinfo();
802
+ }
803
+ rstringPtr(value) {
804
+ return this.underlying.rstringPtr(value);
805
+ }
806
+ rbVmBugreport() {
807
+ this.underlying.rbVmBugreport();
808
+ }
809
+ rbGcEnable() {
810
+ return this.underlying.rbGcEnable();
811
+ }
812
+ rbGcDisable() {
813
+ return this.underlying.rbGcDisable();
814
+ }
815
+ rbSetShouldProhibitRewind(newValue) {
816
+ return this.underlying.rbSetShouldProhibitRewind(newValue);
817
+ }
818
+ async setInstance(instance) {
819
+ // No-op
820
+ }
821
+ addToImports(imports) {
822
+ // No-op
823
+ }
824
+ }
825
+
756
826
  /**
757
827
  * A Ruby VM instance
758
828
  *
@@ -773,7 +843,7 @@ Please replace your \`require('ruby-head-wasm-wasi/dist/browser.script.umd');\`
773
843
  *
774
844
  */
775
845
  class RubyVM {
776
- constructor() {
846
+ constructor(binding) {
777
847
  this.instance = null;
778
848
  this.interfaceState = {
779
849
  hasJSFrameAfterRbFrame: false,
@@ -782,6 +852,7 @@ Please replace your \`require('ruby-head-wasm-wasi/dist/browser.script.umd');\`
782
852
  // if the call stack has sandwitched JS frames like JS -> Ruby -> JS -> Ruby.
783
853
  const proxyExports = (exports) => {
784
854
  const excludedMethods = [
855
+ "setInstance",
785
856
  "addToImports",
786
857
  "instantiate",
787
858
  "rbSetShouldProhibitRewind",
@@ -816,10 +887,34 @@ Please replace your \`require('ruby-head-wasm-wasi/dist/browser.script.umd');\`
816
887
  }
817
888
  return exports;
818
889
  };
819
- this.guest = proxyExports(new RbAbiGuest());
890
+ this.guest = proxyExports(binding !== null && binding !== void 0 ? binding : new LegacyBinding());
820
891
  this.transport = new JsValueTransport();
821
892
  this.exceptionFormatter = new RbExceptionFormatter();
822
893
  }
894
+ static async _instantiate(initComponent, options) {
895
+ const binding = new ComponentBinding();
896
+ const vm = new RubyVM(binding);
897
+ class JsAbiValue {
898
+ constructor(underlying) {
899
+ this.underlying = underlying;
900
+ }
901
+ }
902
+ const imports = vm.getImports((from) => new JsAbiValue(from), (to) => to.underlying);
903
+ const component = await initComponent(Object.assign(Object.assign({}, imports), { throwProhibitRewindException: (message) => {
904
+ vm.throwProhibitRewindException(message);
905
+ }, procToJsFunction: () => {
906
+ const rbValue = new RbValue(component.exportRbValueToJs(), vm, vm.privateObject());
907
+ return new JsAbiValue((...args) => {
908
+ return rbValue.call("call", ...args.map((arg) => vm.wrap(arg))).toJS();
909
+ });
910
+ }, rbObjectToJsRbValue: () => {
911
+ const rbValue = new RbValue(component.exportRbValueToJs(), vm, vm.privateObject());
912
+ return new JsAbiValue(rbValue);
913
+ }, JsAbiValue: JsAbiValue }));
914
+ binding.setUnderlying(component);
915
+ vm.initialize(options.args);
916
+ return vm;
917
+ }
823
918
  /**
824
919
  * Initialize the Ruby VM with the given command line arguments
825
920
  * @param args The command line arguments to pass to Ruby. Must be
@@ -843,7 +938,7 @@ Please replace your \`require('ruby-head-wasm-wasi/dist/browser.script.umd');\`
843
938
  */
844
939
  async setInstance(instance) {
845
940
  this.instance = instance;
846
- await this.guest.instantiate(instance);
941
+ await this.guest.setInstance(instance);
847
942
  }
848
943
  /**
849
944
  * Add intrinsic import entries, which is necessary to interact JavaScript
@@ -852,43 +947,36 @@ Please replace your \`require('ruby-head-wasm-wasi/dist/browser.script.umd');\`
852
947
  */
853
948
  addToImports(imports) {
854
949
  this.guest.addToImports(imports);
855
- function wrapTry(f) {
856
- return (...args) => {
857
- try {
858
- return { tag: "success", val: f(...args) };
859
- }
860
- catch (e) {
861
- if (e instanceof RbFatalError) {
862
- // RbFatalError should not be caught by Ruby because it Ruby VM
863
- // can be already in an inconsistent state.
864
- throw e;
865
- }
866
- return { tag: "failure", val: e };
867
- }
868
- };
869
- }
870
950
  imports["rb-js-abi-host"] = {
871
951
  rb_wasm_throw_prohibit_rewind_exception: (messagePtr, messageLen) => {
872
952
  const memory = this.instance.exports.memory;
873
953
  const str = new TextDecoder().decode(new Uint8Array(memory.buffer, messagePtr, messageLen));
874
- let message = "Ruby APIs that may rewind the VM stack are prohibited under nested VM operation " +
875
- `(${str})\n` +
876
- "Nested VM operation means that the call stack has sandwitched JS frames like JS -> Ruby -> JS -> Ruby " +
877
- "caused by something like `window.rubyVM.eval(\"JS.global[:rubyVM].eval('Fiber.yield')\")`\n" +
878
- "\n" +
879
- "Please check your call stack and make sure that you are **not** doing any of the following inside the nested Ruby frame:\n" +
880
- " 1. Switching fibers (e.g. Fiber#resume, Fiber.yield, and Fiber#transfer)\n" +
881
- " Note that `evalAsync` JS API switches fibers internally\n" +
882
- " 2. Raising uncaught exceptions\n" +
883
- " Please catch all exceptions inside the nested operation\n" +
884
- " 3. Calling Continuation APIs\n";
885
- const error = new RbValue(this.guest.rbErrinfo(), this, this.privateObject());
886
- if (error.call("nil?").toString() === "false") {
887
- message += "\n" + this.exceptionFormatter.format(error, this, this.privateObject());
888
- }
889
- throw new RbFatalError(message);
954
+ this.throwProhibitRewindException(str);
890
955
  },
891
956
  };
957
+ addRbJsAbiHostToImports(imports, this.getImports((value) => value, (value) => value), (name) => {
958
+ return this.instance.exports[name];
959
+ });
960
+ }
961
+ throwProhibitRewindException(str) {
962
+ let message = "Ruby APIs that may rewind the VM stack are prohibited under nested VM operation " +
963
+ `(${str})\n` +
964
+ "Nested VM operation means that the call stack has sandwitched JS frames like JS -> Ruby -> JS -> Ruby " +
965
+ "caused by something like `window.rubyVM.eval(\"JS.global[:rubyVM].eval('Fiber.yield')\")`\n" +
966
+ "\n" +
967
+ "Please check your call stack and make sure that you are **not** doing any of the following inside the nested Ruby frame:\n" +
968
+ " 1. Switching fibers (e.g. Fiber#resume, Fiber.yield, and Fiber#transfer)\n" +
969
+ " Note that `evalAsync` JS API switches fibers internally\n" +
970
+ " 2. Raising uncaught exceptions\n" +
971
+ " Please catch all exceptions inside the nested operation\n" +
972
+ " 3. Calling Continuation APIs\n";
973
+ const error = new RbValue(this.guest.rbErrinfo(), this, this.privateObject());
974
+ if (error.call("nil?").toString() === "false") {
975
+ message += "\n" + this.exceptionFormatter.format(error, this, this.privateObject());
976
+ }
977
+ throw new RbFatalError(message);
978
+ }
979
+ getImports(toJSAbiValue, fromJSAbiValue) {
892
980
  // NOTE: The GC may collect objects that are still referenced by Wasm
893
981
  // locals because Asyncify cannot scan the Wasm stack above the JS frame.
894
982
  // So we need to keep track whether the JS frame is sandwitched by Ruby
@@ -907,9 +995,24 @@ Please replace your \`require('ruby-head-wasm-wasi/dist/browser.script.umd');\`
907
995
  }
908
996
  return imports;
909
997
  };
910
- addRbJsAbiHostToImports(imports, proxyImports({
998
+ function wrapTry(f) {
999
+ return (...args) => {
1000
+ try {
1001
+ return { tag: "success", val: f(...args) };
1002
+ }
1003
+ catch (e) {
1004
+ if (e instanceof RbFatalError) {
1005
+ // RbFatalError should not be caught by Ruby because it Ruby VM
1006
+ // can be already in an inconsistent state.
1007
+ throw e;
1008
+ }
1009
+ return { tag: "failure", val: toJSAbiValue(e) };
1010
+ }
1011
+ };
1012
+ }
1013
+ return proxyImports({
911
1014
  evalJs: wrapTry((code) => {
912
- return Function(code)();
1015
+ return toJSAbiValue(Function(code)());
913
1016
  }),
914
1017
  isJs: (value) => {
915
1018
  // Just for compatibility with the old JS API
@@ -917,45 +1020,47 @@ Please replace your \`require('ruby-head-wasm-wasi/dist/browser.script.umd');\`
917
1020
  },
918
1021
  globalThis: () => {
919
1022
  if (typeof globalThis !== "undefined") {
920
- return globalThis;
1023
+ return toJSAbiValue(globalThis);
921
1024
  }
922
1025
  else if (typeof global !== "undefined") {
923
- return global;
1026
+ return toJSAbiValue(global);
924
1027
  }
925
1028
  else if (typeof window !== "undefined") {
926
- return window;
1029
+ return toJSAbiValue(window);
927
1030
  }
928
1031
  throw new Error("unable to locate global object");
929
1032
  },
930
1033
  intToJsNumber: (value) => {
931
- return value;
1034
+ return toJSAbiValue(value);
932
1035
  },
933
1036
  floatToJsNumber: (value) => {
934
- return value;
1037
+ return toJSAbiValue(value);
935
1038
  },
936
1039
  stringToJsString: (value) => {
937
- return value;
1040
+ return toJSAbiValue(value);
938
1041
  },
939
1042
  boolToJsBool: (value) => {
940
- return value;
1043
+ return toJSAbiValue(value);
941
1044
  },
942
1045
  procToJsFunction: (rawRbAbiValue) => {
943
1046
  const rbValue = this.rbValueOfPointer(rawRbAbiValue);
944
- return (...args) => {
1047
+ return toJSAbiValue((...args) => {
945
1048
  return rbValue.call("call", ...args.map((arg) => this.wrap(arg))).toJS();
946
- };
1049
+ });
947
1050
  },
948
1051
  rbObjectToJsRbValue: (rawRbAbiValue) => {
949
- return this.rbValueOfPointer(rawRbAbiValue);
1052
+ return toJSAbiValue(this.rbValueOfPointer(rawRbAbiValue));
950
1053
  },
951
1054
  jsValueToString: (value) => {
1055
+ value = fromJSAbiValue(value);
952
1056
  // According to the [spec](https://tc39.es/ecma262/multipage/text-processing.html#sec-string-constructor-string-value)
953
1057
  // `String(value)` always returns a string.
954
1058
  return String(value);
955
1059
  },
956
1060
  jsValueToInteger(value) {
1061
+ value = fromJSAbiValue(value);
957
1062
  if (typeof value === "number") {
958
- return { tag: "f64", val: value };
1063
+ return { tag: "as-float", val: value };
959
1064
  }
960
1065
  else if (typeof value === "bigint") {
961
1066
  return { tag: "bignum", val: BigInt(value).toString(10) + "\0" };
@@ -964,38 +1069,40 @@ Please replace your \`require('ruby-head-wasm-wasi/dist/browser.script.umd');\`
964
1069
  return { tag: "bignum", val: value + "\0" };
965
1070
  }
966
1071
  else if (typeof value === "undefined") {
967
- return { tag: "f64", val: 0 };
1072
+ return { tag: "as-float", val: 0 };
968
1073
  }
969
1074
  else {
970
- return { tag: "f64", val: Number(value) };
1075
+ return { tag: "as-float", val: Number(value) };
971
1076
  }
972
1077
  },
973
1078
  exportJsValueToHost: (value) => {
974
1079
  // See `JsValueExporter` for the reason why we need to do this
975
- this.transport.takeJsValue(value);
1080
+ this.transport.takeJsValue(fromJSAbiValue(value));
976
1081
  },
977
1082
  importJsValueFromHost: () => {
978
- return this.transport.consumeJsValue();
1083
+ return toJSAbiValue(this.transport.consumeJsValue());
979
1084
  },
980
1085
  instanceOf: (value, klass) => {
1086
+ klass = fromJSAbiValue(klass);
981
1087
  if (typeof klass === "function") {
982
- return value instanceof klass;
1088
+ return fromJSAbiValue(value) instanceof klass;
983
1089
  }
984
1090
  else {
985
1091
  return false;
986
1092
  }
987
1093
  },
988
1094
  jsValueTypeof(value) {
989
- return typeof value;
1095
+ return typeof fromJSAbiValue(value);
990
1096
  },
991
1097
  jsValueEqual(lhs, rhs) {
992
- return lhs == rhs;
1098
+ return fromJSAbiValue(lhs) == fromJSAbiValue(rhs);
993
1099
  },
994
1100
  jsValueStrictlyEqual(lhs, rhs) {
995
- return lhs === rhs;
1101
+ return fromJSAbiValue(lhs) === fromJSAbiValue(rhs);
996
1102
  },
997
1103
  reflectApply: wrapTry((target, thisArgument, args) => {
998
- return Reflect.apply(target, thisArgument, args);
1104
+ const jsArgs = args.map((arg) => fromJSAbiValue(arg));
1105
+ return toJSAbiValue(Reflect.apply(fromJSAbiValue(target), fromJSAbiValue(thisArgument), jsArgs));
999
1106
  }),
1000
1107
  reflectConstruct: function (target, args) {
1001
1108
  throw new Error("Function not implemented.");
@@ -1004,7 +1111,7 @@ Please replace your \`require('ruby-head-wasm-wasi/dist/browser.script.umd');\`
1004
1111
  throw new Error("Function not implemented.");
1005
1112
  },
1006
1113
  reflectGet: wrapTry((target, propertyKey) => {
1007
- return target[propertyKey];
1114
+ return toJSAbiValue(fromJSAbiValue(target)[propertyKey]);
1008
1115
  }),
1009
1116
  reflectGetOwnPropertyDescriptor: function (target, propertyKey) {
1010
1117
  throw new Error("Function not implemented.");
@@ -1025,13 +1132,11 @@ Please replace your \`require('ruby-head-wasm-wasi/dist/browser.script.umd');\`
1025
1132
  throw new Error("Function not implemented.");
1026
1133
  },
1027
1134
  reflectSet: wrapTry((target, propertyKey, value) => {
1028
- return Reflect.set(target, propertyKey, value);
1135
+ return toJSAbiValue(Reflect.set(fromJSAbiValue(target), propertyKey, fromJSAbiValue(value)));
1029
1136
  }),
1030
1137
  reflectSetPrototypeOf: function (target, prototype) {
1031
1138
  throw new Error("Function not implemented.");
1032
1139
  },
1033
- }), (name) => {
1034
- return this.instance.exports[name];
1035
1140
  });
1036
1141
  }
1037
1142
  /**
@@ -1364,7 +1469,12 @@ Please replace your \`require('ruby-head-wasm-wasi/dist/browser.script.umd');\`
1364
1469
  }
1365
1470
  // All JS exceptions triggered by Ruby code are translated to Ruby exceptions,
1366
1471
  // so non-RbError exceptions are unexpected.
1367
- vm.guest.rbVmBugreport();
1472
+ try {
1473
+ vm.guest.rbVmBugreport();
1474
+ }
1475
+ catch (e) {
1476
+ console.error("Tried to report internal Ruby VM state but failed: ", e);
1477
+ }
1368
1478
  if (e instanceof WebAssembly.RuntimeError && e.message === "unreachable") {
1369
1479
  const error = new RbError(`Something went wrong in Ruby VM: ${e}`);
1370
1480
  error.stack = e.stack;
@@ -1430,7 +1540,12 @@ Please replace your \`require('ruby-head-wasm-wasi/dist/browser.script.umd');\`
1430
1540
  var _a, _b;
1431
1541
  const args = [];
1432
1542
  const env = Object.entries((_a = options.env) !== null && _a !== void 0 ? _a : {}).map(([k, v]) => `${k}=${v}`);
1433
- const fds = [];
1543
+ const fds = [
1544
+ new OpenFile(new File([])),
1545
+ new OpenFile(new File([])),
1546
+ new OpenFile(new File([])),
1547
+ new PreopenDirectory("/", new Map()),
1548
+ ];
1434
1549
  const wasi = new WASI(args, env, fds, { debug: false });
1435
1550
  const vm = new RubyVM();
1436
1551
  const imports = {