/
laser_object.rb
69 lines (60 loc) · 2.09 KB
/
laser_object.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
module Laser
module Analysis
# Catch all representation of an object. Should never have klass <: Module.
class LaserObject
extend ModuleExtensions
attr_reader :scope, :klass, :name
attr_writer :singleton_class
def initialize(klass = ClassRegistry['Object'], scope = Scope::GlobalScope,
name = "#<#{klass.path}:#{object_id.to_s(16)}>")
@klass = klass
@scope = scope
@name = name
@instance_variables = Hash.new do |h, k|
h[k] = Bindings::InstanceVariableBinding.new(k, nil)
end
end
def add_instance_method!(method)
singleton_class.add_instance_method!(method)
end
def inspect
return 'main' if self == Scope::GlobalScope.self_ptr
super
end
alias path name
def normal_class
if @singleton_class
return @singleton_class.superclass
else
return @klass
end
end
def singleton_class
return @singleton_class if @singleton_class
new_scope = ClosedScope.new(self.scope, nil)
@singleton_class = LaserSingletonClass.new(
ClassRegistry['Class'], new_scope, "Class:#{name}", self) do |new_singleton_class|
new_singleton_class.superclass = self.klass
end
@klass = @singleton_class
end
def laser_simulate(method, args, opts={})
opts = {self: self, mutation: false}.merge(opts)
method = klass.instance_method(method)
method.master_cfg.dup.simulate(args, opts.merge(method: method))
end
def instance_variable_defined?(var)
@instance_variables.has_key?(var)
end
def instance_variable_get(var)
@instance_variables[var].value
end
def instance_variable_set(var, value)
normal_class.instance_variable(var).inferred_type =
Types::UnionType.new([normal_class.instance_variable(var).expr_type,
Utilities.normal_class_for(value).as_type])
@instance_variables[var].bind!(value)
end
end
end
end