rlang 0.4.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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'