-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSystem.v3
More file actions
127 lines (123 loc) · 3.54 KB
/
System.v3
File metadata and controls
127 lines (123 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright 2019 Google Inc. All rights reserved.
// See LICENSE for details of Apache 2.0 license.
def STDIN = 0;
def STDOUT = 1;
def STDERR = 2;
// The "System" component for the Wasm/JS target.
component System {
// change the permissions of a file
def chmod(path: string, mode: int) {
var p = toPath(path);
bwave.fs_chmod(p.0, p.1, mode);
}
// open a file
def fileOpen(path: string, read: bool) -> int {
var p = toPath(path);
return bwave.fs_open(p.0, p.1, if(read, 0, 1));
}
// close a file
def fileClose(fd: int) {
bwave.fs_close(fd);
}
// read a single byte from a file
def fileRead(fd: int) -> int {
var buf = Pointer.atContents(iobuf);
var result = bwave.fs_read(fd, buf, 1);
return if(result == 1, iobuf[0], -1);
}
// write some bytes to the file
def fileWriteK(fd: int, data: Array<byte>, offset: int, len: int) {
boundsCheck(data, offset, len);
var buf = Pointer.atContents(data) + offset;
bwave.fs_write(fd, buf, len);
}
// read some bytes from the file
def fileReadK(fd: int, data: Array<byte>, offset: int, len: int) -> int {
boundsCheck(data, offset, len);
var buf = Pointer.atContents(data) + offset;
var result = bwave.fs_read(fd, buf, len);
return result;
}
// calculate bytes remaining to be read from file
def fileLeft(fd: int) -> int {
return bwave.fs_avail(fd);
}
// load a file into a byte array
def fileLoad(path: string) -> Array<byte> {
var p = toPath(path);
var len = bwave.fs_size(p.0, p.1);
if (len < 0) return null;
var fd = bwave.fs_open(p.0, p.1, 0);
if (fd < 0) return null;
var buf = Array<byte>.new(len);
bwave.fs_read(fd, Pointer.atContents(buf), len);
bwave.fs_close(fd);
return buf;
}
// print a character to standard out
def putc(ch: byte) {
iobuf[0] = ch;
bwave.fs_write(STDOUT, Pointer.atContents(iobuf), 1);
}
// print an integer (in decimal) to standard out
def puti(val: int) {
var i = val;
if (i == 0) {
putc('0');
return;
}
var negative = true;
if (i > 0) {
negative = false;
i = 0 - i;
}
var pos = iobuf.length;
while (i != 0) { // XXX: use pointer loop instead?
var digit = byte.!('0' - i % 10);
iobuf[--pos] = digit;
i = i / 10;
}
if (negative) iobuf[--pos] = '-';
bwave.fs_write(STDOUT, Pointer.atContents(iobuf) + pos, iobuf.length - pos);
}
// print a string (as bytes) to standard out
def puts(str: string) {
bwave.fs_write(STDOUT, Pointer.atContents(str), str.length);
}
// prints a newline character to standard out
def ln() {
putc('\n');
}
// output an error, stacktrace, and exit
def error(ex: string, msg: string) {
def s = Pointer.atContents(ex), s_len = ex.length;
def m = if(msg != null, Pointer.atContents(msg));
def m_len = if (msg != null, msg.length);
bwave.throw_ex(s, s_len, m, m_len);
}
// get ticks in milliseconds
def ticksMs() -> int {
return bwave.ticks_ms();
}
// get ticks in microseconds
def ticksUs() -> int {
return bwave.ticks_us();
}
// get ticks in nanoseconds
def ticksNs() -> int {
return bwave.ticks_ns();
}
// @thread-local @lazy buffer for write integers and chars to System.out
private def iobuf = Array<byte>.new(16);
private def BCE = "BoundsCheckException";
private def EMPTY = "";
private def boundsCheck<T>(array: Array<T>, start: int, len: int) {
if (start < 0) System.error(BCE, EMPTY);
if (start > array.length) System.error(BCE, EMPTY);
var end = u32.!(start) + u32.!(len);
if (end > u32.!(array.length)) System.error(BCE, EMPTY);
}
private def toPath(path: string) -> (Pointer, int) {
return (Pointer.atContents(path), path.length);
}
}