@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
@@ -4,11 +4,15 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["ruby-wasm-wasi"] = {}));
5
5
  })(this, (function (exports) { 'use strict';
6
6
 
7
- 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}}
7
+ 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);}}
8
8
 
9
9
  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);
10
10
 
11
- 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"}};}};
11
+ 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"}};}};
12
+
13
+ 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{}
14
+
15
+ 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;}}}
12
16
 
13
17
  /**
14
18
  * Create a console printer that can be used as an overlay of WASI imports.
@@ -506,13 +510,13 @@
506
510
  data_view(memory).setInt32(arg1 + 4, len0, true);
507
511
  data_view(memory).setInt32(arg1 + 0, ptr0, true);
508
512
  };
509
- imports["rb-js-abi-host"]["js-value-to-integer: func(value: handle<js-abi-value>) -> variant { f64(float64), bignum(string) }"] = function(arg0, arg1) {
513
+ imports["rb-js-abi-host"]["js-value-to-integer: func(value: handle<js-abi-value>) -> variant { as-float(float64), bignum(string) }"] = function(arg0, arg1) {
510
514
  const memory = get_export("memory");
511
515
  const realloc = get_export("cabi_realloc");
512
516
  const ret0 = obj.jsValueToInteger(resources0.get(arg0));
513
517
  const variant1 = ret0;
514
518
  switch (variant1.tag) {
515
- case "f64": {
519
+ case "as-float": {
516
520
  const e = variant1.val;
517
521
  data_view(memory).setInt8(arg1 + 0, 0, true);
518
522
  data_view(memory).setFloat64(arg1 + 8, +e, true);
@@ -708,6 +712,72 @@
708
712
  };
709
713
  }
710
714
 
715
+ class LegacyBinding extends RbAbiGuest {
716
+ async setInstance(instance) {
717
+ await this.instantiate(instance);
718
+ }
719
+ }
720
+ class ComponentBinding {
721
+ constructor() { }
722
+ setUnderlying(underlying) {
723
+ this.underlying = underlying;
724
+ }
725
+ rubyShowVersion() {
726
+ this.underlying.rubyShowVersion();
727
+ }
728
+ rubyInit() {
729
+ this.underlying.rubyInit();
730
+ }
731
+ rubySysinit(args) {
732
+ this.underlying.rubySysinit(args);
733
+ }
734
+ rubyOptions(args) {
735
+ this.underlying.rubyOptions(args);
736
+ }
737
+ rubyScript(name) {
738
+ this.underlying.rubyScript(name);
739
+ }
740
+ rubyInitLoadpath() {
741
+ this.underlying.rubyInitLoadpath();
742
+ }
743
+ rbEvalStringProtect(str) {
744
+ return this.underlying.rbEvalStringProtect(str);
745
+ }
746
+ rbFuncallvProtect(recv, mid, args) {
747
+ return this.underlying.rbFuncallvProtect(recv, mid, args);
748
+ }
749
+ rbIntern(name) {
750
+ return this.underlying.rbIntern(name);
751
+ }
752
+ rbErrinfo() {
753
+ return this.underlying.rbErrinfo();
754
+ }
755
+ rbClearErrinfo() {
756
+ return this.underlying.rbClearErrinfo();
757
+ }
758
+ rstringPtr(value) {
759
+ return this.underlying.rstringPtr(value);
760
+ }
761
+ rbVmBugreport() {
762
+ this.underlying.rbVmBugreport();
763
+ }
764
+ rbGcEnable() {
765
+ return this.underlying.rbGcEnable();
766
+ }
767
+ rbGcDisable() {
768
+ return this.underlying.rbGcDisable();
769
+ }
770
+ rbSetShouldProhibitRewind(newValue) {
771
+ return this.underlying.rbSetShouldProhibitRewind(newValue);
772
+ }
773
+ async setInstance(instance) {
774
+ // No-op
775
+ }
776
+ addToImports(imports) {
777
+ // No-op
778
+ }
779
+ }
780
+
711
781
  /**
712
782
  * A Ruby VM instance
713
783
  *
@@ -728,7 +798,7 @@
728
798
  *
729
799
  */
