@ruby/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.
- package/dist/browser.script.umd.js +181 -66
- package/dist/browser.umd.js +181 -66
- package/dist/cjs/bindgen/interfaces/ruby-js-js-runtime.d.ts +45 -0
- package/dist/cjs/bindgen/interfaces/ruby-js-ruby-runtime.d.ts +42 -0
- package/dist/cjs/bindgen/{rb-js-abi-host.d.ts → legacy/rb-js-abi-host.d.ts} +3 -3
- package/dist/cjs/bindgen/{rb-js-abi-host.js → legacy/rb-js-abi-host.js} +2 -2
- package/dist/cjs/binding.d.ts +54 -0
- package/dist/cjs/binding.js +72 -0
- package/dist/cjs/browser.js +6 -1
- package/dist/cjs/node.js +1 -1
- package/dist/cjs/vm.d.ts +12 -5
- package/dist/cjs/vm.js +104 -63
- package/dist/esm/bindgen/interfaces/ruby-js-js-runtime.d.ts +45 -0
- package/dist/esm/bindgen/interfaces/ruby-js-ruby-runtime.d.ts +42 -0
- package/dist/esm/bindgen/{rb-js-abi-host.d.ts → legacy/rb-js-abi-host.d.ts} +3 -3
- package/dist/esm/bindgen/{rb-js-abi-host.js → legacy/rb-js-abi-host.js} +2 -2
- package/dist/esm/binding.d.ts +54 -0
- package/dist/esm/binding.js +66 -0
- package/dist/esm/browser.js +7 -2
- package/dist/esm/node.js +1 -1
- package/dist/esm/vm.d.ts +12 -5
- package/dist/esm/vm.js +104 -63
- package/dist/index.umd.js +169 -63
- package/package.json +9 -8
- /package/dist/cjs/bindgen/{intrinsics.d.ts → legacy/intrinsics.d.ts} +0 -0
- /package/dist/cjs/bindgen/{intrinsics.js → legacy/intrinsics.js} +0 -0
- /package/dist/cjs/bindgen/{rb-abi-guest.d.ts → legacy/rb-abi-guest.d.ts} +0 -0
- /package/dist/cjs/bindgen/{rb-abi-guest.js → legacy/rb-abi-guest.js} +0 -0
- /package/dist/esm/bindgen/{intrinsics.d.ts → legacy/intrinsics.d.ts} +0 -0
- /package/dist/esm/bindgen/{intrinsics.js → legacy/intrinsics.js} +0 -0
- /package/dist/esm/bindgen/{rb-abi-guest.d.ts → legacy/rb-abi-guest.d.ts} +0 -0
- /package/dist/esm/bindgen/{rb-abi-guest.js → legacy/rb-abi-guest.js} +0 -0
|
@@ -46,11 +46,15 @@
|
|
|
46
46
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
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}}
|
|
49
|
+
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);}}
|
|
50
50
|
|
|
51
51
|
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);
|
|
52
52
|
|
|
53
|
-
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"}};}};
|
|
53
|
+
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"}};}};
|
|
54
|
+
|
|
55
|
+
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{}
|
|
56
|
+
|
|
57
|
+
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;}}}
|
|
54
58
|
|
|
55
59
|
/**
|
|
56
60
|
* Create a console printer that can be used as an overlay of WASI imports.
|
|
@@ -548,13 +552,13 @@
|
|
|
548
552
|
data_view(memory).setInt32(arg1 + 4, len0, true);
|
|
549
553
|
data_view(memory).setInt32(arg1 + 0, ptr0, true);
|
|
550
554
|
};
|
|
551
|
-
imports["rb-js-abi-host"]["js-value-to-integer: func(value: handle<js-abi-value>) -> variant {
|
|
555
|
+
imports["rb-js-abi-host"]["js-value-to-integer: func(value: handle<js-abi-value>) -> variant { as-float(float64), bignum(string) }"] = function(arg0, arg1) {
|
|
552
556
|
const memory = get_export("memory");
|
|
553
557
|
const realloc = get_export("cabi_realloc");
|
|
554
558
|
const ret0 = obj.jsValueToInteger(resources0.get(arg0));
|
|
555
559
|
const variant1 = ret0;
|
|
556
560
|
switch (variant1.tag) {
|
|
557
|
-
case "
|
|
561
|
+
case "as-float": {
|
|
558
562
|
const e = variant1.val;
|
|
559
563
|
data_view(memory).setInt8(arg1 + 0, 0, true);
|
|
560
564
|
data_view(memory).setFloat64(arg1 + 8, +e, true);
|
|
@@ -750,6 +754,72 @@
|
|
|
750
754
|
};
|
|
751
755
|
}
|
|
752
756
|
|
|
757
|
+
class LegacyBinding extends RbAbiGuest {
|
|
758
|
+
async setInstance(instance) {
|
|
759
|
+
await this.instantiate(instance);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
class ComponentBinding {
|
|
763
|
+
constructor() { }
|
|
764
|
+
setUnderlying(underlying) {
|
|
765
|
+
this.underlying = underlying;
|
|
766
|
+
}
|
|
767
|
+
rubyShowVersion() {
|
|
768
|
+
this.underlying.rubyShowVersion();
|
|
769
|
+
}
|
|
770
|
+
rubyInit() {
|
|
771
|
+
this.underlying.rubyInit();
|
|
772
|
+
}
|
|
773
|
+
rubySysinit(args) {
|
|
774
|
+
this.underlying.rubySysinit(args);
|
|
775
|
+
}
|
|
776
|
+
rubyOptions(args) {
|
|
777
|
+
this.underlying.rubyOptions(args);
|
|
778
|
+
}
|
|
779
|
+
rubyScript(name) {
|
|
780
|
+
this.underlying.rubyScript(name);
|
|
781
|
+
}
|
|
782
|
+
rubyInitLoadpath() {
|
|
783
|
+
this.underlying.rubyInitLoadpath();
|
|
784
|
+
}
|
|
785
|
+
rbEvalStringProtect(str) {
|
|
786
|
+
return this.underlying.rbEvalStringProtect(str);
|
|
787
|
+
}
|
|
788
|
+
rbFuncallvProtect(recv, mid, args) {
|
|
789
|
+
return this.underlying.rbFuncallvProtect(recv, mid, args);
|
|
790
|
+
}
|
|
791
|
+
rbIntern(name) {
|
|
792
|
+
return this.underlying.rbIntern(name);
|
|
793
|
+
}
|
|
794
|
+
rbErrinfo() {
|
|
795
|
+
return this.underlying.rbErrinfo();
|
|
796
|
+
}
|
|
797
|
+
rbClearErrinfo() {
|
|
798
|
+
return this.underlying.rbClearErrinfo();
|
|
799
|
+
}
|
|
800
|
+
rstringPtr(value) {
|
|
801
|
+
return this.underlying.rstringPtr(value);
|
|
802
|
+
}
|
|
803
|
+
rbVmBugreport() {
|
|
804
|
+
this.underlying.rbVmBugreport();
|
|
805
|
+
}
|
|
806
|
+
rbGcEnable() {
|
|
807
|
+
return this.underlying.rbGcEnable();
|
|
808
|
+
}
|
|
809
|
+
rbGcDisable() {
|
|
810
|
+
return this.underlying.rbGcDisable();
|
|
811
|
+
}
|
|
812
|
+
rbSetShouldProhibitRewind(newValue) {
|
|
813
|
+
return this.underlying.rbSetShouldProhibitRewind(newValue);
|
|
814
|
+
}
|
|
815
|
+
async setInstance(instance) {
|
|
816
|
+
// No-op
|
|
817
|
+
}
|
|
818
|
+
addToImports(imports) {
|
|
819
|
+
// No-op
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
|
|
753
823
|
/**
|
|
754
824
|
* A Ruby VM instance
|
|
755
825
|
*
|
|
@@ -770,7 +840,7 @@
|
|
|
770
840
|
*
|
|
771
841
|
*/
|
|
772
842
|
class RubyVM {
|
|
773
|
-
constructor() {
|
|
843
|
+
constructor(binding) {
|
|
774
844
|
this.instance = null;
|
|
775
845
|
this.interfaceState = {
|
|
776
846
|
hasJSFrameAfterRbFrame: false,
|
|
@@ -779,6 +849,7 @@
|
|
|
779
849
|
// if the call stack has sandwitched JS frames like JS -> Ruby -> JS -> Ruby.
|
|
780
850
|
const proxyExports = (exports) => {
|
|
781
851
|
const excludedMethods = [
|
|
852
|
+
"setInstance",
|
|
782
853
|
"addToImports",
|
|
783
854
|
"instantiate",
|
|
784
855
|
"rbSetShouldProhibitRewind",
|
|
@@ -813,10 +884,34 @@
|
|
|
813
884
|
}
|
|
814
885
|
return exports;
|
|
815
886
|
};
|
|
816
|
-
this.guest = proxyExports(new
|
|
887
|
+
this.guest = proxyExports(binding !== null && binding !== void 0 ? binding : new LegacyBinding());
|
|
817
888
|
this.transport = new JsValueTransport();
|
|
818
889
|
this.exceptionFormatter = new RbExceptionFormatter();
|
|
819
890
|
}
|
|
891
|
+
static async _instantiate(initComponent, options) {
|
|
892
|
+
const binding = new ComponentBinding();
|
|
893
|
+
const vm = new RubyVM(binding);
|
|
894
|
+
class JsAbiValue {
|
|
895
|
+
constructor(underlying) {
|
|
896
|
+
this.underlying = underlying;
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
const imports = vm.getImports((from) => new JsAbiValue(from), (to) => to.underlying);
|
|
900
|
+
const component = await initComponent(Object.assign(Object.assign({}, imports), { throwProhibitRewindException: (message) => {
|
|
901
|
+
vm.throwProhibitRewindException(message);
|
|
902
|
+
}, procToJsFunction: () => {
|
|
903
|
+
const rbValue = new RbValue(component.exportRbValueToJs(), vm, vm.privateObject());
|
|
904
|
+
return new JsAbiValue((...args) => {
|
|
905
|
+
return rbValue.call("call", ...args.map((arg) => vm.wrap(arg))).toJS();
|
|
906
|
+
});
|
|
907
|
+
}, rbObjectToJsRbValue: () => {
|
|
908
|
+
const rbValue = new RbValue(component.exportRbValueToJs(), vm, vm.privateObject());
|
|
909
|
+
return new JsAbiValue(rbValue);
|
|
910
|
+
}, JsAbiValue: JsAbiValue }));
|
|
911
|
+
binding.setUnderlying(component);
|
|
912
|
+
vm.initialize(options.args);
|
|
913
|
+
return vm;
|
|
914
|
+
}
|
|
820
915
|
/**
|
|
821
916
|
* Initialize the Ruby VM with the given command line arguments
|
|
822
917
|
* @param args The command line arguments to pass to Ruby. Must be
|
|
@@ -840,7 +935,7 @@
|
|
|
840
935
|
*/
|
|
841
936
|
async setInstance(instance) {
|
|
842
937
|
this.instance = instance;
|
|
843
|
-
await this.guest.
|
|
938
|
+
await this.guest.setInstance(instance);
|
|
844
939
|
}
|
|
845
940
|
/**
|
|
846
941
|
* Add intrinsic import entries, which is necessary to interact JavaScript
|
|
@@ -849,43 +944,36 @@
|
|
|
849
944
|
*/
|
|
850
945
|
addToImports(imports) {
|
|
851
946
|
this.guest.addToImports(imports);
|
|
852
|
-
function wrapTry(f) {
|
|
853
|
-
return (...args) => {
|
|
854
|
-
try {
|
|
855
|
-
return { tag: "success", val: f(...args) };
|
|
856
|
-
}
|
|
857
|
-
catch (e) {
|
|
858
|
-
if (e instanceof RbFatalError) {
|
|
859
|
-
// RbFatalError should not be caught by Ruby because it Ruby VM
|
|
860
|
-
// can be already in an inconsistent state.
|
|
861
|
-
throw e;
|
|
862
|
-
}
|
|
863
|
-
return { tag: "failure", val: e };
|
|
864
|
-
}
|
|
865
|
-
};
|
|
866
|
-
}
|
|
867
947
|
imports["rb-js-abi-host"] = {
|
|
868
948
|
rb_wasm_throw_prohibit_rewind_exception: (messagePtr, messageLen) => {
|
|
869
949
|
const memory = this.instance.exports.memory;
|
|
870
950
|
const str = new TextDecoder().decode(new Uint8Array(memory.buffer, messagePtr, messageLen));
|
|
871
|
-
|
|
872
|
-
`(${str})\n` +
|
|
873
|
-
"Nested VM operation means that the call stack has sandwitched JS frames like JS -> Ruby -> JS -> Ruby " +
|
|
874
|
-
"caused by something like `window.rubyVM.eval(\"JS.global[:rubyVM].eval('Fiber.yield')\")`\n" +
|
|
875
|
-
"\n" +
|
|
876
|
-
"Please check your call stack and make sure that you are **not** doing any of the following inside the nested Ruby frame:\n" +
|
|
877
|
-
" 1. Switching fibers (e.g. Fiber#resume, Fiber.yield, and Fiber#transfer)\n" +
|
|
878
|
-
" Note that `evalAsync` JS API switches fibers internally\n" +
|
|
879
|
-
" 2. Raising uncaught exceptions\n" +
|
|
880
|
-
" Please catch all exceptions inside the nested operation\n" +
|
|
881
|
-
" 3. Calling Continuation APIs\n";
|
|
882
|
-
const error = new RbValue(this.guest.rbErrinfo(), this, this.privateObject());
|
|
883
|
-
if (error.call("nil?").toString() === "false") {
|
|
884
|
-
message += "\n" + this.exceptionFormatter.format(error, this, this.privateObject());
|
|
885
|
-
}
|
|
886
|
-
throw new RbFatalError(message);
|
|
951
|
+
this.throwProhibitRewindException(str);
|
|
887
952
|
},
|
|
888
953
|
};
|
|
954
|
+
addRbJsAbiHostToImports(imports, this.getImports((value) => value, (value) => value), (name) => {
|
|
955
|
+
return this.instance.exports[name];
|
|
956
|
+
});
|
|
957
|
+
}
|
|
958
|
+
throwProhibitRewindException(str) {
|
|
959
|
+
let message = "Ruby APIs that may rewind the VM stack are prohibited under nested VM operation " +
|
|
960
|
+
`(${str})\n` +
|
|
961
|
+
"Nested VM operation means that the call stack has sandwitched JS frames like JS -> Ruby -> JS -> Ruby " +
|
|
962
|
+
"caused by something like `window.rubyVM.eval(\"JS.global[:rubyVM].eval('Fiber.yield')\")`\n" +
|
|
963
|
+
"\n" +
|
|
964
|
+
"Please check your call stack and make sure that you are **not** doing any of the following inside the nested Ruby frame:\n" +
|
|
965
|
+
" 1. Switching fibers (e.g. Fiber#resume, Fiber.yield, and Fiber#transfer)\n" +
|
|
966
|
+
" Note that `evalAsync` JS API switches fibers internally\n" +
|
|
967
|
+
" 2. Raising uncaught exceptions\n" +
|
|
968
|
+
" Please catch all exceptions inside the nested operation\n" +
|
|
969
|
+
" 3. Calling Continuation APIs\n";
|
|
970
|
+
const error = new RbValue(this.guest.rbErrinfo(), this, this.privateObject());
|
|
971
|
+
if (error.call("nil?").toString() === "false") {
|
|
972
|
+
message += "\n" + this.exceptionFormatter.format(error, this, this.privateObject());
|
|
973
|
+
}
|
|
974
|
+
throw new RbFatalError(message);
|
|
975
|
+
}
|
|
976
|
+
getImports(toJSAbiValue, fromJSAbiValue) {
|
|
889
977
|
// NOTE: The GC may collect objects that are still referenced by Wasm
|
|
890
978
|
// locals because Asyncify cannot scan the Wasm stack above the JS frame.
|
|
891
979
|
// So we need to keep track whether the JS frame is sandwitched by Ruby
|
|
@@ -904,9 +992,24 @@
|
|
|
904
992
|
}
|
|
905
993
|
return imports;
|
|
906
994
|
};
|
|
907
|
-
|
|
995
|
+
function wrapTry(f) {
|
|
996
|
+
return (...args) => {
|
|
997
|
+
try {
|
|
998
|
+
return { tag: "success", val: f(...args) };
|
|
999
|
+
}
|
|
1000
|
+
catch (e) {
|
|
1001
|
+
if (e instanceof RbFatalError) {
|
|
1002
|
+
// RbFatalError should not be caught by Ruby because it Ruby VM
|
|
1003
|
+
// can be already in an inconsistent state.
|
|
1004
|
+
throw e;
|
|
1005
|
+
}
|
|
1006
|
+
return { tag: "failure", val: toJSAbiValue(e) };
|
|
1007
|
+
}
|
|
1008
|
+
};
|
|
1009
|
+
}
|
|
1010
|
+
return proxyImports({
|
|
908
1011
|
evalJs: wrapTry((code) => {
|
|
909
|
-
return Function(code)();
|
|
1012
|
+
return toJSAbiValue(Function(code)());
|
|
910
1013
|
}),
|
|
911
1014
|
isJs: (value) => {
|
|
912
1015
|
// Just for compatibility with the old JS API
|
|
@@ -914,45 +1017,47 @@
|
|
|
914
1017
|
},
|
|
915
1018
|
globalThis: () => {
|
|
916
1019
|
if (typeof globalThis !== "undefined") {
|
|
917
|
-
return globalThis;
|
|
1020
|
+
return toJSAbiValue(globalThis);
|
|
918
1021
|
}
|
|
919
1022
|
else if (typeof global !== "undefined") {
|
|
920
|
-
return global;
|
|
1023
|
+
return toJSAbiValue(global);
|
|
921
1024
|
}
|
|
922
1025
|
else if (typeof window !== "undefined") {
|
|
923
|
-
return window;
|
|
1026
|
+
return toJSAbiValue(window);
|
|
924
1027
|
}
|
|
925
1028
|
throw new Error("unable to locate global object");
|
|
926
1029
|
},
|
|
927
1030
|
intToJsNumber: (value) => {
|
|
928
|
-
return value;
|
|
1031
|
+
return toJSAbiValue(value);
|
|
929
1032
|
},
|
|
930
1033
|
floatToJsNumber: (value) => {
|
|
931
|
-
return value;
|
|
1034
|
+
return toJSAbiValue(value);
|
|
932
1035
|
},
|
|
933
1036
|
stringToJsString: (value) => {
|
|
934
|
-
return value;
|
|
1037
|
+
return toJSAbiValue(value);
|
|
935
1038
|
},
|
|
936
1039
|
boolToJsBool: (value) => {
|
|
937
|
-
return value;
|
|
1040
|
+
return toJSAbiValue(value);
|
|
938
1041
|
},
|
|
939
1042
|
procToJsFunction: (rawRbAbiValue) => {
|
|
940
1043
|
const rbValue = this.rbValueOfPointer(rawRbAbiValue);
|
|
941
|
-
return (...args) => {
|
|
1044
|
+
return toJSAbiValue((...args) => {
|
|
942
1045
|
return rbValue.call("call", ...args.map((arg) => this.wrap(arg))).toJS();
|
|
943
|
-
};
|
|
1046
|
+
});
|
|
944
1047
|
},
|
|
945
1048
|
rbObjectToJsRbValue: (rawRbAbiValue) => {
|
|
946
|
-
return this.rbValueOfPointer(rawRbAbiValue);
|
|
1049
|
+
return toJSAbiValue(this.rbValueOfPointer(rawRbAbiValue));
|
|
947
1050
|
},
|
|
948
1051
|
jsValueToString: (value) => {
|
|
1052
|
+
value = fromJSAbiValue(value);
|
|
949
1053
|
// According to the [spec](https://tc39.es/ecma262/multipage/text-processing.html#sec-string-constructor-string-value)
|
|
950
1054
|
// `String(value)` always returns a string.
|
|
951
1055
|
return String(value);
|
|
952
1056
|
},
|
|
953
1057
|
jsValueToInteger(value) {
|
|
1058
|
+
value = fromJSAbiValue(value);
|
|
954
1059
|
if (typeof value === "number") {
|
|
955
|
-
return { tag: "
|
|
1060
|
+
return { tag: "as-float", val: value };
|
|
956
1061
|
}
|
|
957
1062
|
else if (typeof value === "bigint") {
|
|
958
1063
|
return { tag: "bignum", val: BigInt(value).toString(10) + "\0" };
|
|
@@ -961,38 +1066,40 @@
|
|
|
961
1066
|
return { tag: "bignum", val: value + "\0" };
|
|
962
1067
|
}
|
|
963
1068
|
else if (typeof value === "undefined") {
|
|
964
|
-
return { tag: "
|
|
1069
|
+
return { tag: "as-float", val: 0 };
|
|
965
1070
|
}
|
|
966
1071
|
else {
|
|
967
|
-
return { tag: "
|
|
1072
|
+
return { tag: "as-float", val: Number(value) };
|
|
968
1073
|
}
|
|
969
1074
|
},
|
|
970
1075
|
exportJsValueToHost: (value) => {
|
|
971
1076
|
// See `JsValueExporter` for the reason why we need to do this
|
|
972
|
-
this.transport.takeJsValue(value);
|
|
1077
|
+
this.transport.takeJsValue(fromJSAbiValue(value));
|
|
973
1078
|
},
|
|
974
1079
|
importJsValueFromHost: () => {
|
|
975
|
-
return this.transport.consumeJsValue();
|
|
1080
|
+
return toJSAbiValue(this.transport.consumeJsValue());
|
|
976
1081
|
},
|
|
977
1082
|
instanceOf: (value, klass) => {
|
|
1083
|
+
klass = fromJSAbiValue(klass);
|
|
978
1084
|
if (typeof klass === "function") {
|
|
979
|
-
return value instanceof klass;
|
|
1085
|
+
return fromJSAbiValue(value) instanceof klass;
|
|
980
1086
|
}
|
|
981
1087
|
else {
|
|
982
1088
|
return false;
|
|
983
1089
|
}
|
|
984
1090
|
},
|
|
985
1091
|
jsValueTypeof(value) {
|
|
986
|
-
return typeof value;
|
|
1092
|
+
return typeof fromJSAbiValue(value);
|
|
987
1093
|
},
|
|
988
1094
|
jsValueEqual(lhs, rhs) {
|
|
989
|
-
return lhs == rhs;
|
|
1095
|
+
return fromJSAbiValue(lhs) == fromJSAbiValue(rhs);
|
|
990
1096
|
},
|
|
991
1097
|
jsValueStrictlyEqual(lhs, rhs) {
|
|
992
|
-
return lhs === rhs;
|
|
1098
|
+
return fromJSAbiValue(lhs) === fromJSAbiValue(rhs);
|
|
993
1099
|
},
|
|
994
1100
|
reflectApply: wrapTry((target, thisArgument, args) => {
|
|
995
|
-
|
|
1101
|
+
const jsArgs = args.map((arg) => fromJSAbiValue(arg));
|
|
1102
|
+
return toJSAbiValue(Reflect.apply(fromJSAbiValue(target), fromJSAbiValue(thisArgument), jsArgs));
|
|
996
1103
|
}),
|
|
997
1104
|
reflectConstruct: function (target, args) {
|
|
998
1105
|
throw new Error("Function not implemented.");
|
|
@@ -1001,7 +1108,7 @@
|
|
|
1001
1108
|
throw new Error("Function not implemented.");
|
|
1002
1109
|
},
|
|
1003
1110
|
reflectGet: wrapTry((target, propertyKey) => {
|
|
1004
|
-
return target[propertyKey];
|
|
1111
|
+
return toJSAbiValue(fromJSAbiValue(target)[propertyKey]);
|
|
1005
1112
|
}),
|
|
1006
1113
|
reflectGetOwnPropertyDescriptor: function (target, propertyKey) {
|
|
1007
1114
|
throw new Error("Function not implemented.");
|
|
@@ -1022,13 +1129,11 @@
|
|
|
1022
1129
|
throw new Error("Function not implemented.");
|
|
1023
1130
|
},
|
|
1024
1131
|
reflectSet: wrapTry((target, propertyKey, value) => {
|
|
1025
|
-
return Reflect.set(target, propertyKey, value);
|
|
1132
|
+
return toJSAbiValue(Reflect.set(fromJSAbiValue(target), propertyKey, fromJSAbiValue(value)));
|
|
1026
1133
|
}),
|
|
1027
1134
|
reflectSetPrototypeOf: function (target, prototype) {
|
|
1028
1135
|
throw new Error("Function not implemented.");
|
|
1029
1136
|
},
|
|
1030
|
-
}), (name) => {
|
|
1031
|
-
return this.instance.exports[name];
|
|
1032
1137
|
});
|
|
1033
1138
|
}
|
|
1034
1139
|
/**
|
|
@@ -1361,7 +1466,12 @@
|
|
|
1361
1466
|
}
|
|
1362
1467
|
// All JS exceptions triggered by Ruby code are translated to Ruby exceptions,
|
|
1363
1468
|
// so non-RbError exceptions are unexpected.
|
|
1364
|
-
|
|
1469
|
+
try {
|
|
1470
|
+
vm.guest.rbVmBugreport();
|
|
1471
|
+
}
|
|
1472
|
+
catch (e) {
|
|
1473
|
+
console.error("Tried to report internal Ruby VM state but failed: ", e);
|
|
1474
|
+
}
|
|
1365
1475
|
if (e instanceof WebAssembly.RuntimeError && e.message === "unreachable") {
|
|
1366
1476
|
const error = new RbError(`Something went wrong in Ruby VM: ${e}`);
|
|
1367
1477
|
error.stack = e.stack;
|
|
@@ -1427,7 +1537,12 @@
|
|
|
1427
1537
|
var _a, _b;
|
|
1428
1538
|
const args = [];
|
|
1429
1539
|
const env = Object.entries((_a = options.env) !== null && _a !== void 0 ? _a : {}).map(([k, v]) => `${k}=${v}`);
|
|
1430
|
-
const fds = [
|
|
1540
|
+
const fds = [
|
|
1541
|
+
new OpenFile(new File([])),
|
|
1542
|
+
new OpenFile(new File([])),
|
|
1543
|
+
new OpenFile(new File([])),
|
|
1544
|
+
new PreopenDirectory("/", new Map()),
|
|
1545
|
+
];
|
|
1431
1546
|
const wasi = new WASI(args, env, fds, { debug: false });
|
|
1432
1547
|
const vm = new RubyVM();
|
|
1433
1548
|
const imports = {
|