@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
package/dist/browser.umd.js
CHANGED
|
@@ -4,11 +4,15 @@
|
|
|
4
4
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["ruby-wasm-wasi"] = {}));
|
|
5
5
|
})(this, (function (exports) { 'use strict';
|
|
6
6
|
|
|
7
|
-
const CLOCKID_REALTIME=0;const CLOCKID_MONOTONIC=1;const ERRNO_SUCCESS=0;const ERRNO_BADF=8;const ERRNO_NOSYS=52;class Iovec{static read_bytes(view,ptr){const iovec=new Iovec;iovec.buf=view.getUint32(ptr,true);iovec.buf_len=view.getUint32(ptr+4,true);return iovec}static read_bytes_array(view,ptr,len){const iovecs=[];for(let i=0;i<len;i++){iovecs.push(Iovec.read_bytes(view,ptr+8*i));}return iovecs}}class Ciovec{static read_bytes(view,ptr){const iovec=new Ciovec;iovec.buf=view.getUint32(ptr,true);iovec.buf_len=view.getUint32(ptr+4,true);return iovec}static read_bytes_array(view,ptr,len){const iovecs=[];for(let i=0;i<len;i++){iovecs.push(Ciovec.read_bytes(view,ptr+8*i));}return iovecs}}
|
|
7
|
+
const CLOCKID_REALTIME=0;const CLOCKID_MONOTONIC=1;const ERRNO_SUCCESS=0;const ERRNO_BADF=8;const ERRNO_EXIST=20;const ERRNO_INVAL=28;const ERRNO_ISDIR=31;const ERRNO_NAMETOOLONG=37;const ERRNO_NOENT=44;const ERRNO_NOSYS=52;const ERRNO_NOTDIR=54;const ERRNO_NOTEMPTY=55;const ERRNO_NOTSUP=58;const ERRNO_PERM=63;const ERRNO_NOTCAPABLE=76;const RIGHTS_FD_WRITE=1<<6;class Iovec{static read_bytes(view,ptr){const iovec=new Iovec;iovec.buf=view.getUint32(ptr,true);iovec.buf_len=view.getUint32(ptr+4,true);return iovec}static read_bytes_array(view,ptr,len){const iovecs=[];for(let i=0;i<len;i++){iovecs.push(Iovec.read_bytes(view,ptr+8*i));}return iovecs}}class Ciovec{static read_bytes(view,ptr){const iovec=new Ciovec;iovec.buf=view.getUint32(ptr,true);iovec.buf_len=view.getUint32(ptr+4,true);return iovec}static read_bytes_array(view,ptr,len){const iovecs=[];for(let i=0;i<len;i++){iovecs.push(Ciovec.read_bytes(view,ptr+8*i));}return iovecs}}const WHENCE_SET=0;const WHENCE_CUR=1;const WHENCE_END=2;const FILETYPE_DIRECTORY=3;const FILETYPE_REGULAR_FILE=4;class Dirent{head_length(){return 24}name_length(){return this.dir_name.byteLength}write_head_bytes(view,ptr){view.setBigUint64(ptr,this.d_next,true);view.setBigUint64(ptr+8,this.d_ino,true);view.setUint32(ptr+16,this.dir_name.length,true);view.setUint8(ptr+20,this.d_type);}write_name_bytes(view8,ptr,buf_len){view8.set(this.dir_name.slice(0,Math.min(this.dir_name.byteLength,buf_len)),ptr);}constructor(next_cookie,name,type){this.d_ino=0n;const encoded_name=new TextEncoder().encode(name);this.d_next=next_cookie;this.d_namlen=encoded_name.byteLength;this.d_type=type;this.dir_name=encoded_name;}}const FDFLAGS_APPEND=1<<0;class Fdstat{write_bytes(view,ptr){view.setUint8(ptr,this.fs_filetype);view.setUint16(ptr+2,this.fs_flags,true);view.setBigUint64(ptr+8,this.fs_rights_base,true);view.setBigUint64(ptr+16,this.fs_rights_inherited,true);}constructor(filetype,flags){this.fs_rights_base=0n;this.fs_rights_inherited=0n;this.fs_filetype=filetype;this.fs_flags=flags;}}const OFLAGS_CREAT=1<<0;const OFLAGS_DIRECTORY=1<<1;const OFLAGS_EXCL=1<<2;const OFLAGS_TRUNC=1<<3;class Filestat{write_bytes(view,ptr){view.setBigUint64(ptr,this.dev,true);view.setBigUint64(ptr+8,this.ino,true);view.setUint8(ptr+16,this.filetype);view.setBigUint64(ptr+24,this.nlink,true);view.setBigUint64(ptr+32,this.size,true);view.setBigUint64(ptr+38,this.atim,true);view.setBigUint64(ptr+46,this.mtim,true);view.setBigUint64(ptr+52,this.ctim,true);}constructor(filetype,size){this.dev=0n;this.ino=0n;this.nlink=0n;this.atim=0n;this.mtim=0n;this.ctim=0n;this.filetype=filetype;this.size=size;}}const PREOPENTYPE_DIR=0;class PrestatDir{write_bytes(view,ptr){view.setUint32(ptr,this.pr_name.byteLength,true);}constructor(name){this.pr_name=new TextEncoder().encode(name);}}class Prestat{static dir(name){const prestat=new Prestat;prestat.tag=PREOPENTYPE_DIR;prestat.inner=new PrestatDir(name);return prestat}write_bytes(view,ptr){view.setUint32(ptr,this.tag,true);this.inner.write_bytes(view,ptr+4);}}
|
|
8
8
|
|
|
9
9
|
let Debug=class Debug{enable(enabled){this.log=createLogger(enabled===undefined?true:enabled,this.prefix);}get enabled(){return this.isEnabled}constructor(isEnabled){this.isEnabled=isEnabled;this.prefix="wasi:";this.enable(isEnabled);}};function createLogger(enabled,prefix){if(enabled){const a=console.log.bind(console,"%c%s","color: #265BA0",prefix);return a}else {return ()=>{}}}const debug=new Debug(false);
|
|
10
10
|
|
|
11
|
-
class WASIProcExit extends Error{constructor(code){super("exit with exit code "+code);this.code=code;}}let WASI=class WASI{start(instance){this.inst=instance;try{instance.exports._start();return 0}catch(e){if(e instanceof WASIProcExit){return e.code}else {throw e}}}initialize(instance){this.inst=instance;instance.exports._initialize();}constructor(args,env,fds,options={}){this.args=[];this.env=[];this.fds=[];debug.enable(options.debug);this.args=args;this.env=env;this.fds=fds;const self=this;this.wasiImport={args_sizes_get(argc,argv_buf_size){const buffer=new DataView(self.inst.exports.memory.buffer);buffer.setUint32(argc,self.args.length,true);let buf_size=0;for(const arg of self.args){buf_size+=arg.length+1;}buffer.setUint32(argv_buf_size,buf_size,true);debug.log(buffer.getUint32(argc,true),buffer.getUint32(argv_buf_size,true));return 0},args_get(argv,argv_buf){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);const orig_argv_buf=argv_buf;for(let i=0;i<self.args.length;i++){buffer.setUint32(argv,argv_buf,true);argv+=4;const arg=new TextEncoder().encode(self.args[i]);buffer8.set(arg,argv_buf);buffer.setUint8(argv_buf+arg.length,0);argv_buf+=arg.length+1;}if(debug.enabled){debug.log(new TextDecoder("utf-8").decode(buffer8.slice(orig_argv_buf,argv_buf)));}return 0},environ_sizes_get(environ_count,environ_size){const buffer=new DataView(self.inst.exports.memory.buffer);buffer.setUint32(environ_count,self.env.length,true);let buf_size=0;for(const environ of self.env){buf_size+=environ.length+1;}buffer.setUint32(environ_size,buf_size,true);debug.log(buffer.getUint32(environ_count,true),buffer.getUint32(environ_size,true));return 0},environ_get(environ,environ_buf){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);const orig_environ_buf=environ_buf;for(let i=0;i<self.env.length;i++){buffer.setUint32(environ,environ_buf,true);environ+=4;const e=new TextEncoder().encode(self.env[i]);buffer8.set(e,environ_buf);buffer.setUint8(environ_buf+e.length,0);environ_buf+=e.length+1;}if(debug.enabled){debug.log(new TextDecoder("utf-8").decode(buffer8.slice(orig_environ_buf,environ_buf)));}return 0},clock_res_get(id,res_ptr){let resolutionValue;switch(id){case CLOCKID_MONOTONIC:{resolutionValue=5000n;break}case CLOCKID_REALTIME:{resolutionValue=1000000n;break}default:return ERRNO_NOSYS}const view=new DataView(self.inst.exports.memory.buffer);view.setBigUint64(res_ptr,resolutionValue,true);return ERRNO_SUCCESS},clock_time_get(id,precision,time){const buffer=new DataView(self.inst.exports.memory.buffer);if(id===CLOCKID_REALTIME){buffer.setBigUint64(time,BigInt(new Date().getTime())*1000000n,true);}else if(id==CLOCKID_MONOTONIC){let monotonic_time;try{monotonic_time=BigInt(Math.round(performance.now()*1e6));}catch(e){monotonic_time=0n;}buffer.setBigUint64(time,monotonic_time,true);}else {buffer.setBigUint64(time,0n,true);}return 0},fd_advise(fd,offset,len,advice){if(self.fds[fd]!=undefined){return self.fds[fd].fd_advise(offset,len,advice)}else {return ERRNO_BADF}},fd_allocate(fd,offset,len){if(self.fds[fd]!=undefined){return self.fds[fd].fd_allocate(offset,len)}else {return ERRNO_BADF}},fd_close(fd){if(self.fds[fd]!=undefined){const ret=self.fds[fd].fd_close();self.fds[fd]=undefined;return ret}else {return ERRNO_BADF}},fd_datasync(fd){if(self.fds[fd]!=undefined){return self.fds[fd].fd_datasync()}else {return ERRNO_BADF}},fd_fdstat_get(fd,fdstat_ptr){if(self.fds[fd]!=undefined){const{ret,fdstat}=self.fds[fd].fd_fdstat_get();if(fdstat!=null){fdstat.write_bytes(new DataView(self.inst.exports.memory.buffer),fdstat_ptr);}return ret}else {return ERRNO_BADF}},fd_fdstat_set_flags(fd,flags){if(self.fds[fd]!=undefined){return self.fds[fd].fd_fdstat_set_flags(flags)}else {return ERRNO_BADF}},fd_fdstat_set_rights(fd,fs_rights_base,fs_rights_inheriting){if(self.fds[fd]!=undefined){return self.fds[fd].fd_fdstat_set_rights(fs_rights_base,fs_rights_inheriting)}else {return ERRNO_BADF}},fd_filestat_get(fd,filestat_ptr){if(self.fds[fd]!=undefined){const{ret,filestat}=self.fds[fd].fd_filestat_get();if(filestat!=null){filestat.write_bytes(new DataView(self.inst.exports.memory.buffer),filestat_ptr);}return ret}else {return ERRNO_BADF}},fd_filestat_set_size(fd,size){if(self.fds[fd]!=undefined){return self.fds[fd].fd_filestat_set_size(size)}else {return ERRNO_BADF}},fd_filestat_set_times(fd,atim,mtim,fst_flags){if(self.fds[fd]!=undefined){return self.fds[fd].fd_filestat_set_times(atim,mtim,fst_flags)}else {return ERRNO_BADF}},fd_pread(fd,iovs_ptr,iovs_len,offset,nread_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const iovecs=Iovec.read_bytes_array(buffer,iovs_ptr,iovs_len);const{ret,nread}=self.fds[fd].fd_pread(buffer8,iovecs,offset);buffer.setUint32(nread_ptr,nread,true);return ret}else {return ERRNO_BADF}},fd_prestat_get(fd,buf_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const{ret,prestat}=self.fds[fd].fd_prestat_get();if(prestat!=null){prestat.write_bytes(buffer,buf_ptr);}return ret}else {return ERRNO_BADF}},fd_prestat_dir_name(fd,path_ptr,path_len){if(self.fds[fd]!=undefined){const{ret,prestat_dir_name}=self.fds[fd].fd_prestat_dir_name();if(prestat_dir_name!=null){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);buffer8.set(prestat_dir_name,path_ptr);}return ret}else {return ERRNO_BADF}},fd_pwrite(fd,iovs_ptr,iovs_len,offset,nwritten_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const iovecs=Ciovec.read_bytes_array(buffer,iovs_ptr,iovs_len);const{ret,nwritten}=self.fds[fd].fd_pwrite(buffer8,iovecs,offset);buffer.setUint32(nwritten_ptr,nwritten,true);return ret}else {return ERRNO_BADF}},fd_read(fd,iovs_ptr,iovs_len,nread_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const iovecs=Iovec.read_bytes_array(buffer,iovs_ptr,iovs_len);const{ret,nread}=self.fds[fd].fd_read(buffer8,iovecs);buffer.setUint32(nread_ptr,nread,true);return ret}else {return ERRNO_BADF}},fd_readdir(fd,buf,buf_len,cookie,bufused_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){let bufused=0;while(true){const{ret,dirent}=self.fds[fd].fd_readdir_single(cookie);if(ret!=0){buffer.setUint32(bufused_ptr,bufused,true);return ret}if(dirent==null){break}if(buf_len-bufused<dirent.head_length()){bufused=buf_len;break}const head_bytes=new ArrayBuffer(dirent.head_length());dirent.write_head_bytes(new DataView(head_bytes),0);buffer8.set(new Uint8Array(head_bytes).slice(0,Math.min(head_bytes.byteLength,buf_len-bufused)),buf);buf+=dirent.head_length();bufused+=dirent.head_length();if(buf_len-bufused<dirent.name_length()){bufused=buf_len;break}dirent.write_name_bytes(buffer8,buf,buf_len-bufused);buf+=dirent.name_length();bufused+=dirent.name_length();cookie=dirent.d_next;}buffer.setUint32(bufused_ptr,bufused,true);return 0}else {return ERRNO_BADF}},fd_renumber(fd,to){if(self.fds[fd]!=undefined&&self.fds[to]!=undefined){const ret=self.fds[to].fd_close();if(ret!=0){return ret}self.fds[to]=self.fds[fd];self.fds[fd]=undefined;return 0}else {return ERRNO_BADF}},fd_seek(fd,offset,whence,offset_out_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const{ret,offset:offset_out}=self.fds[fd].fd_seek(offset,whence);buffer.setBigInt64(offset_out_ptr,offset_out,true);return ret}else {return ERRNO_BADF}},fd_sync(fd){if(self.fds[fd]!=undefined){return self.fds[fd].fd_sync()}else {return ERRNO_BADF}},fd_tell(fd,offset_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const{ret,offset}=self.fds[fd].fd_tell();buffer.setBigUint64(offset_ptr,offset,true);return ret}else {return ERRNO_BADF}},fd_write(fd,iovs_ptr,iovs_len,nwritten_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const iovecs=Ciovec.read_bytes_array(buffer,iovs_ptr,iovs_len);const{ret,nwritten}=self.fds[fd].fd_write(buffer8,iovecs);buffer.setUint32(nwritten_ptr,nwritten,true);return ret}else {return ERRNO_BADF}},path_create_directory(fd,path_ptr,path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));return self.fds[fd].path_create_directory(path)}},path_filestat_get(fd,flags,path_ptr,path_len,filestat_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));const{ret,filestat}=self.fds[fd].path_filestat_get(flags,path);if(filestat!=null){filestat.write_bytes(buffer,filestat_ptr);}return ret}else {return ERRNO_BADF}},path_filestat_set_times(fd,flags,path_ptr,path_len,atim,mtim,fst_flags){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));return self.fds[fd].path_filestat_set_times(flags,path,atim,mtim,fst_flags)}else {return ERRNO_BADF}},path_link(old_fd,old_flags,old_path_ptr,old_path_len,new_fd,new_path_ptr,new_path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[old_fd]!=undefined&&self.fds[new_fd]!=undefined){const old_path=new TextDecoder("utf-8").decode(buffer8.slice(old_path_ptr,old_path_ptr+old_path_len));const new_path=new TextDecoder("utf-8").decode(buffer8.slice(new_path_ptr,new_path_ptr+new_path_len));return self.fds[new_fd].path_link(old_fd,old_flags,old_path,new_path)}else {return ERRNO_BADF}},path_open(fd,dirflags,path_ptr,path_len,oflags,fs_rights_base,fs_rights_inheriting,fd_flags,opened_fd_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));debug.log(path);const{ret,fd_obj}=self.fds[fd].path_open(dirflags,path,oflags,fs_rights_base,fs_rights_inheriting,fd_flags);if(ret!=0){return ret}self.fds.push(fd_obj);const opened_fd=self.fds.length-1;buffer.setUint32(opened_fd_ptr,opened_fd,true);return 0}else {return ERRNO_BADF}},path_readlink(fd,path_ptr,path_len,buf_ptr,buf_len,nread_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));debug.log(path);const{ret,data}=self.fds[fd].path_readlink(path);if(data!=null){const data_buf=new TextEncoder().encode(data);if(data_buf.length>buf_len){buffer.setUint32(nread_ptr,0,true);return ERRNO_BADF}buffer8.set(data_buf,buf_ptr);buffer.setUint32(nread_ptr,data_buf.length,true);}return ret}else {return ERRNO_BADF}},path_remove_directory(fd,path_ptr,path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));return self.fds[fd].path_remove_directory(path)}else {return ERRNO_BADF}},path_rename(fd,old_path_ptr,old_path_len,new_fd,new_path_ptr,new_path_len){throw "FIXME what is the best abstraction for this?"},path_symlink(old_path_ptr,old_path_len,fd,new_path_ptr,new_path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const old_path=new TextDecoder("utf-8").decode(buffer8.slice(old_path_ptr,old_path_ptr+old_path_len));const new_path=new TextDecoder("utf-8").decode(buffer8.slice(new_path_ptr,new_path_ptr+new_path_len));return self.fds[fd].path_symlink(old_path,new_path)}else {return ERRNO_BADF}},path_unlink_file(fd,path_ptr,path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));return self.fds[fd].path_unlink_file(path)}else {return ERRNO_BADF}},poll_oneoff(in_,out,nsubscriptions){throw "async io not supported"},proc_exit(exit_code){throw new WASIProcExit(exit_code)},proc_raise(sig){throw "raised signal "+sig},sched_yield(){},random_get(buf,buf_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);for(let i=0;i<buf_len;i++){buffer8[buf+i]=Math.random()*256|0;}},sock_recv(fd,ri_data,ri_flags){throw "sockets not supported"},sock_send(fd,si_data,si_flags){throw "sockets not supported"},sock_shutdown(fd,how){throw "sockets not supported"},sock_accept(fd,flags){throw "sockets not supported"}};}};
|
|
11
|
+
class WASIProcExit extends Error{constructor(code){super("exit with exit code "+code);this.code=code;}}let WASI=class WASI{start(instance){this.inst=instance;try{instance.exports._start();return 0}catch(e){if(e instanceof WASIProcExit){return e.code}else {throw e}}}initialize(instance){this.inst=instance;if(instance.exports._initialize){instance.exports._initialize();}}constructor(args,env,fds,options={}){this.args=[];this.env=[];this.fds=[];debug.enable(options.debug);this.args=args;this.env=env;this.fds=fds;const self=this;this.wasiImport={args_sizes_get(argc,argv_buf_size){const buffer=new DataView(self.inst.exports.memory.buffer);buffer.setUint32(argc,self.args.length,true);let buf_size=0;for(const arg of self.args){buf_size+=arg.length+1;}buffer.setUint32(argv_buf_size,buf_size,true);debug.log(buffer.getUint32(argc,true),buffer.getUint32(argv_buf_size,true));return 0},args_get(argv,argv_buf){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);const orig_argv_buf=argv_buf;for(let i=0;i<self.args.length;i++){buffer.setUint32(argv,argv_buf,true);argv+=4;const arg=new TextEncoder().encode(self.args[i]);buffer8.set(arg,argv_buf);buffer.setUint8(argv_buf+arg.length,0);argv_buf+=arg.length+1;}if(debug.enabled){debug.log(new TextDecoder("utf-8").decode(buffer8.slice(orig_argv_buf,argv_buf)));}return 0},environ_sizes_get(environ_count,environ_size){const buffer=new DataView(self.inst.exports.memory.buffer);buffer.setUint32(environ_count,self.env.length,true);let buf_size=0;for(const environ of self.env){buf_size+=environ.length+1;}buffer.setUint32(environ_size,buf_size,true);debug.log(buffer.getUint32(environ_count,true),buffer.getUint32(environ_size,true));return 0},environ_get(environ,environ_buf){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);const orig_environ_buf=environ_buf;for(let i=0;i<self.env.length;i++){buffer.setUint32(environ,environ_buf,true);environ+=4;const e=new TextEncoder().encode(self.env[i]);buffer8.set(e,environ_buf);buffer.setUint8(environ_buf+e.length,0);environ_buf+=e.length+1;}if(debug.enabled){debug.log(new TextDecoder("utf-8").decode(buffer8.slice(orig_environ_buf,environ_buf)));}return 0},clock_res_get(id,res_ptr){let resolutionValue;switch(id){case CLOCKID_MONOTONIC:{resolutionValue=5000n;break}case CLOCKID_REALTIME:{resolutionValue=1000000n;break}default:return ERRNO_NOSYS}const view=new DataView(self.inst.exports.memory.buffer);view.setBigUint64(res_ptr,resolutionValue,true);return ERRNO_SUCCESS},clock_time_get(id,precision,time){const buffer=new DataView(self.inst.exports.memory.buffer);if(id===CLOCKID_REALTIME){buffer.setBigUint64(time,BigInt(new Date().getTime())*1000000n,true);}else if(id==CLOCKID_MONOTONIC){let monotonic_time;try{monotonic_time=BigInt(Math.round(performance.now()*1e6));}catch(e){monotonic_time=0n;}buffer.setBigUint64(time,monotonic_time,true);}else {buffer.setBigUint64(time,0n,true);}return 0},fd_advise(fd,offset,len,advice){if(self.fds[fd]!=undefined){return ERRNO_SUCCESS}else {return ERRNO_BADF}},fd_allocate(fd,offset,len){if(self.fds[fd]!=undefined){return self.fds[fd].fd_allocate(offset,len)}else {return ERRNO_BADF}},fd_close(fd){if(self.fds[fd]!=undefined){const ret=self.fds[fd].fd_close();self.fds[fd]=undefined;return ret}else {return ERRNO_BADF}},fd_datasync(fd){if(self.fds[fd]!=undefined){return self.fds[fd].fd_sync()}else {return ERRNO_BADF}},fd_fdstat_get(fd,fdstat_ptr){if(self.fds[fd]!=undefined){const{ret,fdstat}=self.fds[fd].fd_fdstat_get();if(fdstat!=null){fdstat.write_bytes(new DataView(self.inst.exports.memory.buffer),fdstat_ptr);}return ret}else {return ERRNO_BADF}},fd_fdstat_set_flags(fd,flags){if(self.fds[fd]!=undefined){return self.fds[fd].fd_fdstat_set_flags(flags)}else {return ERRNO_BADF}},fd_fdstat_set_rights(fd,fs_rights_base,fs_rights_inheriting){if(self.fds[fd]!=undefined){return self.fds[fd].fd_fdstat_set_rights(fs_rights_base,fs_rights_inheriting)}else {return ERRNO_BADF}},fd_filestat_get(fd,filestat_ptr){if(self.fds[fd]!=undefined){const{ret,filestat}=self.fds[fd].fd_filestat_get();if(filestat!=null){filestat.write_bytes(new DataView(self.inst.exports.memory.buffer),filestat_ptr);}return ret}else {return ERRNO_BADF}},fd_filestat_set_size(fd,size){if(self.fds[fd]!=undefined){return self.fds[fd].fd_filestat_set_size(size)}else {return ERRNO_BADF}},fd_filestat_set_times(fd,atim,mtim,fst_flags){if(self.fds[fd]!=undefined){return self.fds[fd].fd_filestat_set_times(atim,mtim,fst_flags)}else {return ERRNO_BADF}},fd_pread(fd,iovs_ptr,iovs_len,offset,nread_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const iovecs=Iovec.read_bytes_array(buffer,iovs_ptr,iovs_len);let nread=0;for(const iovec of iovecs){const{ret,data}=self.fds[fd].fd_pread(iovec.buf_len,offset);if(ret!=ERRNO_SUCCESS){buffer.setUint32(nread_ptr,nread,true);return ret}buffer8.set(data,iovec.buf);nread+=data.length;offset+=BigInt(data.length);if(data.length!=iovec.buf_len){break}}buffer.setUint32(nread_ptr,nread,true);return ERRNO_SUCCESS}else {return ERRNO_BADF}},fd_prestat_get(fd,buf_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const{ret,prestat}=self.fds[fd].fd_prestat_get();if(prestat!=null){prestat.write_bytes(buffer,buf_ptr);}return ret}else {return ERRNO_BADF}},fd_prestat_dir_name(fd,path_ptr,path_len){if(self.fds[fd]!=undefined){const{ret,prestat}=self.fds[fd].fd_prestat_get();if(prestat==null){return ret}const prestat_dir_name=prestat.inner.pr_name;const buffer8=new Uint8Array(self.inst.exports.memory.buffer);buffer8.set(prestat_dir_name.slice(0,path_len),path_ptr);return prestat_dir_name.byteLength>path_len?ERRNO_NAMETOOLONG:ERRNO_SUCCESS}else {return ERRNO_BADF}},fd_pwrite(fd,iovs_ptr,iovs_len,offset,nwritten_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const iovecs=Ciovec.read_bytes_array(buffer,iovs_ptr,iovs_len);let nwritten=0;for(const iovec of iovecs){const data=buffer8.slice(iovec.buf,iovec.buf+iovec.buf_len);const{ret,nwritten:nwritten_part}=self.fds[fd].fd_pwrite(data,offset);if(ret!=ERRNO_SUCCESS){buffer.setUint32(nwritten_ptr,nwritten,true);return ret}nwritten+=nwritten_part;offset+=BigInt(nwritten_part);if(nwritten_part!=data.byteLength){break}}buffer.setUint32(nwritten_ptr,nwritten,true);return ERRNO_SUCCESS}else {return ERRNO_BADF}},fd_read(fd,iovs_ptr,iovs_len,nread_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const iovecs=Iovec.read_bytes_array(buffer,iovs_ptr,iovs_len);let nread=0;for(const iovec of iovecs){const{ret,data}=self.fds[fd].fd_read(iovec.buf_len);if(ret!=ERRNO_SUCCESS){buffer.setUint32(nread_ptr,nread,true);return ret}buffer8.set(data,iovec.buf);nread+=data.length;if(data.length!=iovec.buf_len){break}}buffer.setUint32(nread_ptr,nread,true);return ERRNO_SUCCESS}else {return ERRNO_BADF}},fd_readdir(fd,buf,buf_len,cookie,bufused_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){let bufused=0;while(true){const{ret,dirent}=self.fds[fd].fd_readdir_single(cookie);if(ret!=0){buffer.setUint32(bufused_ptr,bufused,true);return ret}if(dirent==null){break}if(buf_len-bufused<dirent.head_length()){bufused=buf_len;break}const head_bytes=new ArrayBuffer(dirent.head_length());dirent.write_head_bytes(new DataView(head_bytes),0);buffer8.set(new Uint8Array(head_bytes).slice(0,Math.min(head_bytes.byteLength,buf_len-bufused)),buf);buf+=dirent.head_length();bufused+=dirent.head_length();if(buf_len-bufused<dirent.name_length()){bufused=buf_len;break}dirent.write_name_bytes(buffer8,buf,buf_len-bufused);buf+=dirent.name_length();bufused+=dirent.name_length();cookie=dirent.d_next;}buffer.setUint32(bufused_ptr,bufused,true);return 0}else {return ERRNO_BADF}},fd_renumber(fd,to){if(self.fds[fd]!=undefined&&self.fds[to]!=undefined){const ret=self.fds[to].fd_close();if(ret!=0){return ret}self.fds[to]=self.fds[fd];self.fds[fd]=undefined;return 0}else {return ERRNO_BADF}},fd_seek(fd,offset,whence,offset_out_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const{ret,offset:offset_out}=self.fds[fd].fd_seek(offset,whence);buffer.setBigInt64(offset_out_ptr,offset_out,true);return ret}else {return ERRNO_BADF}},fd_sync(fd){if(self.fds[fd]!=undefined){return self.fds[fd].fd_sync()}else {return ERRNO_BADF}},fd_tell(fd,offset_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const{ret,offset}=self.fds[fd].fd_tell();buffer.setBigUint64(offset_ptr,offset,true);return ret}else {return ERRNO_BADF}},fd_write(fd,iovs_ptr,iovs_len,nwritten_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const iovecs=Ciovec.read_bytes_array(buffer,iovs_ptr,iovs_len);let nwritten=0;for(const iovec of iovecs){const data=buffer8.slice(iovec.buf,iovec.buf+iovec.buf_len);const{ret,nwritten:nwritten_part}=self.fds[fd].fd_write(data);if(ret!=ERRNO_SUCCESS){buffer.setUint32(nwritten_ptr,nwritten,true);return ret}nwritten+=nwritten_part;if(nwritten_part!=data.byteLength){break}}buffer.setUint32(nwritten_ptr,nwritten,true);return ERRNO_SUCCESS}else {return ERRNO_BADF}},path_create_directory(fd,path_ptr,path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));return self.fds[fd].path_create_directory(path)}else {return ERRNO_BADF}},path_filestat_get(fd,flags,path_ptr,path_len,filestat_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));const{ret,filestat}=self.fds[fd].path_filestat_get(flags,path);if(filestat!=null){filestat.write_bytes(buffer,filestat_ptr);}return ret}else {return ERRNO_BADF}},path_filestat_set_times(fd,flags,path_ptr,path_len,atim,mtim,fst_flags){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));return self.fds[fd].path_filestat_set_times(flags,path,atim,mtim,fst_flags)}else {return ERRNO_BADF}},path_link(old_fd,old_flags,old_path_ptr,old_path_len,new_fd,new_path_ptr,new_path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[old_fd]!=undefined&&self.fds[new_fd]!=undefined){const old_path=new TextDecoder("utf-8").decode(buffer8.slice(old_path_ptr,old_path_ptr+old_path_len));const new_path=new TextDecoder("utf-8").decode(buffer8.slice(new_path_ptr,new_path_ptr+new_path_len));const{ret,inode_obj}=self.fds[old_fd].path_lookup(old_path,old_flags);if(inode_obj==null){return ret}return self.fds[new_fd].path_link(new_path,inode_obj,false)}else {return ERRNO_BADF}},path_open(fd,dirflags,path_ptr,path_len,oflags,fs_rights_base,fs_rights_inheriting,fd_flags,opened_fd_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));debug.log(path);const{ret,fd_obj}=self.fds[fd].path_open(dirflags,path,oflags,fs_rights_base,fs_rights_inheriting,fd_flags);if(ret!=0){return ret}self.fds.push(fd_obj);const opened_fd=self.fds.length-1;buffer.setUint32(opened_fd_ptr,opened_fd,true);return 0}else {return ERRNO_BADF}},path_readlink(fd,path_ptr,path_len,buf_ptr,buf_len,nread_ptr){const buffer=new DataView(self.inst.exports.memory.buffer);const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));debug.log(path);const{ret,data}=self.fds[fd].path_readlink(path);if(data!=null){const data_buf=new TextEncoder().encode(data);if(data_buf.length>buf_len){buffer.setUint32(nread_ptr,0,true);return ERRNO_BADF}buffer8.set(data_buf,buf_ptr);buffer.setUint32(nread_ptr,data_buf.length,true);}return ret}else {return ERRNO_BADF}},path_remove_directory(fd,path_ptr,path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));return self.fds[fd].path_remove_directory(path)}else {return ERRNO_BADF}},path_rename(fd,old_path_ptr,old_path_len,new_fd,new_path_ptr,new_path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined&&self.fds[new_fd]!=undefined){const old_path=new TextDecoder("utf-8").decode(buffer8.slice(old_path_ptr,old_path_ptr+old_path_len));const new_path=new TextDecoder("utf-8").decode(buffer8.slice(new_path_ptr,new_path_ptr+new_path_len));let{ret,inode_obj}=self.fds[fd].path_unlink(old_path);if(inode_obj==null){return ret}ret=self.fds[new_fd].path_link(new_path,inode_obj,true);if(ret!=ERRNO_SUCCESS){if(self.fds[fd].path_link(old_path,inode_obj,true)!=ERRNO_SUCCESS){throw "path_link should always return success when relinking an inode back to the original place"}}return ret}else {return ERRNO_BADF}},path_symlink(old_path_ptr,old_path_len,fd,new_path_ptr,new_path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){new TextDecoder("utf-8").decode(buffer8.slice(old_path_ptr,old_path_ptr+old_path_len));new TextDecoder("utf-8").decode(buffer8.slice(new_path_ptr,new_path_ptr+new_path_len));return ERRNO_NOTSUP}else {return ERRNO_BADF}},path_unlink_file(fd,path_ptr,path_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);if(self.fds[fd]!=undefined){const path=new TextDecoder("utf-8").decode(buffer8.slice(path_ptr,path_ptr+path_len));return self.fds[fd].path_unlink_file(path)}else {return ERRNO_BADF}},poll_oneoff(in_,out,nsubscriptions){throw "async io not supported"},proc_exit(exit_code){throw new WASIProcExit(exit_code)},proc_raise(sig){throw "raised signal "+sig},sched_yield(){},random_get(buf,buf_len){const buffer8=new Uint8Array(self.inst.exports.memory.buffer);for(let i=0;i<buf_len;i++){buffer8[buf+i]=Math.random()*256|0;}},sock_recv(fd,ri_data,ri_flags){throw "sockets not supported"},sock_send(fd,si_data,si_flags){throw "sockets not supported"},sock_shutdown(fd,how){throw "sockets not supported"},sock_accept(fd,flags){throw "sockets not supported"}};}};
|
|
12
|
+
|
|
13
|
+
class Fd{fd_allocate(offset,len){return ERRNO_NOTSUP}fd_close(){return 0}fd_fdstat_get(){return {ret:ERRNO_NOTSUP,fdstat:null}}fd_fdstat_set_flags(flags){return ERRNO_NOTSUP}fd_fdstat_set_rights(fs_rights_base,fs_rights_inheriting){return ERRNO_NOTSUP}fd_filestat_get(){return {ret:ERRNO_NOTSUP,filestat:null}}fd_filestat_set_size(size){return ERRNO_NOTSUP}fd_filestat_set_times(atim,mtim,fst_flags){return ERRNO_NOTSUP}fd_pread(size,offset){return {ret:ERRNO_NOTSUP,data:new Uint8Array}}fd_prestat_get(){return {ret:ERRNO_NOTSUP,prestat:null}}fd_pwrite(data,offset){return {ret:ERRNO_NOTSUP,nwritten:0}}fd_read(size){return {ret:ERRNO_NOTSUP,data:new Uint8Array}}fd_readdir_single(cookie){return {ret:ERRNO_NOTSUP,dirent:null}}fd_seek(offset,whence){return {ret:ERRNO_NOTSUP,offset:0n}}fd_sync(){return 0}fd_tell(){return {ret:ERRNO_NOTSUP,offset:0n}}fd_write(data){return {ret:ERRNO_NOTSUP,nwritten:0}}path_create_directory(path){return ERRNO_NOTSUP}path_filestat_get(flags,path){return {ret:ERRNO_NOTSUP,filestat:null}}path_filestat_set_times(flags,path,atim,mtim,fst_flags){return ERRNO_NOTSUP}path_link(path,inode,allow_dir){return ERRNO_NOTSUP}path_unlink(path){return {ret:ERRNO_NOTSUP,inode_obj:null}}path_lookup(path,dirflags){return {ret:ERRNO_NOTSUP,inode_obj:null}}path_open(dirflags,path,oflags,fs_rights_base,fs_rights_inheriting,fd_flags){return {ret:ERRNO_NOTDIR,fd_obj:null}}path_readlink(path){return {ret:ERRNO_NOTSUP,data:null}}path_remove_directory(path){return ERRNO_NOTSUP}path_rename(old_path,new_fd,new_path){return ERRNO_NOTSUP}path_unlink_file(path){return ERRNO_NOTSUP}}class Inode{}
|
|
14
|
+
|
|
15
|
+
class OpenFile extends Fd{fd_allocate(offset,len){if(this.file.size>offset+len);else {const new_data=new Uint8Array(Number(offset+len));new_data.set(this.file.data,0);this.file.data=new_data;}return ERRNO_SUCCESS}fd_fdstat_get(){return {ret:0,fdstat:new Fdstat(FILETYPE_REGULAR_FILE,0)}}fd_filestat_set_size(size){if(this.file.size>size){this.file.data=new Uint8Array(this.file.data.buffer.slice(0,Number(size)));}else {const new_data=new Uint8Array(Number(size));new_data.set(this.file.data,0);this.file.data=new_data;}return ERRNO_SUCCESS}fd_read(size){const slice=this.file.data.slice(Number(this.file_pos),Number(this.file_pos+BigInt(size)));this.file_pos+=BigInt(slice.length);return {ret:0,data:slice}}fd_pread(size,offset){const slice=this.file.data.slice(Number(offset),Number(offset+BigInt(size)));return {ret:0,data:slice}}fd_seek(offset,whence){let calculated_offset;switch(whence){case WHENCE_SET:calculated_offset=offset;break;case WHENCE_CUR:calculated_offset=this.file_pos+offset;break;case WHENCE_END:calculated_offset=BigInt(this.file.data.byteLength)+offset;break;default:return {ret:ERRNO_INVAL,offset:0n}}if(calculated_offset<0){return {ret:ERRNO_INVAL,offset:0n}}this.file_pos=calculated_offset;return {ret:0,offset:this.file_pos}}fd_tell(){return {ret:0,offset:this.file_pos}}fd_write(data){if(this.file.readonly)return {ret:ERRNO_BADF,nwritten:0};if(this.file_pos+BigInt(data.byteLength)>this.file.size){const old=this.file.data;this.file.data=new Uint8Array(Number(this.file_pos+BigInt(data.byteLength)));this.file.data.set(old);}this.file.data.set(data,Number(this.file_pos));this.file_pos+=BigInt(data.byteLength);return {ret:0,nwritten:data.byteLength}}fd_pwrite(data,offset){if(this.file.readonly)return {ret:ERRNO_BADF,nwritten:0};if(offset+BigInt(data.byteLength)>this.file.size){const old=this.file.data;this.file.data=new Uint8Array(Number(offset+BigInt(data.byteLength)));this.file.data.set(old);}this.file.data.set(data,Number(offset));return {ret:0,nwritten:data.byteLength}}fd_filestat_get(){return {ret:0,filestat:this.file.stat()}}constructor(file){super();this.file_pos=0n;this.file=file;}}class OpenDirectory extends Fd{fd_seek(offset,whence){return {ret:ERRNO_BADF,offset:0n}}fd_tell(){return {ret:ERRNO_BADF,offset:0n}}fd_allocate(offset,len){return ERRNO_BADF}fd_fdstat_get(){return {ret:0,fdstat:new Fdstat(FILETYPE_DIRECTORY,0)}}fd_readdir_single(cookie){if(debug.enabled){debug.log("readdir_single",cookie);debug.log(cookie,this.dir.contents.keys());}if(cookie==0n){return {ret:ERRNO_SUCCESS,dirent:new Dirent(1n,".",FILETYPE_DIRECTORY)}}else if(cookie==1n){return {ret:ERRNO_SUCCESS,dirent:new Dirent(2n,"..",FILETYPE_DIRECTORY)}}if(cookie>=BigInt(this.dir.contents.size)+2n){return {ret:0,dirent:null}}const[name,entry]=Array.from(this.dir.contents.entries())[Number(cookie-2n)];return {ret:0,dirent:new Dirent(cookie+1n,name,entry.stat().filetype)}}path_filestat_get(flags,path_str){const{ret:path_err,path}=Path.from(path_str);if(path==null){return {ret:path_err,filestat:null}}const{ret,entry}=this.dir.get_entry_for_path(path);if(entry==null){return {ret,filestat:null}}return {ret:0,filestat:entry.stat()}}path_lookup(path_str,dirflags){const{ret:path_ret,path}=Path.from(path_str);if(path==null){return {ret:path_ret,inode_obj:null}}const{ret,entry}=this.dir.get_entry_for_path(path);if(entry==null){return {ret,inode_obj:null}}return {ret:ERRNO_SUCCESS,inode_obj:entry}}path_open(dirflags,path_str,oflags,fs_rights_base,fs_rights_inheriting,fd_flags){const{ret:path_ret,path}=Path.from(path_str);if(path==null){return {ret:path_ret,fd_obj:null}}let{ret,entry}=this.dir.get_entry_for_path(path);if(entry==null){if(ret!=ERRNO_NOENT){return {ret,fd_obj:null}}if((oflags&OFLAGS_CREAT)==OFLAGS_CREAT){const{ret,entry:new_entry}=this.dir.create_entry_for_path(path_str,(oflags&OFLAGS_DIRECTORY)==OFLAGS_DIRECTORY);if(new_entry==null){return {ret,fd_obj:null}}entry=new_entry;}else {return {ret:ERRNO_NOENT,fd_obj:null}}}else if((oflags&OFLAGS_EXCL)==OFLAGS_EXCL){return {ret:ERRNO_EXIST,fd_obj:null}}if((oflags&OFLAGS_DIRECTORY)==OFLAGS_DIRECTORY&&entry.stat().filetype!==FILETYPE_DIRECTORY){return {ret:ERRNO_NOTDIR,fd_obj:null}}return entry.path_open(oflags,fs_rights_base,fd_flags)}path_create_directory(path){return this.path_open(0,path,OFLAGS_CREAT|OFLAGS_DIRECTORY,0n,0n,0).ret}path_link(path_str,inode,allow_dir){const{ret:path_ret,path}=Path.from(path_str);if(path==null){return path_ret}if(path.is_dir){return ERRNO_NOENT}const{ret:parent_ret,parent_entry,filename,entry}=this.dir.get_parent_dir_and_entry_for_path(path,true);if(parent_entry==null||filename==null){return parent_ret}if(entry!=null){const source_is_dir=inode.stat().filetype==FILETYPE_DIRECTORY;const target_is_dir=entry.stat().filetype==FILETYPE_DIRECTORY;if(source_is_dir&&target_is_dir){if(allow_dir&&entry instanceof Directory){if(entry.contents.size==0);else {return ERRNO_NOTEMPTY}}else {return ERRNO_EXIST}}else if(source_is_dir&&!target_is_dir){return ERRNO_NOTDIR}else if(!source_is_dir&&target_is_dir){return ERRNO_ISDIR}else if(inode.stat().filetype==FILETYPE_REGULAR_FILE&&entry.stat().filetype==FILETYPE_REGULAR_FILE);else {return ERRNO_EXIST}}if(!allow_dir&&inode.stat().filetype==FILETYPE_DIRECTORY){return ERRNO_PERM}parent_entry.contents.set(filename,inode);return ERRNO_SUCCESS}path_unlink(path_str){const{ret:path_ret,path}=Path.from(path_str);if(path==null){return {ret:path_ret,inode_obj:null}}const{ret:parent_ret,parent_entry,filename,entry}=this.dir.get_parent_dir_and_entry_for_path(path,true);if(parent_entry==null||filename==null){return {ret:parent_ret,inode_obj:null}}if(entry==null){return {ret:ERRNO_NOENT,inode_obj:null}}parent_entry.contents.delete(filename);return {ret:ERRNO_SUCCESS,inode_obj:entry}}path_unlink_file(path_str){const{ret:path_ret,path}=Path.from(path_str);if(path==null){return path_ret}const{ret:parent_ret,parent_entry,filename,entry}=this.dir.get_parent_dir_and_entry_for_path(path,false);if(parent_entry==null||filename==null||entry==null){return parent_ret}if(entry.stat().filetype===FILETYPE_DIRECTORY){return ERRNO_ISDIR}parent_entry.contents.delete(filename);return ERRNO_SUCCESS}path_remove_directory(path_str){const{ret:path_ret,path}=Path.from(path_str);if(path==null){return path_ret}const{ret:parent_ret,parent_entry,filename,entry}=this.dir.get_parent_dir_and_entry_for_path(path,false);if(parent_entry==null||filename==null||entry==null){return parent_ret}if(!(entry instanceof Directory)||entry.stat().filetype!==FILETYPE_DIRECTORY){return ERRNO_NOTDIR}if(entry.contents.size!==0){return ERRNO_NOTEMPTY}if(!parent_entry.contents.delete(filename)){return ERRNO_NOENT}return ERRNO_SUCCESS}fd_filestat_get(){return {ret:0,filestat:this.dir.stat()}}fd_filestat_set_size(size){return ERRNO_BADF}fd_read(size){return {ret:ERRNO_BADF,data:new Uint8Array}}fd_pread(size,offset){return {ret:ERRNO_BADF,data:new Uint8Array}}fd_write(data){return {ret:ERRNO_BADF,nwritten:0}}fd_pwrite(data,offset){return {ret:ERRNO_BADF,nwritten:0}}constructor(dir){super();this.dir=dir;}}class PreopenDirectory extends OpenDirectory{fd_prestat_get(){return {ret:0,prestat:Prestat.dir(this.prestat_name)}}constructor(name,contents){super(new Directory(contents));this.prestat_name=name;}}class File extends Inode{path_open(oflags,fs_rights_base,fd_flags){if(this.readonly&&(fs_rights_base&BigInt(RIGHTS_FD_WRITE))==BigInt(RIGHTS_FD_WRITE)){return {ret:ERRNO_PERM,fd_obj:null}}if((oflags&OFLAGS_TRUNC)==OFLAGS_TRUNC){if(this.readonly)return {ret:ERRNO_PERM,fd_obj:null};this.data=new Uint8Array([]);}const file=new OpenFile(this);if(fd_flags&FDFLAGS_APPEND)file.fd_seek(0n,WHENCE_END);return {ret:ERRNO_SUCCESS,fd_obj:file}}get size(){return BigInt(this.data.byteLength)}stat(){return new Filestat(FILETYPE_REGULAR_FILE,this.size)}constructor(data,options){super();this.data=new Uint8Array(data);this.readonly=!!options?.readonly;}}let Path=class Path{static from(path){const self=new Path;self.is_dir=path.endsWith("/");if(path.startsWith("/")){return {ret:ERRNO_NOTCAPABLE,path:null}}if(path.includes("\x00")){return {ret:ERRNO_INVAL,path:null}}for(const component of path.split("/")){if(component===""||component==="."){continue}if(component===".."){if(self.parts.pop()==undefined){return {ret:ERRNO_NOTCAPABLE,path:null}}continue}self.parts.push(component);}return {ret:ERRNO_SUCCESS,path:self}}to_path_string(){let s=this.parts.join("/");if(this.is_dir){s+="/";}return s}constructor(){this.parts=[];this.is_dir=false;}};class Directory extends Inode{path_open(oflags,fs_rights_base,fd_flags){return {ret:ERRNO_SUCCESS,fd_obj:new OpenDirectory(this)}}stat(){return new Filestat(FILETYPE_DIRECTORY,0n)}get_entry_for_path(path){let entry=this;for(const component of path.parts){if(!(entry instanceof Directory)){return {ret:ERRNO_NOTDIR,entry:null}}const child=entry.contents.get(component);if(child!==undefined){entry=child;}else {debug.log(component);return {ret:ERRNO_NOENT,entry:null}}}if(path.is_dir){if(entry.stat().filetype!=FILETYPE_DIRECTORY){return {ret:ERRNO_NOTDIR,entry:null}}}return {ret:ERRNO_SUCCESS,entry}}get_parent_dir_and_entry_for_path(path,allow_undefined){const filename=path.parts.pop();if(filename===undefined){return {ret:ERRNO_INVAL,parent_entry:null,filename:null,entry:null}}const{ret:entry_ret,entry:parent_entry}=this.get_entry_for_path(path);if(parent_entry==null){return {ret:entry_ret,parent_entry:null,filename:null,entry:null}}if(!(parent_entry instanceof Directory)){return {ret:ERRNO_NOTDIR,parent_entry:null,filename:null,entry:null}}const entry=parent_entry.contents.get(filename);if(entry===undefined){if(!allow_undefined){return {ret:ERRNO_NOENT,parent_entry:null,filename:null,entry:null}}else {return {ret:ERRNO_SUCCESS,parent_entry,filename,entry:null}}}if(path.is_dir){if(entry.stat().filetype!=FILETYPE_DIRECTORY){return {ret:ERRNO_NOTDIR,parent_entry:null,filename:null,entry:null}}}return {ret:ERRNO_SUCCESS,parent_entry,filename,entry}}create_entry_for_path(path_str,is_dir){const{ret:path_ret,path}=Path.from(path_str);if(path==null){return {ret:path_ret,entry:null}}let{ret:parent_ret,parent_entry,filename,entry}=this.get_parent_dir_and_entry_for_path(path,true);if(parent_entry==null||filename==null){return {ret:parent_ret,entry:null}}if(entry!=null){return {ret:ERRNO_EXIST,entry:null}}debug.log("create",path);let new_child;if(!is_dir){new_child=new File(new ArrayBuffer(0));}else {new_child=new Directory(new Map);}parent_entry.contents.set(filename,new_child);entry=new_child;return {ret:ERRNO_SUCCESS,entry}}constructor(contents){super();if(contents instanceof Array){this.contents=new Map(contents);}else {this.contents=contents;}}}
|
|
12
16
|
|
|
13
17
|
/**
|
|
14
18
|
* Create a console printer that can be used as an overlay of WASI imports.
|
|
@@ -506,13 +510,13 @@
|
|
|
506
510
|
data_view(memory).setInt32(arg1 + 4, len0, true);
|
|
507
511
|
data_view(memory).setInt32(arg1 + 0, ptr0, true);
|
|
508
512
|
};
|
|
509
|
-
imports["rb-js-abi-host"]["js-value-to-integer: func(value: handle<js-abi-value>) -> variant {
|
|
513
|
+
imports["rb-js-abi-host"]["js-value-to-integer: func(value: handle<js-abi-value>) -> variant { as-float(float64), bignum(string) }"] = function(arg0, arg1) {
|
|
510
514
|
const memory = get_export("memory");
|
|
511
515
|
const realloc = get_export("cabi_realloc");
|
|
512
516
|
const ret0 = obj.jsValueToInteger(resources0.get(arg0));
|
|
513
517
|
const variant1 = ret0;
|
|
514
518
|
switch (variant1.tag) {
|
|
515
|
-
case "
|
|
519
|
+
case "as-float": {
|
|
516
520
|
const e = variant1.val;
|
|
517
521
|
data_view(memory).setInt8(arg1 + 0, 0, true);
|
|
518
522
|
data_view(memory).setFloat64(arg1 + 8, +e, true);
|
|
@@ -708,6 +712,72 @@
|
|
|
708
712
|
};
|
|
709
713
|
}
|
|
710
714
|
|
|
715
|
+
class LegacyBinding extends RbAbiGuest {
|
|
716
|
+
async setInstance(instance) {
|
|
717
|
+
await this.instantiate(instance);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
class ComponentBinding {
|
|
721
|
+
constructor() { }
|
|
722
|
+
setUnderlying(underlying) {
|
|
723
|
+
this.underlying = underlying;
|
|
724
|
+
}
|
|
725
|
+
rubyShowVersion() {
|
|
726
|
+
this.underlying.rubyShowVersion();
|
|
727
|
+
}
|
|
728
|
+
rubyInit() {
|
|
729
|
+
this.underlying.rubyInit();
|
|
730
|
+
}
|
|
731
|
+
rubySysinit(args) {
|
|
732
|
+
this.underlying.rubySysinit(args);
|
|
733
|
+
}
|
|
734
|
+
rubyOptions(args) {
|
|
735
|
+
this.underlying.rubyOptions(args);
|
|
736
|
+
}
|
|
737
|
+
rubyScript(name) {
|
|
738
|
+
this.underlying.rubyScript(name);
|
|
739
|
+
}
|
|
740
|
+
rubyInitLoadpath() {
|
|
741
|
+
this.underlying.rubyInitLoadpath();
|
|
742
|
+
}
|
|
743
|
+
rbEvalStringProtect(str) {
|
|
744
|
+
return this.underlying.rbEvalStringProtect(str);
|
|
745
|
+
}
|
|
746
|
+
rbFuncallvProtect(recv, mid, args) {
|
|
747
|
+
return this.underlying.rbFuncallvProtect(recv, mid, args);
|
|
748
|
+
}
|
|
749
|
+
rbIntern(name) {
|
|
750
|
+
return this.underlying.rbIntern(name);
|
|
751
|
+
}
|
|
752
|
+
rbErrinfo() {
|
|
753
|
+
return this.underlying.rbErrinfo();
|
|
754
|
+
}
|
|
755
|
+
rbClearErrinfo() {
|
|
756
|
+
return this.underlying.rbClearErrinfo();
|
|
757
|
+
}
|
|
758
|
+
rstringPtr(value) {
|
|
759
|
+
return this.underlying.rstringPtr(value);
|
|
760
|
+
}
|
|
761
|
+
rbVmBugreport() {
|
|
762
|
+
this.underlying.rbVmBugreport();
|
|
763
|
+
}
|
|
764
|
+
rbGcEnable() {
|
|
765
|
+
return this.underlying.rbGcEnable();
|
|
766
|
+
}
|
|
767
|
+
rbGcDisable() {
|
|
768
|
+
return this.underlying.rbGcDisable();
|
|
769
|
+
}
|
|
770
|
+
rbSetShouldProhibitRewind(newValue) {
|
|
771
|
+
return this.underlying.rbSetShouldProhibitRewind(newValue);
|
|
772
|
+
}
|
|
773
|
+
async setInstance(instance) {
|
|
774
|
+
// No-op
|
|
775
|
+
}
|
|
776
|
+
addToImports(imports) {
|
|
777
|
+
// No-op
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
|
|
711
781
|
/**
|
|
712
782
|
* A Ruby VM instance
|
|
713
783
|
*
|
|
@@ -728,7 +798,7 @@
|
|
|
728
798
|
*
|
|
729
799
|
*/
|
|
730
800
|
class RubyVM {
|
|
731
|
-
constructor() {
|
|
801
|
+
constructor(binding) {
|
|
732
802
|
this.instance = null;
|
|
733
803
|
this.interfaceState = {
|
|
734
804
|
hasJSFrameAfterRbFrame: false,
|
|
@@ -737,6 +807,7 @@
|
|
|
737
807
|
// if the call stack has sandwitched JS frames like JS -> Ruby -> JS -> Ruby.
|
|
738
808
|
const proxyExports = (exports) => {
|
|
739
809
|
const excludedMethods = [
|
|
810
|
+
"setInstance",
|
|
740
811
|
"addToImports",
|
|
741
812
|
"instantiate",
|
|
742
813
|
"rbSetShouldProhibitRewind",
|
|
@@ -771,10 +842,34 @@
|
|
|
771
842
|
}
|
|
772
843
|
return exports;
|
|
773
844
|
};
|
|
774
|
-
this.guest = proxyExports(new
|
|
845
|
+
this.guest = proxyExports(binding !== null && binding !== void 0 ? binding : new LegacyBinding());
|
|
775
846
|
this.transport = new JsValueTransport();
|
|
776
847
|
this.exceptionFormatter = new RbExceptionFormatter();
|
|
777
848
|
}
|
|
849
|
+
static async _instantiate(initComponent, options) {
|
|
850
|
+
const binding = new ComponentBinding();
|
|
851
|
+
const vm = new RubyVM(binding);
|
|
852
|
+
class JsAbiValue {
|
|
853
|
+
constructor(underlying) {
|
|
854
|
+
this.underlying = underlying;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
const imports = vm.getImports((from) => new JsAbiValue(from), (to) => to.underlying);
|
|
858
|
+
const component = await initComponent(Object.assign(Object.assign({}, imports), { throwProhibitRewindException: (message) => {
|
|
859
|
+
vm.throwProhibitRewindException(message);
|
|
860
|
+
}, procToJsFunction: () => {
|
|
861
|
+
const rbValue = new RbValue(component.exportRbValueToJs(), vm, vm.privateObject());
|
|
862
|
+
return new JsAbiValue((...args) => {
|
|
863
|
+
return rbValue.call("call", ...args.map((arg) => vm.wrap(arg))).toJS();
|
|
864
|
+
});
|
|
865
|
+
}, rbObjectToJsRbValue: () => {
|
|
866
|
+
const rbValue = new RbValue(component.exportRbValueToJs(), vm, vm.privateObject());
|
|
867
|
+
return new JsAbiValue(rbValue);
|
|
868
|
+
}, JsAbiValue: JsAbiValue }));
|
|
869
|
+
binding.setUnderlying(component);
|
|
870
|
+
vm.initialize(options.args);
|
|
871
|
+
return vm;
|
|
872
|
+
}
|
|
778
873
|
/**
|
|
779
874
|
* Initialize the Ruby VM with the given command line arguments
|
|
780
875
|
* @param args The command line arguments to pass to Ruby. Must be
|
|
@@ -798,7 +893,7 @@
|
|
|
798
893
|
*/
|
|
799
894
|
async setInstance(instance) {
|
|
800
895
|
this.instance = instance;
|
|
801
|
-
await this.guest.
|
|
896
|
+
await this.guest.setInstance(instance);
|
|
802
897
|
}
|
|
803
898
|
/**
|
|
804
899
|
* Add intrinsic import entries, which is necessary to interact JavaScript
|
|
@@ -807,43 +902,36 @@
|
|
|
807
902
|
*/
|
|
808
903
|
addToImports(imports) {
|
|
809
904
|
this.guest.addToImports(imports);
|
|
810
|
-
function wrapTry(f) {
|
|
811
|
-
return (...args) => {
|
|
812
|
-
try {
|
|
813
|
-
return { tag: "success", val: f(...args) };
|
|
814
|
-
}
|
|
815
|
-
catch (e) {
|
|
816
|
-
if (e instanceof RbFatalError) {
|
|
817
|
-
// RbFatalError should not be caught by Ruby because it Ruby VM
|
|
818
|
-
// can be already in an inconsistent state.
|
|
819
|
-
throw e;
|
|
820
|
-
}
|
|
821
|
-
return { tag: "failure", val: e };
|
|
822
|
-
}
|
|
823
|
-
};
|
|
824
|
-
}
|
|
825
905
|
imports["rb-js-abi-host"] = {
|
|
826
906
|
rb_wasm_throw_prohibit_rewind_exception: (messagePtr, messageLen) => {
|
|
827
907
|
const memory = this.instance.exports.memory;
|
|
828
908
|
const str = new TextDecoder().decode(new Uint8Array(memory.buffer, messagePtr, messageLen));
|
|
829
|
-
|
|
830
|
-
`(${str})\n` +
|
|
831
|
-
"Nested VM operation means that the call stack has sandwitched JS frames like JS -> Ruby -> JS -> Ruby " +
|
|
832
|
-
"caused by something like `window.rubyVM.eval(\"JS.global[:rubyVM].eval('Fiber.yield')\")`\n" +
|
|
833
|
-
"\n" +
|
|
834
|
-
"Please check your call stack and make sure that you are **not** doing any of the following inside the nested Ruby frame:\n" +
|
|
835
|
-
" 1. Switching fibers (e.g. Fiber#resume, Fiber.yield, and Fiber#transfer)\n" +
|
|
836
|
-
" Note that `evalAsync` JS API switches fibers internally\n" +
|
|
837
|
-
" 2. Raising uncaught exceptions\n" +
|
|
838
|
-
" Please catch all exceptions inside the nested operation\n" +
|
|
839
|
-
" 3. Calling Continuation APIs\n";
|
|
840
|
-
const error = new RbValue(this.guest.rbErrinfo(), this, this.privateObject());
|
|
841
|
-
if (error.call("nil?").toString() === "false") {
|
|
842
|
-
message += "\n" + this.exceptionFormatter.format(error, this, this.privateObject());
|
|
843
|
-
}
|
|
844
|
-
throw new RbFatalError(message);
|
|
909
|
+
this.throwProhibitRewindException(str);
|
|
845
910
|
},
|
|
846
911
|
};
|
|
912
|
+
addRbJsAbiHostToImports(imports, this.getImports((value) => value, (value) => value), (name) => {
|
|
913
|
+
return this.instance.exports[name];
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
throwProhibitRewindException(str) {
|
|
917
|
+
let message = "Ruby APIs that may rewind the VM stack are prohibited under nested VM operation " +
|
|
918
|
+
`(${str})\n` +
|
|
919
|
+
"Nested VM operation means that the call stack has sandwitched JS frames like JS -> Ruby -> JS -> Ruby " +
|
|
920
|
+
"caused by something like `window.rubyVM.eval(\"JS.global[:rubyVM].eval('Fiber.yield')\")`\n" +
|
|
921
|
+
"\n" +
|
|
922
|
+
"Please check your call stack and make sure that you are **not** doing any of the following inside the nested Ruby frame:\n" +
|
|
923
|
+
" 1. Switching fibers (e.g. Fiber#resume, Fiber.yield, and Fiber#transfer)\n" +
|
|
924
|
+
" Note that `evalAsync` JS API switches fibers internally\n" +
|
|
925
|
+
" 2. Raising uncaught exceptions\n" +
|
|
926
|
+
" Please catch all exceptions inside the nested operation\n" +
|
|
927
|
+
" 3. Calling Continuation APIs\n";
|
|
928
|
+
const error = new RbValue(this.guest.rbErrinfo(), this, this.privateObject());
|
|
929
|
+
if (error.call("nil?").toString() === "false") {
|
|
930
|
+
message += "\n" + this.exceptionFormatter.format(error, this, this.privateObject());
|
|
931
|
+
}
|
|
932
|
+
throw new RbFatalError(message);
|
|
933
|
+
}
|
|
934
|
+
getImports(toJSAbiValue, fromJSAbiValue) {
|
|
847
935
|
// NOTE: The GC may collect objects that are still referenced by Wasm
|
|
848
936
|
// locals because Asyncify cannot scan the Wasm stack above the JS frame.
|
|
849
937
|
// So we need to keep track whether the JS frame is sandwitched by Ruby
|
|
@@ -862,9 +950,24 @@
|
|
|
862
950
|
}
|
|
863
951
|
return imports;
|
|
864
952
|
};
|
|
865
|
-
|
|
953
|
+
function wrapTry(f) {
|
|
954
|
+
return (...args) => {
|
|
955
|
+
try {
|
|
956
|
+
return { tag: "success", val: f(...args) };
|
|
957
|
+
}
|
|
958
|
+
catch (e) {
|
|
959
|
+
if (e instanceof RbFatalError) {
|
|
960
|
+
// RbFatalError should not be caught by Ruby because it Ruby VM
|
|
961
|
+
// can be already in an inconsistent state.
|
|
962
|
+
throw e;
|
|
963
|
+
}
|
|
964
|
+
return { tag: "failure", val: toJSAbiValue(e) };
|
|
965
|
+
}
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
return proxyImports({
|
|
866
969
|
evalJs: wrapTry((code) => {
|
|
867
|
-
return Function(code)();
|
|
970
|
+
return toJSAbiValue(Function(code)());
|
|
868
971
|
}),
|
|
869
972
|
isJs: (value) => {
|
|
870
973
|
// Just for compatibility with the old JS API
|
|
@@ -872,45 +975,47 @@
|
|
|
872
975
|
},
|
|
873
976
|
globalThis: () => {
|
|
874
977
|
if (typeof globalThis !== "undefined") {
|
|
875
|
-
return globalThis;
|
|
978
|
+
return toJSAbiValue(globalThis);
|
|
876
979
|
}
|
|
877
980
|
else if (typeof global !== "undefined") {
|
|
878
|
-
return global;
|
|
981
|
+
return toJSAbiValue(global);
|
|
879
982
|
}
|
|
880
983
|
else if (typeof window !== "undefined") {
|
|
881
|
-
return window;
|
|
984
|
+
return toJSAbiValue(window);
|
|
882
985
|
}
|
|
883
986
|
throw new Error("unable to locate global object");
|
|
884
987
|
},
|
|
885
988
|
intToJsNumber: (value) => {
|
|
886
|
-
return value;
|
|
989
|
+
return toJSAbiValue(value);
|
|
887
990
|
},
|
|
888
991
|
floatToJsNumber: (value) => {
|
|
889
|
-
return value;
|
|
992
|
+
return toJSAbiValue(value);
|
|
890
993
|
},
|
|
891
994
|
stringToJsString: (value) => {
|
|
892
|
-
return value;
|
|
995
|
+
return toJSAbiValue(value);
|
|
893
996
|
},
|
|
894
997
|
boolToJsBool: (value) => {
|
|
895
|
-
return value;
|
|
998
|
+
return toJSAbiValue(value);
|
|
896
999
|
},
|
|
897
1000
|
procToJsFunction: (rawRbAbiValue) => {
|
|
898
1001
|
const rbValue = this.rbValueOfPointer(rawRbAbiValue);
|
|
899
|
-
return (...args) => {
|
|
1002
|
+
return toJSAbiValue((...args) => {
|
|
900
1003
|
return rbValue.call("call", ...args.map((arg) => this.wrap(arg))).toJS();
|
|
901
|
-
};
|
|
1004
|
+
});
|
|
902
1005
|
},
|
|
903
1006
|
rbObjectToJsRbValue: (rawRbAbiValue) => {
|
|
904
|
-
return this.rbValueOfPointer(rawRbAbiValue);
|
|
1007
|
+
return toJSAbiValue(this.rbValueOfPointer(rawRbAbiValue));
|
|
905
1008
|
},
|
|
906
1009
|
jsValueToString: (value) => {
|
|
1010
|
+
value = fromJSAbiValue(value);
|
|
907
1011
|
// According to the [spec](https://tc39.es/ecma262/multipage/text-processing.html#sec-string-constructor-string-value)
|
|
908
1012
|
// `String(value)` always returns a string.
|
|
909
1013
|
return String(value);
|
|
910
1014
|
},
|
|
911
1015
|
jsValueToInteger(value) {
|
|
1016
|
+
value = fromJSAbiValue(value);
|
|
912
1017
|
if (typeof value === "number") {
|
|
913
|
-
return { tag: "
|
|
1018
|
+
return { tag: "as-float", val: value };
|
|
914
1019
|
}
|
|
915
1020
|
else if (typeof value === "bigint") {
|
|
916
1021
|
return { tag: "bignum", val: BigInt(value).toString(10) + "\0" };
|
|
@@ -919,38 +1024,40 @@
|
|
|
919
1024
|
return { tag: "bignum", val: value + "\0" };
|
|
920
1025
|
}
|
|
921
1026
|
else if (typeof value === "undefined") {
|
|
922
|
-
return { tag: "
|
|
1027
|
+
return { tag: "as-float", val: 0 };
|
|
923
1028
|
}
|
|
924
1029
|
else {
|
|
925
|
-
return { tag: "
|
|
1030
|
+
return { tag: "as-float", val: Number(value) };
|
|
926
1031
|
}
|
|
927
1032
|
},
|
|
928
1033
|
exportJsValueToHost: (value) => {
|
|
929
1034
|
// See `JsValueExporter` for the reason why we need to do this
|
|
930
|
-
this.transport.takeJsValue(value);
|
|
1035
|
+
this.transport.takeJsValue(fromJSAbiValue(value));
|
|
931
1036
|
},
|
|
932
1037
|
importJsValueFromHost: () => {
|
|
933
|
-
return this.transport.consumeJsValue();
|
|
1038
|
+
return toJSAbiValue(this.transport.consumeJsValue());
|
|
934
1039
|
},
|
|
935
1040
|
instanceOf: (value, klass) => {
|
|
1041
|
+
klass = fromJSAbiValue(klass);
|
|
936
1042
|
if (typeof klass === "function") {
|
|
937
|
-
return value instanceof klass;
|
|
1043
|
+
return fromJSAbiValue(value) instanceof klass;
|
|
938
1044
|
}
|
|
939
1045
|
else {
|
|
940
1046
|
return false;
|
|
941
1047
|
}
|
|
942
1048
|
},
|
|
943
1049
|
jsValueTypeof(value) {
|
|
944
|
-
return typeof value;
|
|
1050
|
+
return typeof fromJSAbiValue(value);
|
|
945
1051
|
},
|
|
946
1052
|
jsValueEqual(lhs, rhs) {
|
|
947
|
-
return lhs == rhs;
|
|
1053
|
+
return fromJSAbiValue(lhs) == fromJSAbiValue(rhs);
|
|
948
1054
|
},
|
|
949
1055
|
jsValueStrictlyEqual(lhs, rhs) {
|
|
950
|
-
return lhs === rhs;
|
|
1056
|
+
return fromJSAbiValue(lhs) === fromJSAbiValue(rhs);
|
|
951
1057
|
},
|
|
952
1058
|
reflectApply: wrapTry((target, thisArgument, args) => {
|
|
953
|
-
|
|
1059
|
+
const jsArgs = args.map((arg) => fromJSAbiValue(arg));
|
|
1060
|
+
return toJSAbiValue(Reflect.apply(fromJSAbiValue(target), fromJSAbiValue(thisArgument), jsArgs));
|
|
954
1061
|
}),
|
|
955
1062
|
reflectConstruct: function (target, args) {
|
|
956
1063
|
throw new Error("Function not implemented.");
|
|
@@ -959,7 +1066,7 @@
|
|
|
959
1066
|
throw new Error("Function not implemented.");
|
|
960
1067
|
},
|
|
961
1068
|
reflectGet: wrapTry((target, propertyKey) => {
|
|
962
|
-
return target[propertyKey];
|
|
1069
|
+
return toJSAbiValue(fromJSAbiValue(target)[propertyKey]);
|
|
963
1070
|
}),
|
|
964
1071
|
reflectGetOwnPropertyDescriptor: function (target, propertyKey) {
|
|
965
1072
|
throw new Error("Function not implemented.");
|
|
@@ -980,13 +1087,11 @@
|
|
|
980
1087
|
throw new Error("Function not implemented.");
|
|
981
1088
|
},
|
|
982
1089
|
reflectSet: wrapTry((target, propertyKey, value) => {
|
|
983
|
-
return Reflect.set(target, propertyKey, value);
|
|
1090
|
+
return toJSAbiValue(Reflect.set(fromJSAbiValue(target), propertyKey, fromJSAbiValue(value)));
|
|
984
1091
|
}),
|
|
985
1092
|
reflectSetPrototypeOf: function (target, prototype) {
|
|
986
1093
|
throw new Error("Function not implemented.");
|
|
987
1094
|
},
|
|
988
|
-
}), (name) => {
|
|
989
|
-
return this.instance.exports[name];
|
|
990
1095
|
});
|
|
991
1096
|
}
|
|
992
1097
|
/**
|
|
@@ -1319,7 +1424,12 @@
|
|
|
1319
1424
|
}
|
|
1320
1425
|
// All JS exceptions triggered by Ruby code are translated to Ruby exceptions,
|
|
1321
1426
|
// so non-RbError exceptions are unexpected.
|
|
1322
|
-
|
|
1427
|
+
try {
|
|
1428
|
+
vm.guest.rbVmBugreport();
|
|
1429
|
+
}
|
|
1430
|
+
catch (e) {
|
|
1431
|
+
console.error("Tried to report internal Ruby VM state but failed: ", e);
|
|
1432
|
+
}
|
|
1323
1433
|
if (e instanceof WebAssembly.RuntimeError && e.message === "unreachable") {
|
|
1324
1434
|
const error = new RbError(`Something went wrong in Ruby VM: ${e}`);
|
|
1325
1435
|
error.stack = e.stack;
|
|
@@ -1385,7 +1495,12 @@
|
|
|
1385
1495
|
var _a, _b;
|
|
1386
1496
|
const args = [];
|
|
1387
1497
|
const env = Object.entries((_a = options.env) !== null && _a !== void 0 ? _a : {}).map(([k, v]) => `${k}=${v}`);
|
|
1388
|
-
const fds = [
|
|
1498
|
+
const fds = [
|
|
1499
|
+
new OpenFile(new File([])),
|
|
1500
|
+
new OpenFile(new File([])),
|
|
1501
|
+
new OpenFile(new File([])),
|
|
1502
|
+
new PreopenDirectory("/", new Map()),
|
|
1503
|
+
];
|
|
1389
1504
|
const wasi = new WASI(args, env, fds, { debug: false });
|
|
1390
1505
|
const vm = new RubyVM();
|
|
1391
1506
|
const imports = {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export namespace RubyJsJsRuntime {
|
|
2
|
+
export function evalJs(code: string): JsAbiResult;
|
|
3
|
+
export function isJs(value: JsAbiValue): boolean;
|
|
4
|
+
export function instanceOf(value: JsAbiValue, klass: JsAbiValue): boolean;
|
|
5
|
+
export function globalThis(): JsAbiValue;
|
|
6
|
+
export function intToJsNumber(value: number): JsAbiValue;
|
|
7
|
+
export function floatToJsNumber(value: number): JsAbiValue;
|
|
8
|
+
export function stringToJsString(value: string): JsAbiValue;
|
|
9
|
+
export function boolToJsBool(value: boolean): JsAbiValue;
|
|
10
|
+
export function procToJsFunction(): JsAbiValue;
|
|
11
|
+
export function rbObjectToJsRbValue(): JsAbiValue;
|
|
12
|
+
export function jsValueToString(value: JsAbiValue): string;
|
|
13
|
+
export function jsValueToInteger(value: JsAbiValue): RawInteger;
|
|
14
|
+
export function exportJsValueToHost(value: JsAbiValue): void;
|
|
15
|
+
export function importJsValueFromHost(): JsAbiValue;
|
|
16
|
+
export function jsValueTypeof(value: JsAbiValue): string;
|
|
17
|
+
export function jsValueEqual(lhs: JsAbiValue, rhs: JsAbiValue): boolean;
|
|
18
|
+
export function jsValueStrictlyEqual(lhs: JsAbiValue, rhs: JsAbiValue): boolean;
|
|
19
|
+
export function reflectApply(target: JsAbiValue, thisArgument: JsAbiValue, arguments: JsAbiValue[]): JsAbiResult;
|
|
20
|
+
export function reflectGet(target: JsAbiValue, propertyKey: string): JsAbiResult;
|
|
21
|
+
export function reflectSet(target: JsAbiValue, propertyKey: string, value: JsAbiValue): JsAbiResult;
|
|
22
|
+
export function throwProhibitRewindException(message: string): void;
|
|
23
|
+
export { JsAbiValue };
|
|
24
|
+
}
|
|
25
|
+
export type JsAbiResult = JsAbiResultSuccess | JsAbiResultFailure;
|
|
26
|
+
export interface JsAbiResultSuccess {
|
|
27
|
+
tag: 'success',
|
|
28
|
+
val: JsAbiValue,
|
|
29
|
+
}
|
|
30
|
+
export interface JsAbiResultFailure {
|
|
31
|
+
tag: 'failure',
|
|
32
|
+
val: JsAbiValue,
|
|
33
|
+
}
|
|
34
|
+
export type RawInteger = RawIntegerAsFloat | RawIntegerBignum;
|
|
35
|
+
export interface RawIntegerAsFloat {
|
|
36
|
+
tag: 'as-float',
|
|
37
|
+
val: number,
|
|
38
|
+
}
|
|
39
|
+
export interface RawIntegerBignum {
|
|
40
|
+
tag: 'bignum',
|
|
41
|
+
val: string,
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export class JsAbiValue {
|
|
45
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export namespace RubyJsRubyRuntime {
|
|
2
|
+
export function rubyShowVersion(): void;
|
|
3
|
+
export function rubyInit(): void;
|
|
4
|
+
export function rubySysinit(args: string[]): void;
|
|
5
|
+
export function rubyOptions(args: string[]): RbIseq;
|
|
6
|
+
export function rubyScript(name: string): void;
|
|
7
|
+
export function rubyInitLoadpath(): void;
|
|
8
|
+
export function rbEvalStringProtect(str: string): [RbAbiValue, number];
|
|
9
|
+
export function rbFuncallvProtect(recv: RbAbiValue, mid: RbId, args: RbAbiValue[]): [RbAbiValue, number];
|
|
10
|
+
export function rbIntern(name: string): RbId;
|
|
11
|
+
export function rbErrinfo(): RbAbiValue;
|
|
12
|
+
export function rbClearErrinfo(): void;
|
|
13
|
+
export function rstringPtr(value: RbAbiValue): string;
|
|
14
|
+
export function rbVmBugreport(): void;
|
|
15
|
+
export function rbGcEnable(): boolean;
|
|
16
|
+
export function rbGcDisable(): boolean;
|
|
17
|
+
export function rbSetShouldProhibitRewind(newValue: boolean): boolean;
|
|
18
|
+
export function exportRbValueToJs(): RbAbiValue;
|
|
19
|
+
export { RbIseq };
|
|
20
|
+
export { RbAbiValue };
|
|
21
|
+
}
|
|
22
|
+
import type { JsAbiValue } from './ruby-js-js-runtime.js';
|
|
23
|
+
export { JsAbiValue };
|
|
24
|
+
export type RbErrno = number;
|
|
25
|
+
export type RbId = number;
|
|
26
|
+
|
|
27
|
+
export class RbAbiValue {
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class RbIseq {
|
|
31
|
+
}
|