rlang 0.4.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -3
- data/Gemfile.lock +4 -6
- data/README +11 -0
- data/README.md +18 -10
- data/bin/rlang +17 -5
- data/docs/RlangCompiler.md +5 -1
- data/docs/RlangManual.md +98 -20
- data/examples/fib/fib.rb +5 -1
- data/lib/builder/rlang/compiler.rb +2 -21
- data/lib/rlang/lib/array/array32.rb +59 -0
- data/lib/rlang/lib/array/array64.rb +56 -0
- data/lib/rlang/lib/array.rb +6 -0
- data/lib/rlang/lib/base64.rb +223 -0
- data/lib/rlang/lib/io.rb +75 -0
- data/lib/rlang/lib/kernel.rb +23 -0
- data/lib/rlang/lib/malloc.rb +12 -8
- data/lib/rlang/lib/memory.rb +102 -2
- data/lib/rlang/lib/object.rb +40 -4
- data/lib/rlang/lib/rlang.rb +29 -0
- data/lib/rlang/lib/rlang_core.rb +15 -0
- data/lib/rlang/lib/string.rb +106 -8
- data/lib/rlang/lib/type/i32.rb +43 -0
- data/lib/rlang/lib/type/i64.rb +2 -0
- data/lib/rlang/lib/unistd.rb +1 -2
- data/lib/rlang/lib/wasi.rb +184 -0
- data/lib/rlang/parser/attr.rb +9 -13
- data/lib/rlang/parser/const.rb +105 -1
- data/lib/rlang/parser/cvar.rb +11 -7
- data/lib/rlang/parser/data.rb +17 -6
- data/lib/rlang/parser/export.rb +4 -3
- data/lib/rlang/parser/ext/integer.rb +3 -1
- data/lib/rlang/parser/ext/type.rb +30 -1
- data/lib/rlang/parser/global.rb +10 -2
- data/lib/rlang/parser/ivar.rb +3 -7
- data/lib/rlang/parser/klass.rb +8 -35
- data/lib/rlang/parser/method.rb +36 -12
- data/lib/rlang/parser/module.rb +143 -0
- data/lib/rlang/parser/wgenerator.rb +462 -168
- data/lib/rlang/parser/wnode.rb +387 -142
- data/lib/rlang/parser/wtype.rb +30 -7
- data/lib/rlang/parser.rb +506 -231
- data/lib/rlang/version.rb +1 -1
- data/lib/rlang.rb +3 -0
- data/lib/ruby/mirror/rstring.rb +16 -0
- data/lib/utils/exceptions.rb +12 -0
- data/rlang.gemspec +4 -4
- metadata +25 -13
- data/lib/rlang/lib.rb +0 -11
@@ -0,0 +1,56 @@
|
|
1
|
+
# Rubinius WebAssembly VM
|
2
|
+
# Copyright (c) 2019-2020, Laurent Julliard and contributors
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# 4 bytes object array class
|
6
|
+
require_relative '../memory'
|
7
|
+
require_relative '../object'
|
8
|
+
require_relative '../type'
|
9
|
+
require_relative '../string'
|
10
|
+
|
11
|
+
|
12
|
+
class Array64
|
13
|
+
attr_reader :count, :ptr
|
14
|
+
|
15
|
+
# count: number of elements in Array
|
16
|
+
# Array elements are native types or
|
17
|
+
# pointers to objects
|
18
|
+
# Arrays are fixed size for now
|
19
|
+
def initialize(count)
|
20
|
+
# Avoid allocating 0 bytes in memory
|
21
|
+
if count == 0
|
22
|
+
@ptr = 0
|
23
|
+
else
|
24
|
+
# Memory size is count * 8 bytes
|
25
|
+
@ptr = Object.allocate(count << 3)
|
26
|
+
end
|
27
|
+
@count = count
|
28
|
+
end
|
29
|
+
|
30
|
+
def size; @count; end
|
31
|
+
def length; @count; end
|
32
|
+
def empty?; self.size == 0; end
|
33
|
+
|
34
|
+
def [](idx)
|
35
|
+
result :I64
|
36
|
+
raise "Index out of bound" if idx >= @count || idx < -@count
|
37
|
+
# offset in memory for elt #idx is idx * 8
|
38
|
+
Memory.load64(@ptr + (idx << 3))
|
39
|
+
end
|
40
|
+
|
41
|
+
def []=(idx, value)
|
42
|
+
arg value: :I64
|
43
|
+
result :I64
|
44
|
+
raise "Index out of bound" if idx >= @count || idx < -@count
|
45
|
+
# offset in memory for elt #idx is idx * 8
|
46
|
+
Memory.store64(@ptr + (idx << 3), value)
|
47
|
+
value
|
48
|
+
end
|
49
|
+
|
50
|
+
def free
|
51
|
+
result :none
|
52
|
+
Object.free(@ptr)
|
53
|
+
Object.free(self)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
# Rlang WebAssembly compiler
|
2
|
+
# Copyright (c) 2019-2022, Laurent Julliard and contributors
|
3
|
+
# All rights reserved.
|
4
|
+
|
5
|
+
require 'kernel'
|
6
|
+
require 'string'
|
7
|
+
require 'array'
|
8
|
+
|
9
|
+
module Base64
|
10
|
+
|
11
|
+
include Kernel
|
12
|
+
|
13
|
+
BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
14
|
+
BASE64_CHARS_URLSAFE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
|
15
|
+
PAD = "="
|
16
|
+
LINE_SEP = "\n" # Would be "\r\n" on Windows
|
17
|
+
|
18
|
+
# Tables of valid ASCII char maps for Base64 decoding.
|
19
|
+
# -1 : the char is invalid
|
20
|
+
# >= 0 : the binary value to use for decoding (note: the '=' sign is also 0)
|
21
|
+
#
|
22
|
+
BASE64_CHAR_MAP =
|
23
|
+
[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
24
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
|
25
|
+
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8,
|
26
|
+
9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26,
|
27
|
+
27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
|
28
|
+
51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
29
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
30
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
31
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
32
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
33
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
|
34
|
+
|
35
|
+
BASE64_CHAR_MAP_URLSAFE =
|
36
|
+
[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
37
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,
|
38
|
+
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8,
|
39
|
+
9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, -1, 26,
|
40
|
+
27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
|
41
|
+
51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
42
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
43
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
44
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
45
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
46
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
|
47
|
+
|
48
|
+
|
49
|
+
# Generic base 64 encoding
|
50
|
+
# Derived from
|
51
|
+
# http://www.java2s.com/Code/Java/Development-Class/AfastandmemoryefficientclasstoencodeanddecodetoandfromBASE64infullaccordancewithRFC2045.htm)
|
52
|
+
def self._encode64(bin, line_sep, base64_chars)
|
53
|
+
arg bin: :String, base64_chars: :String
|
54
|
+
local str: :String
|
55
|
+
result :String
|
56
|
+
|
57
|
+
# Check special case
|
58
|
+
return "" if bin.empty?
|
59
|
+
slen = bin.length
|
60
|
+
|
61
|
+
# Number of even 24 bits (groups of 3 bytes)
|
62
|
+
elen = (slen / 3) * 3
|
63
|
+
# Encoded character count
|
64
|
+
ccnt = ((slen - 1) / 3 + 1) << 2
|
65
|
+
# Size of encoded string (incl. line separators)
|
66
|
+
# Note : Ruby implementation always add a \n at the end
|
67
|
+
# hence the +1
|
68
|
+
dlen = ccnt
|
69
|
+
dlen += ((ccnt - 1) / 60 + 1) * LINE_SEP.length if line_sep
|
70
|
+
|
71
|
+
# Allocate the proper size for encoded string
|
72
|
+
# to avoid allocating many string objects during
|
73
|
+
# concatenation
|
74
|
+
str = String.new(0, dlen)
|
75
|
+
|
76
|
+
# Encode even 24 bits
|
77
|
+
s=0; d=0; cc=0
|
78
|
+
while s < elen
|
79
|
+
# Copy next three bytes into lower 24 bits of int,
|
80
|
+
# paying attention to sign.
|
81
|
+
i = bin[s].ord << 16 | bin[s+1].ord << 8 | bin[s+2].ord
|
82
|
+
s += 3
|
83
|
+
|
84
|
+
# Encode the int into four chars
|
85
|
+
str[d] = base64_chars[(i >> 18) & 0x3f]; d += 1
|
86
|
+
str[d] = base64_chars[(i >> 12) & 0x3f]; d += 1
|
87
|
+
str[d] = base64_chars[(i >> 6) & 0x3f]; d += 1
|
88
|
+
str[d] = base64_chars[i & 0x3f]; d += 1
|
89
|
+
cc += 1
|
90
|
+
|
91
|
+
# Add optional line separator each 60 chars in Ruby
|
92
|
+
if (line_sep && cc == 15 && d < dlen - 1)
|
93
|
+
str[d] = LINE_SEP; d += LINE_SEP.length
|
94
|
+
cc = 0
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Pad and encode last bits if source isn't even 24 bits.
|
99
|
+
left = slen - elen # 0 - 2
|
100
|
+
if left > 0
|
101
|
+
# Prepare the last int
|
102
|
+
i = bin[elen].ord << 10
|
103
|
+
i |= (bin[slen - 1].ord << 2) if left == 2
|
104
|
+
|
105
|
+
# Set last four chars
|
106
|
+
str[d] = base64_chars[i >> 12]; d += 1
|
107
|
+
str[d] = base64_chars[(i >> 6) & 0x3f]; d += 1
|
108
|
+
if left == 2
|
109
|
+
str[d] = base64_chars[i & 0x3f]
|
110
|
+
else
|
111
|
+
str[d] = PAD
|
112
|
+
end
|
113
|
+
d += 1
|
114
|
+
str[d] = PAD; d += 1
|
115
|
+
end
|
116
|
+
|
117
|
+
str[d] = LINE_SEP if line_sep
|
118
|
+
return str
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
# Decodes a BASE64 encoded String. All illegal characters will be
|
123
|
+
# ignored and can handle both arrays with and without line separators.
|
124
|
+
#
|
125
|
+
# Derived from
|
126
|
+
# http://www.java2s.com/Code/Java/Development-Class/AfastandmemoryefficientclasstoencodeanddecodetoandfromBASE64infullaccordancewithRFC2045.htm)
|
127
|
+
|
128
|
+
def self._decode64(str, base64_chars, base64_char_map)
|
129
|
+
arg str: :String, base64_chars: :String, base64_char_map: :Array32
|
130
|
+
local bin: :String
|
131
|
+
result :String
|
132
|
+
|
133
|
+
# Check special case
|
134
|
+
return "" if (slen = str.length) == 0
|
135
|
+
|
136
|
+
# Count illegal characters (including '\r', '\n') to know what
|
137
|
+
# size the returned array will be, so we don't have to reallocate
|
138
|
+
# & copy it later.
|
139
|
+
# Number of separator characters. (Actually illegal characters,
|
140
|
+
# but that's a bonus...)
|
141
|
+
sepcnt = 0; i = 0
|
142
|
+
while i < slen
|
143
|
+
sepcnt += 1 if base64_char_map[str[i].ord] < 0
|
144
|
+
i += 1
|
145
|
+
end
|
146
|
+
|
147
|
+
# Check that legal chars (including '=') are evenly divideable
|
148
|
+
# by 4 as specified in RFC 2045.
|
149
|
+
return "" if (slen - sepcnt) % 4 != 0
|
150
|
+
|
151
|
+
# Count padding chars from the end
|
152
|
+
pad = 0; i = slen-1
|
153
|
+
while i > 0 && base64_char_map[str[i].ord] <= 0
|
154
|
+
pad += 1 if str[i] == PAD
|
155
|
+
i -= 1
|
156
|
+
end
|
157
|
+
|
158
|
+
# Preallocate String of exact length
|
159
|
+
len = ((slen - sepcnt) * 6 >> 3) - pad
|
160
|
+
bin = String.new(0, len)
|
161
|
+
|
162
|
+
# Go on decoding
|
163
|
+
s = 0; d = 0
|
164
|
+
while d < len
|
165
|
+
# Assemble 3 bytes into an int from 4 valid characters.
|
166
|
+
i = 0; j = 0
|
167
|
+
while j < 4
|
168
|
+
c = base64_char_map[str[s].ord]; s += 1
|
169
|
+
# j increases only if a valid char is found
|
170
|
+
if c != -1
|
171
|
+
i |= c << (18 - j * 6)
|
172
|
+
j += 1
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# Now decode the int and add 3 chars to the bin string
|
177
|
+
bin[d] = (i >> 16 & 0xff).chr; d += 1
|
178
|
+
if d < len
|
179
|
+
bin[d] = (i >> 8 & 0xff).chr; d += 1
|
180
|
+
if d < len
|
181
|
+
bin[d] = (i & 0xff).chr; d += 1
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
return bin
|
187
|
+
end
|
188
|
+
|
189
|
+
def self.decode64(str)
|
190
|
+
arg str: :String
|
191
|
+
result :String
|
192
|
+
self._decode64(str, BASE64_CHARS, BASE64_CHAR_MAP)
|
193
|
+
end
|
194
|
+
|
195
|
+
def self.encode64(bin)
|
196
|
+
arg bin: :String
|
197
|
+
result :String
|
198
|
+
self._encode64(bin, 1, BASE64_CHARS)
|
199
|
+
end
|
200
|
+
|
201
|
+
def self.strict_decode64(str)
|
202
|
+
arg str: :String
|
203
|
+
self._decode64(str, BASE64_CHARS, BASE64_CHAR_MAP)
|
204
|
+
end
|
205
|
+
|
206
|
+
def self.strict_encode64(bin)
|
207
|
+
arg bin: :String
|
208
|
+
result :String
|
209
|
+
self._encode64(bin, 0, BASE64_CHARS)
|
210
|
+
end
|
211
|
+
|
212
|
+
def self.urlsafe_decode64(str)
|
213
|
+
arg str: :String
|
214
|
+
self._decode64(str, BASE64_CHARS_URLSAFE, BASE64_CHAR_MAP_URLSAFE)
|
215
|
+
end
|
216
|
+
|
217
|
+
def self.urlsafe_encode64(bin)
|
218
|
+
arg bin: :String
|
219
|
+
result :String
|
220
|
+
self._encode64(bin, 0, BASE64_CHARS_URLSAFE)
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|
data/lib/rlang/lib/io.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# Rubinius WebAssembly VM
|
2
|
+
# Copyright (c) 2019-2020, Laurent Julliard and contributors
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# IO class for all basic input and output operations
|
6
|
+
|
7
|
+
require_relative './wasi'
|
8
|
+
|
9
|
+
class IO
|
10
|
+
attr_accessor :fd
|
11
|
+
|
12
|
+
@@num_bytes_written = 0
|
13
|
+
@@num_bytes_read = 0
|
14
|
+
|
15
|
+
def initialize(fd)
|
16
|
+
@fd = fd
|
17
|
+
end
|
18
|
+
|
19
|
+
def write(stg)
|
20
|
+
arg stg: :String
|
21
|
+
ciovec = WASI::CIOVec.new(1)
|
22
|
+
ciovec << stg
|
23
|
+
errno = WASI.fd_write(@fd, ciovec.ciovs.ptr, 1, @@num_bytes_written.addr)
|
24
|
+
ciovec.free
|
25
|
+
errno
|
26
|
+
end
|
27
|
+
|
28
|
+
def print(stg)
|
29
|
+
self.write(stg)
|
30
|
+
end
|
31
|
+
|
32
|
+
def puts(stg)
|
33
|
+
arg stg: :String
|
34
|
+
result :none
|
35
|
+
ciovec = WASI::CIOVec.new(2)
|
36
|
+
ciovec << stg
|
37
|
+
ciovec << "\n"
|
38
|
+
errno = WASI.fd_write(@fd, ciovec.ciovs.ptr, 2, @@num_bytes_written.addr)
|
39
|
+
ciovec.free
|
40
|
+
end
|
41
|
+
|
42
|
+
def read
|
43
|
+
result :String
|
44
|
+
local stg: :String
|
45
|
+
iovec = WASI::IOVec.new(1)
|
46
|
+
errno = WASI.fd_read(@fd, iovec.iovs.ptr, 1, @@num_bytes_read.addr)
|
47
|
+
# -1 below because of \0 terminated string
|
48
|
+
stg = String.new(iovec.iovs[0], @@num_bytes_read-1)
|
49
|
+
# Nullify the iovs entry used by the String object so it is not freed
|
50
|
+
iovec.iovs[0] = 0
|
51
|
+
iovec.free
|
52
|
+
stg
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
STDIN = IO.new
|
58
|
+
STDOUT = IO.new
|
59
|
+
STDERR = IO.new
|
60
|
+
|
61
|
+
module Kernel
|
62
|
+
|
63
|
+
def puts(stg)
|
64
|
+
arg stg: :String
|
65
|
+
result :none
|
66
|
+
STDOUT.puts(stg)
|
67
|
+
end
|
68
|
+
|
69
|
+
def print(stg)
|
70
|
+
arg stg: :String
|
71
|
+
result :none
|
72
|
+
STDOUT.print(stg)
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Rubinius WebAssembly VM
|
2
|
+
# Copyright (c) 2019-2020, Laurent Julliard and contributors
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Kernel methods
|
6
|
+
#
|
7
|
+
# Most of the Kernel methods are defined in other files
|
8
|
+
# to avoid requiring classes that rely on Kernel methods
|
9
|
+
# themselves.
|
10
|
+
|
11
|
+
class String; end
|
12
|
+
|
13
|
+
module Kernel
|
14
|
+
|
15
|
+
def raise(msg)
|
16
|
+
arg msg: :String
|
17
|
+
result :none
|
18
|
+
#$! = msg
|
19
|
+
#STDERR.puts msg
|
20
|
+
inline wat: '(unreachable)', wtype: :none
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/lib/rlang/lib/malloc.rb
CHANGED
@@ -8,8 +8,8 @@
|
|
8
8
|
# For a detailed explanation of the allocator code see
|
9
9
|
# https://gnuchops.wordpress.com/2013/02/26/memory-allocator-for-embedded-system-k-r-ritchie-book/
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
require_relative './memory'
|
12
|
+
require_relative './unistd'
|
13
13
|
|
14
14
|
# minimum number of units to request
|
15
15
|
$NALLOC = 1024
|
@@ -30,13 +30,14 @@ $NALLOC = 1024
|
|
30
30
|
|
31
31
|
# Allocate some unused memory space to make
|
32
32
|
# sure so that freep doesn't point to memory
|
33
|
-
# address 0 because it has a
|
34
|
-
# Allocate 20 bytes (
|
35
|
-
DAta
|
33
|
+
# address 0 because it has a special meaning
|
34
|
+
# Allocate 20 bytes (4 x I32 integers)
|
35
|
+
DAta.align(4)
|
36
|
+
DAta[:dummy_malloc_data] = [0, 0, 0, 0]
|
36
37
|
|
37
38
|
class Header
|
38
39
|
attr_accessor :ptr, :size
|
39
|
-
attr_type ptr: :Header, size: :
|
40
|
+
attr_type ptr: :Header, size: :UI32
|
40
41
|
end
|
41
42
|
|
42
43
|
class Malloc
|
@@ -47,13 +48,15 @@ class Malloc
|
|
47
48
|
# declare ahead of time because is used in
|
48
49
|
# the code before it is actually defined
|
49
50
|
result :Malloc, :free, :nil
|
51
|
+
result :Malloc, :morecore, :Header
|
50
52
|
|
51
53
|
# -------- Dynamic Memory Allocator Functions -----------
|
52
54
|
|
53
55
|
# malloc: allocate n bytes of memory and return pointer
|
54
56
|
# to data block
|
55
57
|
def self.malloc(nbytes)
|
56
|
-
|
58
|
+
arg nbytes: :UI32
|
59
|
+
local p: :Header, prevp: :Header, nunits: :UI32
|
57
60
|
|
58
61
|
# allocate memory by chunk of units (the unit is
|
59
62
|
# the size of a Header object here)
|
@@ -105,6 +108,7 @@ class Malloc
|
|
105
108
|
|
106
109
|
# morecore: ask system for more memory
|
107
110
|
def self.morecore(nu)
|
111
|
+
arg nu: :UI32
|
108
112
|
result :Header
|
109
113
|
local up: :Header
|
110
114
|
|
@@ -120,7 +124,7 @@ class Malloc
|
|
120
124
|
|
121
125
|
# Free memory block
|
122
126
|
def self.free(ap)
|
123
|
-
arg ap: :
|
127
|
+
arg ap: :UI32
|
124
128
|
result :none
|
125
129
|
local bp: :Header, p: :Header
|
126
130
|
|
data/lib/rlang/lib/memory.rb
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
-
|
1
|
+
# Rubinius WebAssembly VM
|
2
|
+
# Copyright (c) 2019-2020, Laurent Julliard and contributors
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Web Assembly memory access methods
|
6
|
+
#
|
2
7
|
|
3
8
|
class Memory
|
4
9
|
|
@@ -25,5 +30,100 @@ class Memory
|
|
25
30
|
idx += 1
|
26
31
|
end
|
27
32
|
end
|
28
|
-
|
33
|
+
|
34
|
+
def self.load32_8(addr)
|
35
|
+
arg addr: :I32
|
36
|
+
result :I32
|
37
|
+
inline wat: '(i32.load8_u (local.get $addr))',
|
38
|
+
wtype: :I32
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.load32_16(addr)
|
42
|
+
arg addr: :I32
|
43
|
+
result :I32
|
44
|
+
inline wat: '(i32.load16_u (local.get $addr))',
|
45
|
+
wtype: :I32
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.load32(addr)
|
49
|
+
arg addr: :I32
|
50
|
+
result :I32
|
51
|
+
inline wat: '(i32.load (local.get $addr))',
|
52
|
+
wtype: :I32
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.load64_8(addr)
|
56
|
+
arg addr: :I32
|
57
|
+
result :I64
|
58
|
+
inline wat: '(i64.load8_u (local.get $addr))',
|
59
|
+
wtype: :I64
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.load64_16(addr)
|
63
|
+
arg addr: :I32
|
64
|
+
result :I64
|
65
|
+
inline wat: '(i64.load16_u (local.get $addr))',
|
66
|
+
wtype: :I64
|
67
|
+
end
|
68
|
+
def self.load64_32(addr)
|
69
|
+
arg addr: :I32
|
70
|
+
result :I64
|
71
|
+
inline wat: '(i64.load32_u (local.get $addr))',
|
72
|
+
wtype: :I64
|
73
|
+
end
|
74
|
+
def self.load64(addr)
|
75
|
+
arg addr: :I32
|
76
|
+
result :I64
|
77
|
+
inline wat: '(i64.load (local.get $addr))',
|
78
|
+
wtype: :I64
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.store32_8(addr, value)
|
82
|
+
arg addr: :I32, value: :I32
|
83
|
+
result :none
|
84
|
+
inline wat: '(i32.store8 (local.get $addr) (local.get $value))',
|
85
|
+
wtype: :none
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.store32_16(addr, value)
|
89
|
+
arg addr: :I32, value: :I32
|
90
|
+
result :none
|
91
|
+
inline wat: '(i32.store16 (local.get $addr) (local.get $value))',
|
92
|
+
wtype: :none
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.store32(addr, value)
|
96
|
+
arg addr: :I32, value: :I32
|
97
|
+
result :none
|
98
|
+
inline wat: '(i32.store (local.get $addr) (local.get $value))',
|
99
|
+
wtype: :none
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.store64_8(addr, value)
|
103
|
+
arg addr: :I32, value: :I64
|
104
|
+
result :none
|
105
|
+
inline wat: '(i64.store8 (local.get $addr) (local.get $value))',
|
106
|
+
wtype: :none
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.store64_16(addr, value)
|
110
|
+
arg addr: :I32, value: :I64
|
111
|
+
result :none
|
112
|
+
inline wat: '(i64.store16 (local.get $addr) (local.get $value))',
|
113
|
+
wtype: :none
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.store64_32(addr, value)
|
117
|
+
arg addr: :I32, value: :I64
|
118
|
+
result :none
|
119
|
+
inline wat: '(i64.store32 (local.get $addr) (local.get $value))',
|
120
|
+
wtype: :none
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.store64(addr, value)
|
124
|
+
arg addr: :I32, value: :I64
|
125
|
+
result :none
|
126
|
+
inline wat: '(i64.store (local.get $addr) (local.get $value))',
|
127
|
+
wtype: :none
|
128
|
+
end
|
29
129
|
end
|
data/lib/rlang/lib/object.rb
CHANGED
@@ -1,10 +1,18 @@
|
|
1
|
+
# Rubinius WebAssembly VM
|
2
|
+
# Copyright (c) 2019-2020, Laurent Julliard and contributors
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Base Object class
|
6
|
+
|
1
7
|
require_relative './malloc'
|
8
|
+
require_relative './kernel'
|
9
|
+
require_relative './string'
|
2
10
|
|
3
11
|
class Object
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def self.
|
12
|
+
|
13
|
+
include Kernel
|
14
|
+
|
15
|
+
def self.allocate(nbytes)
|
8
16
|
result :I32
|
9
17
|
Malloc.malloc(nbytes)
|
10
18
|
end
|
@@ -13,4 +21,32 @@ class Object
|
|
13
21
|
result :none
|
14
22
|
Malloc.free(object_ptr)
|
15
23
|
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
result :String
|
27
|
+
"Object <addr>"
|
28
|
+
end
|
29
|
+
|
30
|
+
def object_id
|
31
|
+
result :I32
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def eql?(object)
|
36
|
+
result :I32
|
37
|
+
inline wat: '(i32.eq
|
38
|
+
(local.get $_self_)
|
39
|
+
(local.get $object))',
|
40
|
+
wtype: :I32,
|
41
|
+
ruby: 'self.object_id == object.object_id'
|
42
|
+
end
|
43
|
+
|
44
|
+
def ==(object)
|
45
|
+
self.eql?(object)
|
46
|
+
end
|
47
|
+
|
48
|
+
def !=(object)
|
49
|
+
!(self == object)
|
50
|
+
end
|
51
|
+
|
16
52
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Rubinius WebAssembly VM
|
2
|
+
# Copyright (c) 2019-2020, Laurent Julliard and contributors
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Rlang standard library classes and modules
|
6
|
+
# and runtime initialization
|
7
|
+
#
|
8
|
+
require_relative './rlang_core'
|
9
|
+
require_relative './wasi'
|
10
|
+
require_relative './io'
|
11
|
+
|
12
|
+
class Rlang
|
13
|
+
def self.init
|
14
|
+
# WASI init: setup ARGC, ARGV, etc...
|
15
|
+
errno = WASI.init
|
16
|
+
|
17
|
+
# IO init: setup fd of stdin, out and err
|
18
|
+
# This code cannot be executed within io.rb
|
19
|
+
# as STDxxx can only be used after io.rb is
|
20
|
+
# compiled
|
21
|
+
STDIN.fd = WASI::STDIN_FD
|
22
|
+
STDOUT.fd = WASI::STDOUT_FD
|
23
|
+
STDERR.fd = WASI::STDERR_FD
|
24
|
+
$stdin = STDIN
|
25
|
+
$stdout = STDOUT
|
26
|
+
$stderr = STDERR
|
27
|
+
errno
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Rubinius WebAssembly VM
|
2
|
+
# Copyright (c) 2019-2020, Laurent Julliard and contributors
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Rlang core library classes and modules
|
6
|
+
#
|
7
|
+
|
8
|
+
require_relative './memory'
|
9
|
+
require_relative './unistd'
|
10
|
+
require_relative './malloc'
|
11
|
+
require_relative './object'
|
12
|
+
require_relative './kernel'
|
13
|
+
require_relative './string'
|
14
|
+
require_relative './array'
|
15
|
+
require_relative './type'
|