@ruby/head-wasm-wasi 2.4.1 → 2.5.0

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.
@@ -1343,6 +1343,107 @@ SOFTWARE.
1343
1343
 
1344
1344
  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();}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){if(data.length>buf_len){buffer.setUint32(nread_ptr,0,true);return ERRNO_BADF}buffer8.set(data,buf_ptr);buffer.setUint32(nread_ptr,data.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"}};}};
1345
1345
 
1346
+ /**
1347
+ * Create a console printer that can be used as an overlay of WASI imports.
1348
+ * See the example below for how to use it.
1349
+ *
1350
+ * ```javascript
1351
+ * const imports = {
1352
+ * "wasi_snapshot_preview1": wasi.wasiImport,
1353
+ * }
1354
+ * const printer = consolePrinter();
1355
+ * printer.addToImports(imports);
1356
+ *
1357
+ * const instance = await WebAssembly.instantiate(module, imports);
1358
+ * printer.setMemory(instance.exports.memory);
1359
+ * ```
1360
+ *
1361
+ * Note that the `stdout` and `stderr` functions are called with text, not
1362
+ * bytes. This means that bytes written to stdout/stderr will be decoded as
1363
+ * UTF-8 and then passed to the `stdout`/`stderr` functions every time a write
1364
+ * occurs without buffering.
1365
+ *
1366
+ * @param stdout A function that will be called when stdout is written to.
1367
+ * Defaults to `console.log`.
1368
+ * @param stderr A function that will be called when stderr is written to.
1369
+ * Defaults to `console.warn`.
1370
+ * @returns An object that can be used as an overlay of WASI imports.
1371
+ */
1372
+ function consolePrinter({ stdout, stderr, } = {
1373
+ stdout: console.log,
1374
+ stderr: console.warn,
1375
+ }) {
1376
+ let memory = undefined;
1377
+ let _view = undefined;
1378
+ function getMemoryView() {
1379
+ if (typeof memory === "undefined") {
1380
+ throw new Error("Memory is not set");
1381
+ }
1382
+ if (_view === undefined || _view.buffer.byteLength === 0) {
1383
+ _view = new DataView(memory.buffer);
1384
+ }
1385
+ return _view;
1386
+ }
1387
+ const decoder = new TextDecoder();
1388
+ return {
1389
+ addToImports(imports) {
1390
+ const wasiImport = imports.wasi_snapshot_preview1;
1391
+ const original_fd_write = wasiImport.fd_write;
1392
+ wasiImport.fd_write = (fd, iovs, iovsLen, nwritten) => {
1393
+ if (fd !== 1 && fd !== 2) {
1394
+ return original_fd_write(fd, iovs, iovsLen, nwritten);
1395
+ }
1396
+ const view = getMemoryView();
1397
+ const buffers = Array.from({ length: iovsLen }, (_, i) => {
1398
+ const ptr = iovs + i * 8;
1399
+ const buf = view.getUint32(ptr, true);
1400
+ const bufLen = view.getUint32(ptr + 4, true);
1401
+ return new Uint8Array(memory.buffer, buf, bufLen);
1402
+ });
1403
+ let written = 0;
1404
+ let str = "";
1405
+ for (const buffer of buffers) {
1406
+ str += decoder.decode(buffer);
1407
+ written += buffer.byteLength;
1408
+ }
1409
+ view.setUint32(nwritten, written, true);
1410
+ const log = fd === 1 ? stdout : stderr;
1411
+ log(str);
1412
+ return 0;
1413
+ };
1414
+ const original_fd_filestat_get = wasiImport.fd_filestat_get;
1415
+ wasiImport.fd_filestat_get = (fd, filestat) => {
1416
+ if (fd !== 1 && fd !== 2) {
1417
+ return original_fd_filestat_get(fd, filestat);
1418
+ }
1419
+ const view = getMemoryView();
1420
+ const result = original_fd_filestat_get(fd, filestat);
1421
+ if (result !== 0) {
1422
+ return result;
1423
+ }
1424
+ const filetypePtr = filestat + 0;
1425
+ view.setUint8(filetypePtr, 2); // FILETYPE_CHARACTER_DEVICE
1426
+ return 0;
1427
+ };
1428
+ const original_fd_fdstat_get = wasiImport.fd_fdstat_get;
1429
+ wasiImport.fd_fdstat_get = (fd, fdstat) => {
1430
+ if (fd !== 1 && fd !== 2) {
1431
+ return original_fd_fdstat_get(fd, fdstat);
1432
+ }
1433
+ const view = getMemoryView();
1434
+ const fs_filetypePtr = fdstat + 0;
1435
+ view.setUint8(fs_filetypePtr, 2); // FILETYPE_CHARACTER_DEVICE
1436
+ const fs_rights_basePtr = fdstat + 8;
1437
+ view.setBigUint64(fs_rights_basePtr, BigInt(1)); // RIGHTS_FD_WRITE
1438
+ return 0;
1439
+ };
1440
+ },
1441
+ setMemory(m) {
1442
+ memory = m;
1443
+ },
1444
+ };
1445
+ }
1446
+
1346
1447
  let DATA_VIEW = new DataView(new ArrayBuffer());
1347
1448
  function data_view(mem) {
1348
1449
  if (DATA_VIEW.buffer !== mem.buffer)
@@ -1926,107 +2027,6 @@ SOFTWARE.
1926
2027
  };
1927
2028
  }
1928
2029
 
1929
- /**
1930
- * Create a console printer that can be used as an overlay of WASI imports.
1931
- * See the example below for how to use it.
1932
- *
1933
- * ```javascript
1934
- * const imports = {
1935
- * "wasi_snapshot_preview1": wasi.wasiImport,
1936
- * }
1937
- * const printer = consolePrinter();
1938
- * printer.addToImports(imports);
1939
- *
1940
- * const instance = await WebAssembly.instantiate(module, imports);
1941
- * printer.setMemory(instance.exports.memory);
1942
- * ```
1943
- *
1944
- * Note that the `stdout` and `stderr` functions are called with text, not
1945
- * bytes. This means that bytes written to stdout/stderr will be decoded as
1946
- * UTF-8 and then passed to the `stdout`/`stderr` functions every time a write
1947
- * occurs without buffering.
1948
- *
1949
- * @param stdout A function that will be called when stdout is written to.
1950
- * Defaults to `console.log`.
1951
- * @param stderr A function that will be called when stderr is written to.
1952
- * Defaults to `console.warn`.
1953
- * @returns An object that can be used as an overlay of WASI imports.
1954
- */
1955
- function consolePrinter({ stdout, stderr, } = {
1956
- stdout: console.log,
1957
- stderr: console.warn,
1958
- }) {
1959
- let memory = undefined;
1960
- let _view = undefined;
1961
- function getMemoryView() {
1962
- if (typeof memory === "undefined") {
1963
- throw new Error("Memory is not set");
1964
- }
1965
- if (_view === undefined || _view.buffer.byteLength === 0) {
1966
- _view = new DataView(memory.buffer);
1967
- }
1968
- return _view;
1969
- }
1970
- const decoder = new TextDecoder();
1971
- return {
1972
- addToImports(imports) {
1973
- const wasiImport = imports.wasi_snapshot_preview1;
1974
- const original_fd_write = wasiImport.fd_write;
1975
- wasiImport.fd_write = (fd, iovs, iovsLen, nwritten) => {
1976
- if (fd !== 1 && fd !== 2) {
1977
- return original_fd_write(fd, iovs, iovsLen, nwritten);
1978
- }
1979
- const view = getMemoryView();
1980
- const buffers = Array.from({ length: iovsLen }, (_, i) => {
1981
- const ptr = iovs + i * 8;
1982
- const buf = view.getUint32(ptr, true);
1983
- const bufLen = view.getUint32(ptr + 4, true);
1984
- return new Uint8Array(memory.buffer, buf, bufLen);
1985
- });
1986
- let written = 0;
1987
- let str = "";
1988
- for (const buffer of buffers) {
1989
- str += decoder.decode(buffer);
1990
- written += buffer.byteLength;
1991
- }
1992
- view.setUint32(nwritten, written, true);
1993
- const log = fd === 1 ? stdout : stderr;
1994
- log(str);
1995
- return 0;
1996
- };
1997
- const original_fd_filestat_get = wasiImport.fd_filestat_get;
1998
- wasiImport.fd_filestat_get = (fd, filestat) => {
1999
- if (fd !== 1 && fd !== 2) {
2000
- return original_fd_filestat_get(fd, filestat);
2001
- }
2002
- const view = getMemoryView();
2003
- const result = original_fd_filestat_get(fd, filestat);
2004
- if (result !== 0) {
2005
- return result;
2006
- }
2007
- const filetypePtr = filestat + 0;
2008
- view.setUint8(filetypePtr, 2); // FILETYPE_CHARACTER_DEVICE
2009
- return 0;
2010
- };
2011
- const original_fd_fdstat_get = wasiImport.fd_fdstat_get;
2012
- wasiImport.fd_fdstat_get = (fd, fdstat) => {
2013
- if (fd !== 1 && fd !== 2) {
2014
- return original_fd_fdstat_get(fd, fdstat);
2015
- }
2016
- const view = getMemoryView();
2017
- const fs_filetypePtr = fdstat + 0;
2018
- view.setUint8(fs_filetypePtr, 2); // FILETYPE_CHARACTER_DEVICE
2019
- const fs_rights_basePtr = fdstat + 8;
2020
- view.setBigUint64(fs_rights_basePtr, BigInt(1)); // RIGHTS_FD_WRITE
2021
- return 0;
2022
- };
2023
- },
2024
- setMemory(m) {
2025
- memory = m;
2026
- },
2027
- };
2028
- }
2029
-
2030
2030
  /**
2031
2031
  * A Ruby VM instance
2032
2032
  *
@@ -2099,11 +2099,12 @@ SOFTWARE.
2099
2099
  * @param args The command line arguments to pass to Ruby. Must be
2100
2100
  * an array of strings starting with the Ruby program name.
2101
2101
  */
2102
- initialize(args = ["ruby.wasm", "--disable-gems", "-EUTF-8", "-e_=0"]) {
2102
+ initialize(args = ["ruby.wasm", "-EUTF-8", "-e_=0"]) {
2103
2103
  const c_args = args.map((arg) => arg + "\0");
2104
2104
  this.guest.rubyInit();
2105
2105
  this.guest.rubySysinit(c_args);
2106
2106
  this.guest.rubyOptions(c_args);
2107
+ this.eval(`require "/bundle/setup"`);
2107
2108
  }
2108
2109
  /**
2109
2110
  * Set a given instance to interact JavaScript and Ruby's
@@ -2338,13 +2339,8 @@ SOFTWARE.
2338
2339
  */
2339
2340
  evalAsync(code) {
2340
2341
  const JS = this.eval("require 'js'; JS");
2341
- return new Promise((resolve, reject) => {
2342
- JS.call("__eval_async_rb", this.wrap(code), this.wrap({
2343
- resolve,
2344
- reject: (error) => {
2345
- reject(new RbError(this.exceptionFormatter.format(error, this, this.privateObject())));
2346
- },
2347
- }));
2342
+ return newRbPromise(this, this.privateObject(), (future) => {
2343
+ JS.call("__eval_async_rb", this.wrap(code), future);
2348
2344
  });
2349
2345
  }
2350
2346
  /**
@@ -2429,17 +2425,42 @@ SOFTWARE.
2429
2425
  *
2430
2426
  * @param callee name of the Ruby method to call
2431
2427
  * @param args arguments to pass to the method. Must be an array of RbValue
2428
+ * @returns The result of the method call as a new RbValue.
2432
2429
  *
2433
2430
  * @example
2434
2431
  * const ary = vm.eval("[1, 2, 3]");
2435
2432
  * ary.call("push", 4);
2436
2433
  * console.log(ary.call("sample").toString());
2437
- *
2438
2434
  */
2439
2435
  call(callee, ...args) {
2440
2436
  const innerArgs = args.map((arg) => arg.inner);
2441
2437
  return new RbValue(callRbMethod(this.vm, this.privateObject, this.inner, callee, innerArgs), this.vm, this.privateObject);
2442
2438
  }
2439
+ /**
2440
+ * Call a given method that may call `JS::Object#await` with given arguments
2441
+ *
2442
+ * @param callee name of the Ruby method to call
2443
+ * @param args arguments to pass to the method. Must be an array of RbValue
2444
+ * @returns A Promise that resolves to the result of the method call as a new RbValue.
2445
+ *
2446
+ * @example
2447
+ * const client = vm.eval(`
2448
+ * require 'js'
2449
+ * class HttpClient
2450
+ * def get(url)
2451
+ * JS.global.fetch(url).await
2452
+ * end
2453
+ * end
2454
+ * HttpClient.new
2455
+ * `);
2456
+ * const response = await client.callAsync("get", vm.eval(`"https://example.com"`));
2457
+ */
2458
+ callAsync(callee, ...args) {
2459
+ const JS = this.vm.eval("require 'js'; JS");
2460
+ return newRbPromise(this.vm, this.privateObject, (future) => {
2461
+ JS.call("__call_async_method", this, this.vm.wrap(callee), future, ...args);
2462
+ });
2463
+ }
2443
2464
  /**
2444
2465
  * @see {@link https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive}
2445
2466
  * @param hint Preferred type of the result primitive value. `"number"`, `"string"`, or `"default"`.
@@ -2638,6 +2659,18 @@ SOFTWARE.
2638
2659
  return new RbValue(value, vm, privateObject);
2639
2660
  });
2640
2661
  };
2662
+ function newRbPromise(vm, privateObject, body) {
2663
+ return new Promise((resolve, reject) => {
2664
+ const future = vm.wrap({
2665
+ resolve,
2666
+ reject: (error) => {
2667
+ const rbError = new RbError(privateObject.exceptionFormatter.format(error, vm, privateObject));
2668
+ reject(rbError);
2669
+ },
2670
+ });
2671
+ body(future);
2672
+ });
2673
+ }
2641
2674
  /**
2642
2675
  * Error class thrown by Ruby execution
2643
2676
  */
@@ -2773,7 +2806,7 @@ SOFTWARE.
2773
2806
  };
2774
2807
 
2775
2808
  var name = "@ruby/head-wasm-wasi";
2776
- var version = "2.4.1";
2809
+ var version = "2.5.0";
2777
2810
  var description = "Ruby head built on WASI";
2778
2811
  var main = "./dist/cjs/index.js";
2779
2812
  var module = "./dist/esm/index.js";
@@ -2789,6 +2822,12 @@ SOFTWARE.
2789
2822
  umd: "./dist/umd/*.js",
2790
2823
  "import": "./dist/esm/*.js",
2791
2824
  require: "./dist/cjs/*.js"
2825
+ },
2826
+ "./*.wasm": {
2827
+ browser: "./*.wasm",
2828
+ umd: "./*.wasm",
2829
+ "import": "./*.wasm",
2830
+ require: "./*.wasm"
2792
2831
  }
2793
2832
  };
2794
2833
  var files = [
@@ -2801,9 +2840,8 @@ SOFTWARE.
2801
2840
  "build:static:files": "../ruby-wasm-wasi/tools/pack-static-files.sh ./dist",
2802
2841
  "build:static:compat": "../ruby-wasm-wasi/tools/pack-compat-shim.mjs --dist=./dist --pkg=ruby-head-wasm-wasi",
2803
2842
  "build:static": "npm run build:static:files && npm run build:static:compat",
2804
- "build:wasm": "../ruby-wasm-wasi/tools/pack-ruby-wasm.sh ../../../rubies/head-wasm32-unknown-wasi-full-js-debug ./dist",
2805
2843
  "build:rollup": "rollup -c rollup.config.mjs",
2806
- build: "npm run build:deps && npm run build:static && npm run build:wasm && npm run build:rollup && ../ruby-wasm-wasi/tools/post-build.sh ./dist"
2844
+ build: "npm run build:deps && npm run build:static && npm run build:rollup && ../ruby-wasm-wasi/tools/post-build.sh ./dist"
2807
2845
  };
2808
2846
  var repository = "https://github.com/ruby/ruby.wasm";
2809
2847
  var homepage = "https://github.com/ruby/ruby.wasm/tree/main/packages/npm-packages/ruby-head-wasm-wasi";