rlang 0.4.1 → 0.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -1
- data/Gemfile.lock +1 -1
- data/README.md +15 -9
- data/docs/RlangManual.md +26 -4
- data/lib/rlang/lib/array/array32.rb +43 -0
- data/lib/rlang/lib/array/array64.rb +43 -0
- data/lib/rlang/lib/array.rb +6 -0
- data/lib/rlang/lib/kernel.rb +18 -0
- data/lib/rlang/lib/malloc.rb +5 -3
- data/lib/rlang/lib/memory.rb +102 -2
- data/lib/rlang/lib/object.rb +11 -4
- data/lib/rlang/lib/string.rb +1 -0
- data/lib/rlang/lib/unistd.rb +1 -2
- data/lib/rlang/lib.rb +4 -2
- data/lib/rlang/parser/attr.rb +9 -13
- data/lib/rlang/parser/const.rb +105 -1
- data/lib/rlang/parser/cvar.rb +10 -6
- data/lib/rlang/parser/data.rb +5 -2
- data/lib/rlang/parser/ivar.rb +3 -7
- data/lib/rlang/parser/klass.rb +8 -35
- data/lib/rlang/parser/method.rb +22 -11
- data/lib/rlang/parser/module.rb +143 -0
- data/lib/rlang/parser/wgenerator.rb +190 -90
- data/lib/rlang/parser/wnode.rb +296 -121
- data/lib/rlang/parser/wtype.rb +18 -1
- data/lib/rlang/parser.rb +224 -113
- data/lib/rlang/version.rb +1 -1
- metadata +7 -2
data/lib/rlang/parser/cvar.rb
CHANGED
@@ -12,17 +12,21 @@ require_relative './data'
|
|
12
12
|
module Rlang::Parser
|
13
13
|
class CVar
|
14
14
|
include Log
|
15
|
-
attr_reader :name, :
|
15
|
+
attr_reader :name, :klass
|
16
16
|
attr_accessor :wtype
|
17
17
|
|
18
|
-
def initialize(
|
18
|
+
def initialize(klass, name, value=0, wtype=WType::DEFAULT)
|
19
|
+
@klass = klass
|
19
20
|
@name = name
|
20
|
-
@class_name = class_name
|
21
21
|
@wtype = wtype
|
22
22
|
# Allocate and initialize the new cvar
|
23
|
-
raise "Error:
|
24
|
-
@data = DAta.new(self.wasm_name.to_sym, value, wtype)
|
25
|
-
logger.debug "creating #{self.class} #{class_name}::#{name} @ #{@address} with value #{value} / wtype #{wtype}"
|
23
|
+
raise "Error: #{self.class} #{self.wasm_name} already created!" if DAta.exist? self.wasm_name.to_sym
|
24
|
+
@data = DAta.new(self.wasm_name.to_sym, value, wtype) unless wtype.name == :Class
|
25
|
+
logger.debug "creating #{self.class} #{self.class_name}::#{name} @ #{@address} with value #{value} / wtype #{wtype}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def class_name
|
29
|
+
@klass.name
|
26
30
|
end
|
27
31
|
|
28
32
|
def address
|
data/lib/rlang/parser/data.rb
CHANGED
@@ -23,13 +23,14 @@ module Rlang::Parser
|
|
23
23
|
def initialize(label, value, wtype=WType::DEFAULT)
|
24
24
|
raise "Data label '#{label}' already initialized" \
|
25
25
|
if self.class.exist? label
|
26
|
+
logger.debug "@@current_address: #{@@current_address}"
|
26
27
|
@label = label
|
27
28
|
@wtype = wtype
|
28
29
|
@address = @@current_address
|
29
30
|
@@label_table[@label] = self
|
30
31
|
@value = []
|
31
32
|
self.append_value(value, wtype)
|
32
|
-
logger.debug "New Data[#{@label}] initialized with #{@value} at address #{@address}"
|
33
|
+
logger.debug "New Data[#{@label}] initialized with #{@value} at address #{@address} / new current address: #{@@current_address}"
|
33
34
|
end
|
34
35
|
|
35
36
|
def self.reset!
|
@@ -39,7 +40,7 @@ module Rlang::Parser
|
|
39
40
|
|
40
41
|
def append_value(value, wtype)
|
41
42
|
@value << value
|
42
|
-
if value.is_a?
|
43
|
+
if value.is_a? String
|
43
44
|
@@current_address += value.length
|
44
45
|
else
|
45
46
|
logger.warn "Data type #{@wtype} misaligned!!! (Data[:#{@label}] value #{value} at address #{@address}" \
|
@@ -71,6 +72,8 @@ module Rlang::Parser
|
|
71
72
|
end
|
72
73
|
|
73
74
|
def self.address=(address)
|
75
|
+
logger.fatal "ERROR!! Cannot decrease current DAta address (was #{@@current_address}, got #{address}) " \
|
76
|
+
if address < @@current_address
|
74
77
|
@@current_address = address
|
75
78
|
end
|
76
79
|
|
data/lib/rlang/parser/ivar.rb
CHANGED
@@ -11,11 +11,11 @@ require_relative './data'
|
|
11
11
|
module Rlang::Parser
|
12
12
|
class IVar
|
13
13
|
include Log
|
14
|
-
attr_reader :name
|
14
|
+
attr_reader :name, :klass
|
15
15
|
attr_accessor :wtype, :offset
|
16
16
|
|
17
|
-
def initialize(
|
18
|
-
@
|
17
|
+
def initialize(klass, name, wtype=WType::DEFAULT)
|
18
|
+
@klass = klass
|
19
19
|
@name = name
|
20
20
|
@wtype = wtype
|
21
21
|
# this is the offset of the instance variable
|
@@ -26,10 +26,6 @@ module Rlang::Parser
|
|
26
26
|
logger.debug "Instance variable #{name} created"
|
27
27
|
end
|
28
28
|
|
29
|
-
def class_name
|
30
|
-
@class_wnode.class_name
|
31
|
-
end
|
32
|
-
|
33
29
|
def size
|
34
30
|
@wtype.size
|
35
31
|
end
|
data/lib/rlang/parser/klass.rb
CHANGED
@@ -1,52 +1,25 @@
|
|
1
1
|
# Rubinius WebAssembly VM
|
2
|
-
# Copyright (c) 2019, Laurent Julliard and contributors
|
2
|
+
# Copyright (c) 2019-2020, Laurent Julliard and contributors
|
3
3
|
# All rights reserved.
|
4
4
|
|
5
5
|
# Rlang classes
|
6
6
|
require_relative '../../utils/log'
|
7
7
|
require_relative './wtype'
|
8
|
+
require_relative './const'
|
9
|
+
require_relative './module'
|
8
10
|
|
9
11
|
module Rlang::Parser
|
10
12
|
# Note: Cannot use Class as class name
|
11
13
|
# because it's already used by Ruby
|
12
|
-
class Klass
|
14
|
+
class Klass < Module
|
13
15
|
include Log
|
14
16
|
|
15
|
-
|
16
|
-
attr_accessor :name, :wnode, :attrs, :ivars, :cvars,
|
17
|
-
:consts, :methods, :offset
|
17
|
+
attr_accessor :super_class
|
18
18
|
|
19
|
-
def initialize(
|
20
|
-
|
21
|
-
|
22
|
-
@wtype = WType.new(name)
|
23
|
-
@size = 0
|
24
|
-
# the wnode implementing the code of the class
|
25
|
-
@wnode = nil
|
26
|
-
logger.debug "Klass created #{self.inspect}"
|
27
|
-
@attrs = [] # class attributes
|
28
|
-
@ivars = [] # instance variables
|
29
|
-
@cvars = [] # class variables
|
30
|
-
@consts = [] # class constants
|
31
|
-
@methods = [] # methods
|
32
|
-
@offset = 0 # offset of the next class attribute in memory
|
19
|
+
def initialize(const, scope_class, super_class)
|
20
|
+
super(const, scope_class)
|
21
|
+
self.super_class = super_class
|
33
22
|
end
|
34
23
|
|
35
|
-
def size
|
36
|
-
@offset
|
37
|
-
end
|
38
|
-
|
39
|
-
def wtype=(wtype)
|
40
|
-
@wtype = wtype
|
41
|
-
logger.debug "Klass #{@name} wtype updated: #{self.inspect}"
|
42
|
-
end
|
43
|
-
|
44
|
-
def wasm_name
|
45
|
-
@name
|
46
|
-
end
|
47
|
-
|
48
|
-
def wasm_type
|
49
|
-
@wtype.wasm_type
|
50
|
-
end
|
51
24
|
end
|
52
25
|
end
|
data/lib/rlang/parser/method.rb
CHANGED
@@ -13,24 +13,31 @@ module Rlang::Parser
|
|
13
13
|
class MEthod
|
14
14
|
include Log
|
15
15
|
|
16
|
-
attr_reader :name, :wtype
|
17
|
-
attr_accessor :
|
16
|
+
attr_reader :name, :wtype, :method_type, :wnode
|
17
|
+
attr_accessor :klass, :margs, :lvars
|
18
18
|
|
19
|
-
METHOD_TYPES = [:
|
19
|
+
METHOD_TYPES = [:instance, :class]
|
20
20
|
|
21
|
-
def initialize(name,
|
21
|
+
def initialize(name, klass, wtype, method_type)
|
22
22
|
raise "Wrong method wtype argument: #{wtype.inspect}" unless wtype.is_a? WType
|
23
23
|
@name = name
|
24
|
-
@
|
24
|
+
@klass = klass
|
25
25
|
@wtype = wtype || WType::DEFAULT
|
26
26
|
@method_type = method_type
|
27
27
|
raise "Unknown method type: #{method_type}" unless METHOD_TYPES.include? @method_type
|
28
|
-
@wnode = nil
|
29
|
-
logger.debug "Method created #{
|
28
|
+
@wnode = nil # wnode where this method is implemented
|
29
|
+
logger.debug "Method created #{name} in class #{klass.name} / ID:#{self}"
|
30
30
|
@margs = [] # method args
|
31
31
|
@lvars = [] # local variables
|
32
32
|
end
|
33
33
|
|
34
|
+
# Setup bidirectional links between
|
35
|
+
# wnode and method
|
36
|
+
def wnode=(wnode)
|
37
|
+
@wnode = wnode
|
38
|
+
wnode.method = self
|
39
|
+
end
|
40
|
+
|
34
41
|
def implemented?
|
35
42
|
!@wnode.nil?
|
36
43
|
end
|
@@ -58,10 +65,12 @@ module Rlang::Parser
|
|
58
65
|
end
|
59
66
|
|
60
67
|
def wasm_name
|
68
|
+
# [] method name is illegal in Wasm function name
|
69
|
+
name = @name.to_s.sub(/\[\]/, 'brackets').to_sym
|
61
70
|
if self.instance?
|
62
|
-
"$#{@
|
71
|
+
"$#{@klass.path_name}##{name}"
|
63
72
|
else
|
64
|
-
"$#{@
|
73
|
+
"$#{@klass.path_name}::#{name}"
|
65
74
|
end
|
66
75
|
end
|
67
76
|
|
@@ -70,10 +79,12 @@ module Rlang::Parser
|
|
70
79
|
end
|
71
80
|
|
72
81
|
def export_name
|
82
|
+
# [] method name is illegal in Wasm function name
|
83
|
+
name = @name.to_s.sub(/\[\]/, 'brackets').to_sym
|
73
84
|
if self.instance?
|
74
|
-
"#{@
|
85
|
+
"#{@klass.path_name.downcase}_i_#{name}"
|
75
86
|
else
|
76
|
-
"#{@
|
87
|
+
"#{@klass.path_name.downcase}_c_#{name}"
|
77
88
|
end
|
78
89
|
end
|
79
90
|
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# Rubinius WebAssembly VM
|
2
|
+
# Copyright (c) 2019, Laurent Julliard and contributors
|
3
|
+
# All rights reserved.
|
4
|
+
|
5
|
+
# Rlang classes
|
6
|
+
require_relative '../../utils/log'
|
7
|
+
require_relative './const'
|
8
|
+
|
9
|
+
module Rlang::Parser
|
10
|
+
class Module
|
11
|
+
include Log
|
12
|
+
|
13
|
+
attr_reader :wtype, :const
|
14
|
+
attr_accessor :wnode, :attrs, :ivars, :cvars,
|
15
|
+
:consts, :methods, :offset,
|
16
|
+
:includes, :extends
|
17
|
+
|
18
|
+
def initialize(const, scope_class)
|
19
|
+
@const = const
|
20
|
+
# upper lexical class or module
|
21
|
+
logger.debug "scope_class: #{scope_class}"
|
22
|
+
@const.scope_class = scope_class
|
23
|
+
# the wtype of a Class/Module is either :Class or :Module
|
24
|
+
@wtype = WType.new(@const.path_name)
|
25
|
+
# memory space used by ivars in bytes
|
26
|
+
@size = 0
|
27
|
+
# the wnode implementing the code of the class
|
28
|
+
@wnode = nil
|
29
|
+
@super_class = nil
|
30
|
+
@attrs = [] # class attributes
|
31
|
+
@ivars = [] # instance variables
|
32
|
+
@cvars = [] # class variables
|
33
|
+
# Note: the consts list is fed from the Const class
|
34
|
+
# on purpose so that it applies to any constant not jus
|
35
|
+
# Classes and modules
|
36
|
+
@consts = [] # class constants
|
37
|
+
@methods = [] # methods
|
38
|
+
@offset = 0 # memory offset of next ivar
|
39
|
+
|
40
|
+
# Modules included/extended/prepended in
|
41
|
+
# this module/class
|
42
|
+
@modules = [] # all modules included, prepended, extended
|
43
|
+
@includes = [] # modules included
|
44
|
+
@prepends = [] # modules prepended
|
45
|
+
@extends = [] # modules extended
|
46
|
+
|
47
|
+
# Is this module extended, included, prepended ?
|
48
|
+
@extended = false
|
49
|
+
@included = false
|
50
|
+
@prepended = false
|
51
|
+
|
52
|
+
# Associated constant/value points to the class/module
|
53
|
+
@const.value = self
|
54
|
+
logger.debug "Created Class/Module #{@const} / #{self}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def object_class?
|
58
|
+
self.const.name == :Object && self.const.scope_class == self
|
59
|
+
end
|
60
|
+
|
61
|
+
def name
|
62
|
+
@const.name
|
63
|
+
end
|
64
|
+
|
65
|
+
def path
|
66
|
+
@const.path
|
67
|
+
end
|
68
|
+
|
69
|
+
def path_name
|
70
|
+
@const.path_name
|
71
|
+
end
|
72
|
+
|
73
|
+
# Do not include the top class Object in nesting
|
74
|
+
def nesting
|
75
|
+
sk = nil; k = self; n = [k]
|
76
|
+
while (sk = k.const.scope_class) && (sk != k) && !sk.object_class?
|
77
|
+
logger.debug "k: #{k.name}/#{k}, sk: #{sk.name}/#{sk}, sk.object_class? #{sk.object_class?}"
|
78
|
+
n.unshift(sk)
|
79
|
+
k = sk
|
80
|
+
end
|
81
|
+
logger.debug "Class#nesting : #{n.map(&:name)}"
|
82
|
+
n
|
83
|
+
end
|
84
|
+
|
85
|
+
def include(klass)
|
86
|
+
@modules |= [klass]
|
87
|
+
@includes |= [klass]
|
88
|
+
end
|
89
|
+
|
90
|
+
def prepend(klass)
|
91
|
+
@modules |= [klass]
|
92
|
+
@prepends |= [klass]
|
93
|
+
end
|
94
|
+
|
95
|
+
def extend(klass)
|
96
|
+
@modules |= [klass]
|
97
|
+
@extends |= [klass]
|
98
|
+
end
|
99
|
+
|
100
|
+
def ancestors
|
101
|
+
@prepends.reverse + [self] + @includes.reverse + @extends.reverse + \
|
102
|
+
(@super_class ? @super_class.ancestors : [])
|
103
|
+
end
|
104
|
+
|
105
|
+
def const_get(name)
|
106
|
+
consts.find { |c| c.name == name}
|
107
|
+
end
|
108
|
+
|
109
|
+
def delete_instance_methods
|
110
|
+
@methods.select { |m| m.instance? }.each { |m| m.wnode.delete!; @methods.delete(m) }
|
111
|
+
end
|
112
|
+
|
113
|
+
def delete_class_methods
|
114
|
+
self.methods.select { |m| m.class? }.each { |m| m.wnode.delete!; @methods.delete(m) }
|
115
|
+
end
|
116
|
+
|
117
|
+
def size
|
118
|
+
@offset
|
119
|
+
end
|
120
|
+
|
121
|
+
def wtype=(wtype)
|
122
|
+
@wtype = wtype
|
123
|
+
logger.debug "#{self.class} #{@name} wtype updated: #{self.inspect}"
|
124
|
+
end
|
125
|
+
|
126
|
+
def wasm_name
|
127
|
+
@name
|
128
|
+
end
|
129
|
+
|
130
|
+
def wasm_type
|
131
|
+
@wtype.wasm_type
|
132
|
+
end
|
133
|
+
|
134
|
+
def extended?; @extended; end
|
135
|
+
def extended!; @extended = true; end
|
136
|
+
|
137
|
+
def included?; @included; end
|
138
|
+
def included!; @included = true; end
|
139
|
+
|
140
|
+
def prepended?; @prepended; end
|
141
|
+
def prepended!; @prepended = true; end
|
142
|
+
end
|
143
|
+
end
|