Skip to content

Commit 303172f

Browse files
committed
Address comments
1 parent b30311d commit 303172f

File tree

13 files changed

+177
-139
lines changed

13 files changed

+177
-139
lines changed

src/library_wasmfs.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,37 @@ var WasmfsLibrary = {
8686
// For file preloading, cwd should be '/' to begin with.
8787
return '/';
8888
}
89+
},
90+
_emscripten_write_js_file: function(index, buffer, length, offset) {
91+
var size = wasmFS$JSMemoryFiles[index].length;
92+
// Resize the typed array if the length of the write buffer exceeds its capacity.
93+
if (offset + length >= size) {
94+
var oldContents =wasmFS$JSMemoryFiles[index];
95+
wasmFS$JSMemoryFiles[index] = new Uint8Array(offset + length);
96+
wasmFS$JSMemoryFiles[index].set(oldContents.subarray(0, size));
97+
}
98+
99+
wasmFS$JSMemoryFiles[index].set(HEAPU8.subarray(buffer, buffer + length), offset);
100+
},
101+
_emscripten_read_js_file: function(index, buffer, length, offset) {
102+
HEAPU8.set(wasmFS$JSMemoryFiles[index].subarray(offset, offset + length), buffer);
103+
},
104+
_emscripten_get_js_file_size: function(index) {
105+
return wasmFS$JSMemoryFiles[index].length;
106+
},
107+
_emscripten_create_js_file: function() {
108+
// Traverse wasmFS$JSMemoryFiles until an empty index is found.
109+
for (var index = 0; index < wasmFS$JSMemoryFiles.length; index++) {
110+
if (wasmFS$JSMemoryFiles[index] === null) {
111+
wasmFS$JSMemoryFiles[index] = new Uint8Array(0);
112+
return index;
113+
}
114+
}
115+
wasmFS$JSMemoryFiles.push(new Uint8Array(0));
116+
return wasmFS$JSMemoryFiles.length - 1;
117+
},
118+
_emscripten_remove_js_file: function(index) {
119+
wasmFS$JSMemoryFiles[index] = null;
89120
}
90121
}
91122

system/include/emscripten/wasmfs.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,20 @@ extern "C" {
1616

1717
typedef struct Backend* backend_t;
1818

19-
// Obtains backend_t of a specified path.
20-
backend_t wasmfs_get_backend(char* path);
19+
// Obtains the backend_t of a specified path.
20+
backend_t wasmfs_get_backend_by_path(char* path);
21+
22+
// Obtains the backend_t of a specified fd.
23+
backend_t wasmfs_get_backend_by_fd(int fd);
2124

2225
// Creates a JSFile Backend in the new file system.
23-
backend_t create_js_file_backend();
26+
backend_t wasmfs_create_js_file_backend();
2427

25-
// Creates a new file in the new file system under a specific backend.
26-
uint32_t wasmfs_create(char* pathname, mode_t mode, backend_t backend);
28+
// Creates a file in a specific backend and returns an fd to an open file.
29+
uint32_t wasmfs_create_file(char* pathname, mode_t mode, backend_t backend);
2730

2831
// Creates a new directory in the new file system under a specific backend.
29-
long wasmfs_mkdir(char* path, long mode, backend_t backend);
32+
long wasmfs_create_directory(char* path, long mode, backend_t backend);
3033

3134
#ifdef __cplusplus
3235
}

system/lib/wasmfs/backend.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,5 @@ class Backend {
2929
// Note: Backends will be defined in cpp files, but functions to instantiate
3030
// them will be defined in a header file. This is so that any unused backends
3131
// are not linked in if they are not called.
32-
// TODO: In the next PR, a user-visible header is introduced. Update this
33-
// comment then.
3432
backend_t createMemoryFileBackend();
3533
} // namespace wasmfs

