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.
@@ -12,17 +12,21 @@ require_relative './data'
12
12
  module Rlang::Parser
13
13
  class CVar
14
14
  include Log
15
- attr_reader :name, :class_name
15
+ attr_reader :name, :klass
16
16
  attr_accessor :wtype
17
17
 
18
- def initialize(class_name, name, value=0, wtype=WType::DEFAULT)
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: Class variable #{self.wasm_name} already created!" if DAta.exist? self.wasm_name.to_sym
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
@@ -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?(String)
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
 
@@ -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(class_wnode, name, wtype=WType::DEFAULT)
18
- @class_wnode = class_wnode
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
@@ -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
- attr_reader :wtype
16
- attr_accessor :name, :wnode, :attrs, :ivars, :cvars,
17
- :consts, :methods, :offset
17
+ attr_accessor :super_class
18
18
 
19
- def initialize(name)
20
- @name = name
21
- # the type of a class is its name by definition
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
@@ -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 :class_name, :margs, :lvars, :wnode
16
+ attr_reader :name, :wtype, :method_type, :wnode
17
+ attr_accessor :klass, :margs, :lvars
18
18
 
19
- METHOD_TYPES = [:class, :instance]
19
+ METHOD_TYPES = [:instance, :class]
20
20
 
21
- def initialize(name, class_name, wtype, method_type)
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
- @class_name = class_name
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 # wnode where method is implemented
29
- logger.debug "Method created #{self.inspect}"
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
- "$#{@class_name}##{@name}"
71
+ "$#{@klass.path_name}##{name}"
63
72
  else
64
- "$#{@class_name}::#{@name}"
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
- "#{@class_name.downcase}_i_#{@name}"
85
+ "#{@klass.path_name.downcase}_i_#{name}"
75
86
  else
76
- "#{@class_name.downcase}_c_#{@name}"
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