Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions wasm-wasi-core/src/common/buffer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { size } from './baseTypes';

export function read(content: Uint8Array, offset: number, buffers: Uint8Array[]): size {
let totalBytesRead = 0;
for (const buffer of buffers) {
const toRead = Math.min(buffer.length, content.byteLength - offset);
buffer.set(content.subarray(offset, offset + toRead));
totalBytesRead += toRead;
if (toRead < buffer.length) {
break;
}
offset += toRead;
}
return totalBytesRead;
}

export function write(content: Uint8Array, offset: number, buffers: Uint8Array[]): [Uint8Array, size] {
let bytesToWrite: size = 0;
for (const bytes of buffers) {
bytesToWrite += bytes.byteLength;
}

const newSize = offset + bytesToWrite;

// Do we need to increase the buffer
if (newSize > content.byteLength) {
interface ResizeableArrayBuffer extends ArrayBuffer {
resize: (newByteLength: number) => void;
maxByteLength: number;
}
//Utilize ECMAScript 2024 In-Place Resizable ArrayBuffers

const buffer = content.buffer as ResizeableArrayBuffer;
const oldSize = buffer.maxByteLength;

if(newSize < oldSize){
buffer.resize(newSize);
} else {
const newBuffer = new (ArrayBuffer as any)(newSize, { maxByteLength: Math.max(newSize, oldSize << 1) });
const newContent = new Uint8Array(newBuffer);
newContent.set(content);
content = newContent;
}
}

for (const bytes of buffers) {
content.set(bytes, offset);
offset += bytes.length;
}

return [content, bytesToWrite];
}
44 changes: 4 additions & 40 deletions wasm-wasi-core/src/common/memoryFileSystemDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Errno, Fdflags, Filetype, Lookupflags, Oflags, Rights, WasiError, Whenc
import { size, u64 } from './baseTypes';
import { BigInts } from './converter';
import * as fs from './fileSystem';
import * as buffer from './buffer';
import { ReadableStream, WritableStream } from './streams';

const paths = RAL().path;
Expand Down Expand Up @@ -158,18 +159,18 @@ export class MemoryFileSystem extends fs.BaseFileSystem<DirectoryNode, FileNode,

public async readFile(node: FileNode, offset: bigint, buffers: Uint8Array[]): Promise<size> {
const content = await this.getContent(node);
return this.read(content, offset, buffers);
return buffer.read(content, BigInts.asNumber(offset), buffers);
}

public async readCharacterDevice(node: CharacterDeviceNode & { writable: WritableStream }, buffers: Uint8Array[]): Promise<size> {
const maxBytes = buffers.reduce((previousValue, current) => { return previousValue + current.byteLength; }, 0);
const content = await node.writable.read('max', maxBytes);
return this.read(content, 0n, buffers);
return buffer.read(content, 0, buffers);
}

public async writeFile(node: FileNode, offset: bigint, buffers: Uint8Array[]): Promise<size> {
const content = await this.getContent(node);
const [newContent, bytesWritten] = this.write(content, offset, buffers);
const [newContent, bytesWritten] = buffer.write(content, BigInts.asNumber(offset), buffers);
node.content = newContent;
return bytesWritten;
}
Expand All @@ -195,43 +196,6 @@ export class MemoryFileSystem extends fs.BaseFileSystem<DirectoryNode, FileNode,
return result;
}
}

private read(content: Uint8Array, _offset: bigint, buffers: Uint8Array[]): size {
let offset = BigInts.asNumber(_offset);
let totalBytesRead = 0;
for (const buffer of buffers) {
const toRead = Math.min(buffer.length, content.byteLength - offset);
buffer.set(content.subarray(offset, offset + toRead));
totalBytesRead += toRead;
if (toRead < buffer.length) {
break;
}
offset += toRead;
}
return totalBytesRead;
}

private write(content: Uint8Array, _offset: bigint, buffers: Uint8Array[]): [Uint8Array, size] {
let offset = BigInts.asNumber(_offset);
let bytesToWrite: size = 0;
for (const bytes of buffers) {
bytesToWrite += bytes.byteLength;
}

// Do we need to increase the buffer
if (offset + bytesToWrite > content.byteLength) {
const newContent = new Uint8Array(offset + bytesToWrite);
newContent.set(content);
content = newContent;
}

for (const bytes of buffers) {
content.set(bytes, offset);
offset += bytes.length;
}

return [content, bytesToWrite];
}
}