system/lib/wasmfs/file.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Emscripten is available under two separate licenses, the MIT license and the
33
// University of Illinois/NCSA Open Source License. Both these licenses can be
44
// found in the LICENSE file.
5+
56
// This file defines the file object of the new file system.
67
// Current Status: Work in Progress.
78
// See https://github.com/emscripten-core/emscripten/issues/15041.
@@ -25,6 +26,7 @@ class Backend;
2526
// This represents an opaque pointer to a Backend. A user may use this to
2627
// specify a backend in file operations.
2728
using backend_t = Backend*;
29+
const backend_t NullBackend = nullptr;
2830

2931
class File : public std::enable_shared_from_this<File> {
3032

@@ -87,6 +89,8 @@ class File : public std::enable_shared_from_this<File> {
8789
// specified by the parent weak_ptr.
8890
std::shared_ptr<File> getParent() { return file->parent.lock(); }
8991
void setParent(std::shared_ptr<File> parent) { file->parent = parent; }
92+
93+
backend_t getBackend() { return file->backend; }
9094
};
9195

9296
Handle locked() { return Handle(shared_from_this()); }
@@ -101,7 +105,8 @@ class File : public std::enable_shared_from_this<File> {
101105
}
102106

103107
protected:
104-
File(FileKind kind, mode_t mode) : kind(kind), mode(mode) {}
108+
File(FileKind kind, mode_t mode, backend_t backend)
109+
: kind(kind), mode(mode), backend(backend) {}
105110
// A mutex is needed for multiple accesses to the same file.
106111
std::recursive_mutex mutex;
107112

@@ -121,6 +126,9 @@ class File : public std::enable_shared_from_this<File> {
121126
// dependencies where the parent and child have shared_ptrs that reference
122127
// each other. This prevents the case in which an uncollectable cycle occurs.
123128
std::weak_ptr<File> parent;
129+
130+
// This specifies which backend a file is associated with.
131+
backend_t backend;
124132
};
125133

126134
class DataFile : public File {
@@ -131,7 +139,8 @@ class DataFile : public File {
131139

132140
public:
133141
static constexpr FileKind expectedKind = File::DataFileKind;
134-
DataFile(mode_t mode) : File(File::DataFileKind, mode) {}
142+
DataFile(mode_t mode, backend_t backend)
143+
: File(File::DataFileKind, mode, backend) {}
135144
virtual ~DataFile() = default;
136145

137146
class Handle : public File::Handle {
@@ -161,15 +170,10 @@ class Directory : public File {
161170
// This value was also copied from the existing file system.
162171
size_t getSize() override { return 4096; }
163172

164-
// This specifies which backend a directory is associated with. By default,
165-
// files and sub-directories added to this directory's entries will be created
166-
// through this same backend unless an alternative is specified.
167-
backend_t backend;
168-
169173
public:
170174
static constexpr FileKind expectedKind = File::DirectoryKind;
171175
Directory(mode_t mode, backend_t backend)
172-
: File(File::DirectoryKind, mode), backend(backend) {}
176+
: File(File::DirectoryKind, mode, backend) {}
173177

174178
struct Entry {
175179
std::string name;
@@ -231,8 +235,6 @@ class Directory : public File {
231235
return entries;
232236
}
233237

234-
backend_t getBackend() { return getDir()->backend; }
235-
236238
#ifdef WASMFS_DEBUG
237239
void printKeys() {
238240
for (auto keyPair : getDir()->entries) {

system/lib/wasmfs/js_file_backend.cpp

Lines changed: 34 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,105 +2,81 @@
22
// Emscripten is available under two separate licenses, the MIT license and the
33
// University of Illinois/NCSA Open Source License. Both these licenses can be
44
// found in the LICENSE file.
5+
56
// This file defines the JS file backend and JS file of the new file system.
67
// Current Status: Work in Progress.
78
// See https://github.com/emscripten-core/emscripten/issues/15041.
89

910
#include "backend.h"
1011
#include "wasmfs.h"
1112

12-
namespace wasmfs {
13-
1413
using js_index_t = uint32_t;
1514

15+
extern "C" {
16+
void _emscripten_write_js_file(js_index_t index,
17+
const uint8_t* buffer,
18+
size_t length,
19+
off_t offset);
20+
void _emscripten_read_js_file(js_index_t index,
21+
const uint8_t* buffer,
22+
size_t length,
23+
off_t offset);
24+
int _emscripten_get_js_file_size(js_index_t index);
25+
int _emscripten_create_js_file();
26+
void _emscripten_remove_js_file(js_index_t index);
27+
}
28+
29+
namespace wasmfs {
30+
1631
// This class describes a file that lives in JS Memory
1732
class JSFile : public DataFile {
18-
// This index indicates the location of the JS File in $wasmFS$JSMemoryFiles.
33+
// This index indicates the location of the JS File in the backing JS array.
1934
js_index_t index;
2035

21-
// JSFiles will write from a Wasm Memory buffer into a JS array defined in
22-
// $wasmFS$JSMemoryFiles.
36+
// JSFiles will write from a Wasm Memory buffer into the backing JS array.
2337
__wasi_errno_t write(const uint8_t* buf, size_t len, off_t offset) override {
24-
EM_ASM(
25-
{
26-
// Resize the typed array if the length of the write buffer exceeds its
27-
// capacity.
28-
var size = wasmFS$JSMemoryFiles[$0].length;
29-
if ($2 >= size) {
30-
var oldContents = wasmFS$JSMemoryFiles[$0];
31-
wasmFS$JSMemoryFiles[$0] = new Uint8Array($2);
32-
wasmFS$JSMemoryFiles[$0].set(oldContents.subarray(0, $2));
33-
}
34-
wasmFS$JSMemoryFiles[$0].set(HEAPU8.subarray($1, $1 + $2), $3);
35-
},
36-
index,
37-
buf,
38-
len,
39-
(size_t)offset);
38+
39+
_emscripten_write_js_file(index, buf, len, offset);
4040

4141
return __WASI_ERRNO_SUCCESS;
4242
}
4343

44-
// JSFiles will read from JS Memory into a Wasm Memory buffer.
44+
// JSFiles will read from the backing JS array into a Wasm Memory buffer.
4545
__wasi_errno_t read(uint8_t* buf, size_t len, off_t offset) override {
4646
assert(offset + len - 1 < getSize());
47-
EM_ASM({ HEAPU8.set(wasmFS$JSMemoryFiles[$0].subarray($1, $2), $3); },
48-
index,
49-
(size_t)offset,
50-
(size_t)offset + len,
51-
buf);
47+
48+
_emscripten_read_js_file(index, buf, len, offset);
5249

5350
return __WASI_ERRNO_SUCCESS;
5451
}
5552

56-
// The size of the JSFile is defined as the length of the JS array in
57-
// $wasmFS$JSMemoryFiles.
58-
size_t getSize() override {
59-
return (size_t)EM_ASM_INT({ return wasmFS$JSMemoryFiles[$0].length; },
60-
index);
61-
}
53+
// The size of the JSFile is defined as the length of the backing JS array.
54+
size_t getSize() override { return _emscripten_get_js_file_size(index); }
6255

6356
public:
64-
JSFile(mode_t mode) : DataFile(mode) {
65-
// Add the new JSFile to the $wasmFS$JSMemoryFiles array and assign the
66-
// array index.
67-
index = (js_index_t)EM_ASM_INT({
68-
wasmFS$JSMemoryFiles.push(new Uint8Array(0));
69-
return wasmFS$JSMemoryFiles.length - 1;
70-
});
71-
}
72-
73-
// Remove the typed array file contents in $wasmFS$JSMemoryFiles array.
74-
~JSFile() {
75-
EM_ASM({ wasmFS$JSMemoryFiles[$0] = null; }, index);
57+
JSFile(mode_t mode, backend_t backend) : DataFile(mode, backend) {
58+
// Create a new file in the backing JS array and store its index.
59+
index = _emscripten_create_js_file();
7660
}
7761

78-
class Handle : public DataFile::Handle {
79-
80-
std::shared_ptr<JSFile> getFile() { return file->cast<JSFile>(); }
81-
82-
public:
83-
Handle(std::shared_ptr<File> dataFile) : DataFile::Handle(dataFile) {}
84-
};
85-
86-
Handle locked() { return Handle(shared_from_this()); }
62+
// Remove the typed array file contents in the backing JS array.
63+
~JSFile() { _emscripten_remove_js_file(index); }
8764
};
8865

8966
class JSFileBackend : public Backend {
9067

9168
public:
9269
std::shared_ptr<DataFile> createFile(mode_t mode) override {
93-
return std::make_shared<JSFile>(mode);
70+
return std::make_shared<JSFile>(mode, this);
9471
}
9572
std::shared_ptr<Directory> createDirectory(mode_t mode) override {
9673
return std::make_shared<Directory>(mode, this);
9774
}
9875
};
9976

10077
// This function is exposed to users to instantiate a new JSBackend.
101-
extern "C" backend_t create_js_file_backend() {
102-
wasmFS.backendTable.push_back(std::make_unique<JSFileBackend>());
103-
return wasmFS.backendTable.back().get();
78+
extern "C" backend_t wasmfs_create_js_file_backend() {
79+
return wasmFS.addBackend(std::make_unique<JSFileBackend>());
10480
}
10581

10682
} // namespace wasmfs

system/lib/wasmfs/memory_file.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class MemoryFile : public DataFile {
2424
size_t getSize() override { return buffer.size(); }
2525

2626
public:
27-
MemoryFile(mode_t mode) : DataFile(mode) {}
27+
MemoryFile(mode_t mode, backend_t backend) : DataFile(mode, backend) {}
2828

2929
class Handle : public DataFile::Handle {
3030

system/lib/wasmfs/memory_file_backend.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Emscripten is available under two separate licenses, the MIT license and the
33
// University of Illinois/NCSA Open Source License. Both these licenses can be
44
// found in the LICENSE file.
5+
56
// This file defines the memory file backend of the new file system.
67
// Current Status: Work in Progress.
78
// See https://github.com/emscripten-core/emscripten/issues/15041.
@@ -15,7 +16,7 @@ class MemoryFileBackend : public Backend {
1516

1617
public:
1718
std::shared_ptr<DataFile> createFile(mode_t mode) override {
18-
return std::make_shared<MemoryFile>(mode);
19+
return std::make_shared<MemoryFile>(mode, this);
1920
}
2021
std::shared_ptr<Directory> createDirectory(mode_t mode) override {
2122
return std::make_shared<Directory>(mode, this);

system/lib/wasmfs/streams.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class StdinFile : public DataFile {
2828
size_t getSize() override { return 0; }
2929

3030
public:
31-
StdinFile(mode_t mode) : DataFile(mode) {}
31+
StdinFile(mode_t mode) : DataFile(mode, NullBackend) {}
3232
static std::shared_ptr<StdinFile> getSingleton();
3333
};
3434

@@ -45,7 +45,7 @@ class StdoutFile : public DataFile {
4545
size_t getSize() override { return 0; }
4646

4747
public:
48-
StdoutFile(mode_t mode) : DataFile(mode) {}
48+
StdoutFile(mode_t mode) : DataFile(mode, NullBackend) {}
4949
static std::shared_ptr<StdoutFile> getSingleton();
5050
};
5151

@@ -65,7 +65,7 @@ class StderrFile : public DataFile {
6565
size_t getSize() override { return 0; }
6666

6767
public:
68-
StderrFile(mode_t mode) : DataFile(mode) {}
68+
StderrFile(mode_t mode) : DataFile(mode, NullBackend) {}
6969
static std::shared_ptr<StderrFile> getSingleton();
7070
};
7171
} // namespace wasmfs

0 commit comments

Comments
 (0)