rlang 0.4.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -3
  3. data/Gemfile.lock +4 -6
  4. data/README +11 -0
  5. data/README.md +18 -10
  6. data/bin/rlang +17 -5
  7. data/docs/RlangCompiler.md +5 -1
  8. data/docs/RlangManual.md +98 -20
  9. data/examples/fib/fib.rb +5 -1
  10. data/lib/builder/rlang/compiler.rb +2 -21
  11. data/lib/rlang/lib/array/array32.rb +59 -0
  12. data/lib/rlang/lib/array/array64.rb +56 -0
  13. data/lib/rlang/lib/array.rb +6 -0
  14. data/lib/rlang/lib/base64.rb +223 -0
  15. data/lib/rlang/lib/io.rb +75 -0
  16. data/lib/rlang/lib/kernel.rb +23 -0
  17. data/lib/rlang/lib/malloc.rb +12 -8
  18. data/lib/rlang/lib/memory.rb +102 -2
  19. data/lib/rlang/lib/object.rb +40 -4
  20. data/lib/rlang/lib/rlang.rb +29 -0
  21. data/lib/rlang/lib/rlang_core.rb +15 -0
  22. data/lib/rlang/lib/string.rb +106 -8
  23. data/lib/rlang/lib/type/i32.rb +43 -0
  24. data/lib/rlang/lib/type/i64.rb +2 -0
  25. data/lib/rlang/lib/unistd.rb +1 -2
  26. data/lib/rlang/lib/wasi.rb +184 -0
  27. data/lib/rlang/parser/attr.rb +9 -13
  28. data/lib/rlang/parser/const.rb +105 -1
  29. data/lib/rlang/parser/cvar.rb +11 -7
  30. data/lib/rlang/parser/data.rb +17 -6
  31. data/lib/rlang/parser/export.rb +4 -3
  32. data/lib/rlang/parser/ext/integer.rb +3 -1
  33. data/lib/rlang/parser/ext/type.rb +30 -1
  34. data/lib/rlang/parser/global.rb +10 -2
  35. data/lib/rlang/parser/ivar.rb +3 -7
  36. data/lib/rlang/parser/klass.rb +8 -35
  37. data/lib/rlang/parser/method.rb +36 -12
  38. data/lib/rlang/parser/module.rb +143 -0
  39. data/lib/rlang/parser/wgenerator.rb +462 -168
  40. data/lib/rlang/parser/wnode.rb +387 -142
  41. data/lib/rlang/parser/wtype.rb +30 -7
  42. data/lib/rlang/parser.rb +506 -231
  43. data/lib/rlang/version.rb +1 -1
  44. data/lib/rlang.rb +3 -0
  45. data/lib/ruby/mirror/rstring.rb +16 -0
  46. data/lib/utils/exceptions.rb +12 -0
  47. data/rlang.gemspec +4 -4
  48. metadata +25 -13
  49. 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,6 @@
1
+ # Rubinius WebAssembly VM
2
+ # Copyright (c) 2019, Laurent Julliard and contributors
3
+ # All rights reserved.
4
+ #
5
+ require_relative './array/array32'
6
+ require_relative './array/array64'
@@ -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
@@ -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
@@ -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
- require 'rlang/lib/memory'
12
- require 'rlang/lib/unistd'
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 sepcial meaning
34
- # Allocate 20 bytes (5 x I32 integers)
35
- DAta[:dummy_malloc_data] = [0, 0, 0, 0, 0]
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: :I32
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
- local p: :Header, prevp: :Header
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: :I32
127
+ arg ap: :UI32
124
128
  result :none
125
129
  local bp: :Header, p: :Header
126
130
 
@@ -1,4 +1,9 @@
1
- require 'rlang/lib/type'
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
@@ -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
- # don't use allocate as a name to avoid
5
- # colliding with Ruby native method in
6
- # Rlang simulator
7
- def self.alloc(nbytes)
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'