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