730
800
  class RubyVM {
731
- constructor() {
801
+ constructor(binding) {
732
802
  this.instance = null;
733
803
  this.interfaceState = {
734
804
  hasJSFrameAfterRbFrame: false,
@@ -737,6 +807,7 @@
737
807
  // if the call stack has sandwitched JS frames like JS -> Ruby -> JS -> Ruby.
738
808
  const proxyExports = (exports) => {
739
809
  const excludedMethods = [
810
+ "setInstance",
740
811
  "addToImports",
741
812
  "instantiate",
742
813
  "rbSetShouldProhibitRewind",
@@ -771,10 +842,34 @@
771
842
  }
772
843
  return exports;
773
844
  };
774
- this.guest = proxyExports(new RbAbiGuest());
845
+ this.guest = proxyExports(binding !== null && binding !== void 0 ? binding : new LegacyBinding());
775
846
  this.transport = new JsValueTransport();
776
847
  this.exceptionFormatter = new RbExceptionFormatter();
777
848
  }
849
+ static async _instantiate(initComponent, options) {
850
+ const binding = new ComponentBinding();
851
+ const vm = new RubyVM(binding);
852
+ class JsAbiValue {
853
+ constructor(underlying) {
854
+ this.underlying = underlying;
855
+ }
856
+ }
857
+ const imports = vm.getImports((from) => new JsAbiValue(from), (to) => to.underlying);
858
+ const component = await initComponent(Object.assign(Object.assign({}, imports), { throwProhibitRewindException: (message) => {
859
+ vm.throwProhibitRewindException(message);
860
+ }, procToJsFunction: () => {
861
+ const rbValue = new RbValue(component.exportRbValueToJs(), vm, vm.privateObject());
862
+ return new JsAbiValue((...args) => {
863
+ return rbValue.call("call", ...args.map((arg) => vm.wrap(arg))).toJS();
864
+ });
865
+ }, rbObjectToJsRbValue: () => {
866
+ const rbValue = new RbValue(component.exportRbValueToJs(), vm, vm.privateObject());
867
+ return new JsAbiValue(rbValue);
868
+ }, JsAbiValue: JsAbiValue }));
869
+ binding.setUnderlying(component);
870
+ vm.initialize(options.args);
871
+ return vm;
872
+ }
778
873
  /**
779
874
  * Initialize the Ruby VM with the given command line arguments
780
875
  * @param args The command line arguments to pass to Ruby. Must be
@@ -798,7 +893,7 @@
798
893
  */
799
894
  async setInstance(instance) {
800
895
  this.instance = instance;
801
- await this.guest.instantiate(instance);
896
+ await this.guest.setInstance(instance);
802
897
  }
803
898
  /**
804
899
  * Add intrinsic import entries, which is necessary to interact JavaScript
@@ -807,43 +902,36 @@
807
902
  */
808
903
  addToImports(imports) {
809
904
  this.guest.addToImports(imports);
810
- function wrapTry(f) {
811
- return (...args) => {
812
- try {
813
- return { tag: "success", val: f(...args) };
814
- }
815
- catch (e) {
816
- if (e instanceof RbFatalError) {
817
- // RbFatalError should not be caught by Ruby because it Ruby VM
818
- // can be already in an inconsistent state.
819
- throw e;
820
- }
821
- return { tag: "failure", val: e };
822
- }
823
- };
824
- }
825
905
  imports["rb-js-abi-host"] = {
826
906
  rb_wasm_throw_prohibit_rewind_exception: (messagePtr, messageLen) => {
827
907
  const memory = this.instance.exports.memory;
828
908
  const str = new TextDecoder().decode(new Uint8Array(memory.buffer, messagePtr, messageLen));
829
- let message = "Ruby APIs that may rewind the VM stack are prohibited under nested VM operation " +
830
- `(${str})\n` +
831
- "Nested VM operation means that the call stack has sandwitched JS frames like JS -> Ruby -> JS -> Ruby " +
832
- "caused by something like `window.rubyVM.eval(\"JS.global[:rubyVM].eval('Fiber.yield')\")`\n" +
833
- "\n" +
834
- "Please check your call stack and make sure that you are **not** doing any of the following inside the nested Ruby frame:\n" +
835
- " 1. Switching fibers (e.g. Fiber#resume, Fiber.yield, and Fiber#transfer)\n" +
836
- " Note that `evalAsync` JS API switches fibers internally\n" +
837
- " 2. Raising uncaught exceptions\n" +
838
- " Please catch all exceptions inside the nested operation\n" +
839
- " 3. Calling Continuation APIs\n";
840
- const error = new RbValue(this.guest.rbErrinfo(), this, this.privateObject());
841
- if (error.call("nil?").toString() === "false") {
842
- message += "\n" + this.exceptionFormatter.format(error, this, this.privateObject());
843
- }
844
- throw new RbFatalError(message);
909
+ this.throwProhibitRewindException(str);
845
910
  },
846
911
  };
912
+ addRbJsAbiHostToImports(imports, this.getImports((value) => value, (value) => value), (name) => {
913
+ return this.instance.exports[name];
914
+ });
915
+ }
916
+ throwProhibitRewindException(str) {
917
+ let message = "Ruby APIs that may rewind the VM stack are prohibited under nested VM operation " +
918
+ `(${str})\n` +
919
+ "Nested VM operation means that the call stack has sandwitched JS frames like JS -> Ruby -> JS -> Ruby " +
920
+ "caused by something like `window.rubyVM.eval(\"JS.global[:rubyVM].eval('Fiber.yield')\")`\n" +
921
+ "\n" +
922
+ "Please check your call stack and make sure that you are **not** doing any of the following inside the nested Ruby frame:\n" +
923
+ " 1. Switching fibers (e.g. Fiber#resume, Fiber.yield, and Fiber#transfer)\n" +
924
+ " Note that `evalAsync` JS API switches fibers internally\n" +
925
+ " 2. Raising uncaught exceptions\n" +
926
+ " Please catch all exceptions inside the nested operation\n" +
927
+ " 3. Calling Continuation APIs\n";
928
+ const error = new RbValue(this.guest.rbErrinfo(), this, this.privateObject());
929
+ if (error.call("nil?").toString() === "false") {
930
+ message += "\n" + this.exceptionFormatter.format(error, this, this.privateObject());
931
+ }
932
+ throw new RbFatalError(message);
933
+ }
934
+ getImports(toJSAbiValue, fromJSAbiValue) {
847
935
  // NOTE: The GC may collect objects that are still referenced by Wasm
848
936
  // locals because Asyncify cannot scan the Wasm stack above the JS frame.
849
937
  // So we need to keep track whether the JS frame is sandwitched by Ruby
@@ -862,9 +950,24 @@
862
950
  }
863
951
  return imports;
864
952
  };
865
- addRbJsAbiHostToImports(imports, proxyImports({
953
+ function wrapTry(f) {
954
+ return (...args) => {
955
+ try {
956
+ return { tag: "success", val: f(...args) };
957
+ }
958
+ catch (e) {
959
+ if (e instanceof RbFatalError) {
960
+ // RbFatalError should not be caught by Ruby because it Ruby VM
961
+ // can be already in an inconsistent state.
962
+ throw e;
963
+ }
964
+ return { tag: "failure", val: toJSAbiValue(e) };
965
+ }
966
+ };
967
+ }
968
+ return proxyImports({
866
969
  evalJs: wrapTry((code) => {
867
- return Function(code)();
970
+ return toJSAbiValue(Function(code)());
868
971
  }),
869
972
  isJs: (value) => {
870
973
  // Just for compatibility with the old JS API
@@ -872,45 +975,47 @@
872
975
  },
873
976
  globalThis: () => {
874
977
  if (typeof globalThis !== "undefined") {
875
- return globalThis;
978
+ return toJSAbiValue(globalThis);
876
979
  }
877
980
  else if (typeof global !== "undefined") {
878
- return global;
981
+ return toJSAbiValue(global);
879
982
  }
880
983
  else if (typeof window !== "undefined") {
881
- return window;
984
+ return toJSAbiValue(window);
882
985
  }
883
986
  throw new Error("unable to locate global object");
884
987
  },
885
988
  intToJsNumber: (value) => {
886
- return value;
989
+ return toJSAbiValue(value);
887
990
  },
888
991
  floatToJsNumber: (value) => {
889
- return value;
992
+ return toJSAbiValue(value);
890
993
  },
891
994
  stringToJsString: (value) => {
892
- return value;
995
+ return toJSAbiValue(value);
893
996
  },
894
997
  boolToJsBool: (value) => {
895
- return value;
998
+ return toJSAbiValue(value);
896
999
  },
897
1000
  procToJsFunction: (rawRbAbiValue) => {
898
1001
  const rbValue = this.rbValueOfPointer(rawRbAbiValue);
899
- return (...args) => {
1002
+ return toJSAbiValue((...args) => {
900
1003
  return rbValue.call("call", ...args.map((arg) => this.wrap(arg))).toJS();
901
- };
1004
+ });
902
1005
  },
903
1006
  rbObjectToJsRbValue: (rawRbAbiValue) => {
904
- return this.rbValueOfPointer(rawRbAbiValue);
1007
+ return toJSAbiValue(this.rbValueOfPointer(rawRbAbiValue));
905
1008
  },
906
1009
  jsValueToString: (value) => {
1010
+ value = fromJSAbiValue(value);
907
1011
  // According to the [spec](https://tc39.es/ecma262/multipage/text-processing.html#sec-string-constructor-string-value)
908
1012
  // `String(value)` always returns a string.
909
1013
  return String(value);
910
1014
  },
911
1015
  jsValueToInteger(value) {
1016
+ value = fromJSAbiValue(value);
912
1017
  if (typeof value === "number") {
913
- return { tag: "f64", val: value };
1018
+ return { tag: "as-float", val: value };
914
1019
  }
915
1020
  else if (typeof value === "bigint") {
916
1021
  return { tag: "bignum", val: BigInt(value).toString(10) + "\0" };
@@ -919,38 +1024,40 @@
919
1024
  return { tag: "bignum", val: value + "\0" };
920
1025
  }
921
1026
  else if (typeof value === "undefined") {
922
- return { tag: "f64", val: 0 };
1027
+ return { tag: "as-float", val: 0 };
923
1028
  }
924
1029
  else {
925
- return { tag: "f64", val: Number(value) };
1030
+ return { tag: "as-float", val: Number(value) };
926
1031
  }
927
1032
  },
928
1033
  exportJsValueToHost: (value) => {
929
1034
  // See `JsValueExporter` for the reason why we need to do this
930
- this.transport.takeJsValue(value);
1035
+ this.transport.takeJsValue(fromJSAbiValue(value));
931
1036
  },
932
1037
  importJsValueFromHost: () => {
933
- return this.transport.consumeJsValue();
1038
+ return toJSAbiValue(this.transport.consumeJsValue());
934
1039
  },
935
1040
  instanceOf: (value, klass) => {
1041
+ klass = fromJSAbiValue(klass);
936
1042
  if (typeof klass === "function") {
937
- return value instanceof klass;
1043
+ return fromJSAbiValue(value) instanceof klass;
938
1044
  }
939
1045
  else {
940
1046
  return false;
941
1047
  }
942
1048
  },
943
1049
  jsValueTypeof(value) {
944
- return typeof value;
1050
+ return typeof fromJSAbiValue(value);
945
1051
  },
946
1052
  jsValueEqual(lhs, rhs) {
947
- return lhs == rhs;
1053
+ return fromJSAbiValue(lhs) == fromJSAbiValue(rhs);
948
1054
  },
949
1055
  jsValueStrictlyEqual(lhs, rhs) {
950
- return lhs === rhs;
1056
+ return fromJSAbiValue(lhs) === fromJSAbiValue(rhs);
951
1057
  },
952
1058
  reflectApply: wrapTry((target, thisArgument, args) => {
953
- return Reflect.apply(target, thisArgument, args);
1059
+ const jsArgs = args.map((arg) => fromJSAbiValue(arg));
1060
+ return toJSAbiValue(Reflect.apply(fromJSAbiValue(target), fromJSAbiValue(thisArgument), jsArgs));
954
1061
  }),
955
1062
  reflectConstruct: function (target, args) {
956
1063
  throw new Error("Function not implemented.");
@@ -959,7 +1066,7 @@
959
1066
  throw new Error("Function not implemented.");
960
1067
  },
961
1068
  reflectGet: wrapTry((target, propertyKey) => {
962
- return target[propertyKey];
1069
+ return toJSAbiValue(fromJSAbiValue(target)[propertyKey]);
963
1070
  }),
964
1071
  reflectGetOwnPropertyDescriptor: function (target, propertyKey) {
965
1072
  throw new Error("Function not implemented.");
@@ -980,13 +1087,11 @@
980
1087
  throw new Error("Function not implemented.");
981
1088
  },
982
1089
  reflectSet: wrapTry((target, propertyKey, value) => {
983
- return Reflect.set(target, propertyKey, value);
1090
+ return toJSAbiValue(Reflect.set(fromJSAbiValue(target), propertyKey, fromJSAbiValue(value)));
984
1091
  }),
985
1092
  reflectSetPrototypeOf: function (target, prototype) {
986
1093
  throw new Error("Function not implemented.");
987
1094
  },
988
- }), (name) => {
989
- return this.instance.exports[name];
990
1095
  });
991
1096
  }
992
1097
  /**
@@ -1319,7 +1424,12 @@
1319
1424
  }
1320
1425
  // All JS exceptions triggered by Ruby code are translated to Ruby exceptions,
1321
1426
  // so non-RbError exceptions are unexpected.
1322
- vm.guest.rbVmBugreport();
1427
+ try {
1428
+ vm.guest.rbVmBugreport();
1429
+ }
1430
+ catch (e) {
1431
+ console.error("Tried to report internal Ruby VM state but failed: ", e);
1432
+ }
1323
1433
  if (e instanceof WebAssembly.RuntimeError && e.message === "unreachable") {
1324
1434
  const error = new RbError(`Something went wrong in Ruby VM: ${e}`);
1325
1435
  error.stack = e.stack;
@@ -1385,7 +1495,12 @@
1385
1495
  var _a, _b;
1386
1496
  const args = [];
1387
1497
  const env = Object.entries((_a = options.env) !== null && _a !== void 0 ? _a : {}).map(([k, v]) => `${k}=${v}`);
1388
- const fds = [];
1498
+ const fds = [
1499
+ new OpenFile(new File([])),
1500
+ new OpenFile(new File([])),
1501
+ new OpenFile(new File([])),
1502
+ new PreopenDirectory("/", new Map()),
1503
+ ];
1389
1504
  const wasi = new WASI(args, env, fds, { debug: false });
1390
1505
  const vm = new RubyVM();
1391
1506
  const imports = {
@@ -0,0 +1,45 @@
1
+ export namespace RubyJsJsRuntime {
2
+ export function evalJs(code: string): JsAbiResult;
3
+ export function isJs(value: JsAbiValue): boolean;
4
+ export function instanceOf(value: JsAbiValue, klass: JsAbiValue): boolean;
5
+ export function globalThis(): JsAbiValue;
6
+ export function intToJsNumber(value: number): JsAbiValue;
7
+ export function floatToJsNumber(value: number): JsAbiValue;
8
+ export function stringToJsString(value: string): JsAbiValue;
9
+ export function boolToJsBool(value: boolean): JsAbiValue;
10
+ export function procToJsFunction(): JsAbiValue;
11
+ export function rbObjectToJsRbValue(): JsAbiValue;
12
+ export function jsValueToString(value: JsAbiValue): string;
13
+ export function jsValueToInteger(value: JsAbiValue): RawInteger;
14
+ export function exportJsValueToHost(value: JsAbiValue): void;
15
+ export function importJsValueFromHost(): JsAbiValue;
16
+ export function jsValueTypeof(value: JsAbiValue): string;
17
+ export function jsValueEqual(lhs: JsAbiValue, rhs: JsAbiValue): boolean;
18
+ export function jsValueStrictlyEqual(lhs: JsAbiValue, rhs: JsAbiValue): boolean;
19
+ export function reflectApply(target: JsAbiValue, thisArgument: JsAbiValue, arguments: JsAbiValue[]): JsAbiResult;
20
+ export function reflectGet(target: JsAbiValue, propertyKey: string): JsAbiResult;
21
+ export function reflectSet(target: JsAbiValue, propertyKey: string, value: JsAbiValue): JsAbiResult;
22
+ export function throwProhibitRewindException(message: string): void;
23
+ export { JsAbiValue };
24
+ }
25
+ export type JsAbiResult = JsAbiResultSuccess | JsAbiResultFailure;
26
+ export interface JsAbiResultSuccess {
27
+ tag: 'success',
28
+ val: JsAbiValue,
29
+ }
30
+ export interface JsAbiResultFailure {
31
+ tag: 'failure',
32
+ val: JsAbiValue,
33
+ }
34
+ export type RawInteger = RawIntegerAsFloat | RawIntegerBignum;
35
+ export interface RawIntegerAsFloat {
36
+ tag: 'as-float',
37
+ val: number,
38
+ }
39
+ export interface RawIntegerBignum {
40
+ tag: 'bignum',
41
+ val: string,
42
+ }
43
+
44
+ export class JsAbiValue {
45
+ }
@@ -0,0 +1,31 @@
1
+ export namespace RubyJsRubyRuntime {
2
+ export function rubyShowVersion(): void;
3
+ export function rubyInit(): void;
4
+ export function rubySysinit(args: string[]): void;
5
+ export function rubyOptions(args: string[]): RbIseq;
6
+ export function rubyScript(name: string): void;
7
+ export function rubyInitLoadpath(): void;
8
+ export function rbEvalStringProtect(str: string): [RbAbiValue, number];
9
+ export function rbFuncallvProtect(recv: RbAbiValue, mid: RbId, args: RbAbiValue[]): [RbAbiValue, number];
10
+ export function rbIntern(name: string): RbId;
11
+ export function rbErrinfo(): RbAbiValue;
12
+ export function rbClearErrinfo(): void;
13
+ export function rstringPtr(value: RbAbiValue): string;
14
+ export function rbVmBugreport(): void;
15
+ export function rbGcEnable(): boolean;
16
+ export function rbGcDisable(): boolean;
17
+ export function rbSetShouldProhibitRewind(newValue: boolean): boolean;
18
+ export function exportRbValueToJs(): RbAbiValue;
19
+ export { RbIseq };
20
+ export { RbAbiValue };
21
+ }
22
+ import type { JsAbiValue } from './ruby-js-js-runtime.js';
23
+ export { JsAbiValue };
24
+ export type RbErrno = number;
25
+ export type RbId = number;
26
+
27
+ export class RbAbiValue {
28
+ }
29
+
30
+ export class RbIseq {
31
+ }
@@ -0,0 +1,3 @@
1
+ export namespace WasiCliEnvironment {
2
+ export function getEnvironment(): [string, string][];
3
+ }
@@ -0,0 +1,4 @@
1
+ export namespace WasiCliExit {
2
+ export function exit(status: Result<void, void>): void;
3
+ }
4
+ export type Result<T, E> = { tag: 'ok', val: T } | { tag: 'err', val: E };
@@ -0,0 +1,5 @@
1
+ export namespace WasiCliStderr {
2
+ export function getStderr(): OutputStream;
3
+ }
4
+ import type { OutputStream } from './wasi-io-streams.js';
5
+ export { OutputStream };
@@ -0,0 +1,5 @@
1
+ export namespace WasiCliStdin {
2
+ export function getStdin(): InputStream;
3
+ }
4
+ import type { InputStream } from './wasi-io-streams.js';
5
+ export { InputStream };
@@ -0,0 +1,5 @@
1
+ export namespace WasiCliStdout {
2
+ export function getStdout(): OutputStream;
3
+ }
4
+ import type { OutputStream } from './wasi-io-streams.js';
5
+ export { OutputStream };
@@ -0,0 +1,6 @@
1
+ export namespace WasiCliTerminalInput {
2
+ export { TerminalInput };
3
+ }
4
+
5
+ export class TerminalInput {
6
+ }
@@ -0,0 +1,6 @@
1
+ export namespace WasiCliTerminalOutput {
2
+ export { TerminalOutput };
3
+ }
4
+
5
+ export class TerminalOutput {
6
+ }
@@ -0,0 +1,5 @@
1
+ export namespace WasiCliTerminalStderr {
2
+ export function getTerminalStderr(): TerminalOutput | undefined;
3
+ }
4
+ import type { TerminalOutput } from './wasi-cli-terminal-output.js';
5
+ export { TerminalOutput };