rlang 0.4.1 → 0.5.0

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