Skip to content

Commit

Permalink
gltfpack: Support texture compression in WASI builds
Browse files Browse the repository at this point in the history
We now support texture compression through a fake system() call; this
also required implementing getenv() in the WASI JS layer.
  • Loading branch information
zeux committed Oct 10, 2020
1 parent 0511930 commit b5ac6fe
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 21 deletions.
63 changes: 55 additions & 8 deletions gltf/bin/gltfpack.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var fs = require('fs');
var cp = require('child_process');

var WASI_EBADF = 8;
var WASI_EINVAL = 28;
Expand All @@ -19,6 +20,7 @@ var fds = {
};

var args = process.argv.slice(1);
var env = Object.keys(process.env).map(function (key) { return key + '=' + process.env[key] });

function nextFd() {
for (var i = 0; ; ++i) {
Expand Down Expand Up @@ -83,12 +85,24 @@ var wasi = {
heap.setUint32(opened_fd, fd, true);
return 0;
} catch (err) {
return WASI_ENOSYS;
return WASI_EIO;
}
},

path_unlink_file: function(parent_fd, path, path_len) {
return WASI_EINVAL;
if (fds[parent_fd] !== null) {
return WASI_EBADF;
}

var heap = getHeap();
var path_name = Buffer.from(heap.buffer, path, path_len).toString('utf-8');

try {
fs.unlinkSys(path_name);
return 0;
} catch (err) {
return WASI_EIO;
}
},

args_sizes_get: function(argc, argv_buf_size) {
Expand All @@ -111,13 +125,13 @@ var wasi = {
var argp = argv_buf;

for (var i = 0; i < args.length; ++i) {
var au = Buffer.from(args[i], 'utf-8');
var item = Buffer.from(args[i], 'utf-8');

heap.setUint32(argv + i * 4, argp, true);
au.copy(memory, argp);
heap.setUint8(argp + au.length, 0);
item.copy(memory, argp);
heap.setUint8(argp + item.length, 0);

argp += au.length + 1;
argp += item.length + 1;
}

return 0;
Expand Down Expand Up @@ -145,12 +159,33 @@ var wasi = {

environ_sizes_get: function(environc, environ_buf_size) {
var heap = getHeap();
heap.setUint32(environc, 0, true);
heap.setUint32(environ_buf_size, 0, true);

var buf_size = 0;
for (var i = 0; i < env.length; ++i) {
buf_size += Buffer.from(env[i], 'utf-8').length + 1;
}

heap.setUint32(environc, env.length, true);
heap.setUint32(environ_buf_size, buf_size, true);
return 0;
},

environ_get: function(environ, environ_buf) {
var heap = getHeap();
var memory = new Uint8Array(heap.buffer);

var envp = environ_buf;

for (var i = 0; i < env.length; ++i) {
var item = Buffer.from(env[i], 'utf-8');

heap.setUint32(environ + i * 4, envp, true);
item.copy(memory, envp);
heap.setUint8(envp + item.length, 0);

envp += item.length + 1;
}

return 0;
},

Expand Down Expand Up @@ -233,6 +268,18 @@ var wasi = {
heap.setUint32(nwritten, written, true);
return 0;
},

path_readlink: function(fd, path, path_len, buf, buf_len, bufused) {
if (fd !== -1) {
return WASI_ENOSYS;
}

var heap = getHeap();
var command = Buffer.from(heap.buffer, path, path_len).toString('utf-8');

var ret = cp.spawnSync(command, [], {shell:true});
return ret.status == null ? 256 : ret.status;
},
};

var wasm = fs.readFileSync(__dirname + '/gltfpack.wasm');
Expand Down
2 changes: 1 addition & 1 deletion gltf/fileio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ TempFile::TempFile(const char* suffix)
char ids[16];
sprintf(ids, "%d", id++);

path = "/tmp/gltfpack-";
path = "gltfpack-temp-";
path += ids;
path += suffix;
#else
Expand Down
14 changes: 2 additions & 12 deletions gltf/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,6 @@ static const char* mimeExtension(const char* mime_type)
return ".raw";
}

#if defined(__wasi__)
static int execute(const char* cmd_, bool ignore_stdout, bool ignore_stderr)
{
return -1;
}

static const char* readenv(const char* name)
{
return getenv(name);
}
#else
static int execute(const char* cmd_, bool ignore_stdout, bool ignore_stderr)
{
#ifdef _WIN32
Expand All @@ -125,10 +114,12 @@ static int execute(const char* cmd_, bool ignore_stdout, bool ignore_stderr)

std::string cmd = cmd_;

#ifndef __wasi__
if (ignore_stdout)
(cmd += " >") += ignore;
if (ignore_stderr)
(cmd += " 2>") += ignore;
#endif

return system(cmd.c_str());
}
Expand All @@ -137,7 +128,6 @@ static const char* readenv(const char* name)
{
return getenv(name);
}
#endif

bool checkBasis(bool verbose)
{
Expand Down
9 changes: 9 additions & 0 deletions gltf/wasistubs.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#ifdef __wasi__
#include <stdlib.h>
#include <string.h>

#include <wasi/api.h>

Expand Down Expand Up @@ -40,4 +41,12 @@ __wasi_errno_t __wasi_fd_seek(__wasi_fd_t fd, __wasi_filedelta_t offset, __wasi_
*newoffset = newoffset32;
return result;
}

extern "C" int system(const char* command)
{
// WASI doesn't provide a system() equivalent; we highjack readlink here, the reasoning being that if we run against a real WASI implementation,
// the effect is more likely to be benign.
return __wasi_path_readlink(-1, command, strlen(command), 0, 0, 0);
}

#endif

0 comments on commit b5ac6fe

Please sign in to comment.