// When mounted the file system is readonly for now. We need to invest to make this writable and we need a use case first.
Expand Down
45 changes: 5 additions & 40 deletions wasm-wasi-core/src/common/vscodeFileSystemDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import { FileStat, FileType, workspace, Uri } from 'vscode';

import RAL from './ral';
import * as buffer from './buffer';
import { LRUCache } from './linkedMap';
import { u64, size } from './baseTypes';
import {
Expand Down Expand Up @@ -520,42 +521,6 @@ export function create(deviceId: DeviceId, baseUri: Uri, readOnly: boolean = fal
return BigInt(timeInMilliseconds) * 1000000n;
}

function read(content: Uint8Array, offset: number, buffers: Uint8Array[]): size {
let totalBytesRead = 0;
for (const buffer of buffers) {
const toRead = Math.min(buffer.length, content.byteLength - offset);
buffer.set(content.subarray(offset, offset + toRead));
totalBytesRead += toRead;
if (toRead < buffer.length) {
break;
}
offset += toRead;
}
return totalBytesRead;
}

function write(content: Uint8Array, offset: number, buffers: Uint8Array[]): [Uint8Array, size] {
let bytesToWrite: size = 0;
for (const bytes of buffers) {
bytesToWrite += bytes.byteLength;
}

// Do we need to increase the buffer
if (offset + bytesToWrite > content.byteLength) {
const newContent = new Uint8Array(offset + bytesToWrite);
newContent.set(content);
content = newContent;
}

for (const bytes of buffers) {
content.set(bytes, offset);
offset += bytes.length;
}

return [content, bytesToWrite];
}


async function createOrTruncate(fileDescriptor: FileFileDescriptor): Promise<void> {
const content = new Uint8Array(0);
const inode = fs.getNode(fileDescriptor.inode, NodeKind.File);
Expand Down Expand Up @@ -674,12 +639,12 @@ export function create(deviceId: DeviceId, baseUri: Uri, readOnly: boolean = fal
async fd_pread(fileDescriptor: FileDescriptor, _offset: filesize, buffers: Uint8Array[]): Promise<size> {
const offset = BigInts.asNumber(_offset);
const content = await fs.getContent(fs.getNode(fileDescriptor.inode, NodeKind.File), vscode_fs);
return read(content, offset, buffers);
return buffer.read(content, offset, buffers);
},
async fd_pwrite(fileDescriptor: FileDescriptor, _offset: filesize, buffers: Uint8Array[]): Promise<number> {
const offset = BigInts.asNumber(_offset);
const inode = fs.getNode(fileDescriptor.inode, NodeKind.File);
const [newContent, bytesWritten] = write(await fs.getContent(inode, vscode_fs), offset, buffers);
const [newContent, bytesWritten] = buffer.write(await fs.getContent(inode, vscode_fs), offset, buffers);
await writeContent(inode, newContent);
return bytesWritten;
},
Expand All @@ -691,7 +656,7 @@ export function create(deviceId: DeviceId, baseUri: Uri, readOnly: boolean = fal

const content = await fs.getContent(fs.getNode(fileDescriptor.inode, NodeKind.File), vscode_fs);
const offset = fileDescriptor.cursor;
const totalBytesRead = read(content, offset, buffers);
const totalBytesRead = buffer.read(content, offset, buffers);
fileDescriptor.cursor = fileDescriptor.cursor + totalBytesRead;
return totalBytesRead;
},
Expand Down Expand Up @@ -754,7 +719,7 @@ export function create(deviceId: DeviceId, baseUri: Uri, readOnly: boolean = fal
if (Fdflags.appendOn(fileDescriptor.fdflags)) {
fileDescriptor.cursor = content.byteLength;
}
const [newContent, bytesWritten] = write(content, fileDescriptor.cursor, buffers);
const [newContent, bytesWritten] = buffer.write(content, fileDescriptor.cursor, buffers);
await writeContent(inode,newContent);
fileDescriptor.cursor = fileDescriptor.cursor + bytesWritten;
return bytesWritten;
Expand Down