Class: Ruby2CExtension::Scopes::DynaScope

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby2cext/scopes.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base_scope, outer_scope, depth) ⇒ DynaScope

Returns a new instance of DynaScope.



79
80
81
82
83
84
85
# File 'lib/ruby2cext/scopes.rb', line 79

def initialize(base_scope, outer_scope, depth)
	@base_scope = base_scope
	@outer_scope = outer_scope
	@depth = depth
	@closure_tbl = nil # must be set by user
	@tbl = []
end

Instance Attribute Details

#base_scopeObject (readonly)

Returns the value of attribute base_scope.



86
87
88
# File 'lib/ruby2cext/scopes.rb', line 86

def base_scope
  @base_scope
end

#closure_tblObject

Returns the value of attribute closure_tbl.



87
88
89
# File 'lib/ruby2cext/scopes.rb', line 87

def closure_tbl
  @closure_tbl
end

#depthObject (readonly)

Returns the value of attribute depth.



86
87
88
# File 'lib/ruby2cext/scopes.rb', line 86

def depth
  @depth
end

#need_closureObject

Returns the value of attribute need_closure.



87
88
89
# File 'lib/ruby2cext/scopes.rb', line 87

def need_closure
  @need_closure
end

#need_heapObject

Returns the value of attribute need_heap.



87
88
89
# File 'lib/ruby2cext/scopes.rb', line 87

def need_heap
  @need_heap
end

#outer_scopeObject (readonly)

Returns the value of attribute outer_scope.



86
87
88
# File 'lib/ruby2cext/scopes.rb', line 86

def outer_scope
  @outer_scope
end

#tblObject (readonly)

Returns the value of attribute tbl.



86
87
88
# File 'lib/ruby2cext/scopes.rb', line 86

def tbl
  @tbl
end

Instance Method Details

#add_closure_need(need) ⇒ Object



92
93
94
95
96
97
98
99
# File 'lib/ruby2cext/scopes.rb', line 92

def add_closure_need(need)
	# need is in [1, self.depth) or :lvar
	unless need == :lvar || (1...depth) === need
		raise Ruby2CExtError::Bug, "unexpected needed closure vars: #{need}"
	end
	self.need_closure = true
	outer_closure_tbl << need unless outer_closure_tbl.include? need
end

#get_closure_ary(clos_idx) ⇒ Object



100
101
102
103
# File 'lib/ruby2cext/scopes.rb', line 100

def get_closure_ary(clos_idx)
	add_closure_need(clos_idx)
	"closure[#{outer_closure_tbl.index(clos_idx)}]"
end

#get_closure_var(clos_idx, var_idx) ⇒ Object



104
105
106
# File 'lib/ruby2cext/scopes.rb', line 104

def get_closure_var(clos_idx, var_idx)
	"RARRAY(#{get_closure_ary(clos_idx)})->ptr[#{var_idx}]"
end

#get_dvar(sym) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/ruby2cext/scopes.rb', line 120

def get_dvar(sym)
	if tbl.include?(sym)
		return get_dvar_curr(sym)
	end
	cur = self
	while (cur = cur.outer_scope)
		if (i = cur.tbl.index(sym))
			return get_closure_var(cur.depth, i)
		end
	end
	# Ruby versions <= 1.8.5 should/will never reach here
	# (otherwise it is a bug in the parser).
	# But starting after 1.8.5 dvars are only initialized, if there
	# is an assignment in a sub-block. Because of that we can reach
	# here, in that case we want a new dvar_curr:
	get_dvar_curr(sym)
end

#get_dvar_ary(idx) ⇒ Object



144
145
146
147
148
149
150
151
# File 'lib/ruby2cext/scopes.rb', line 144

def get_dvar_ary(idx)
	if idx == depth
		self.need_heap = true
		"dvar_ary"
	else
		get_closure_ary(idx)
	end
end

#get_dvar_curr(sym) ⇒ Object



137
138
139
140
141
142
143
# File 'lib/ruby2cext/scopes.rb', line 137

def get_dvar_curr(sym)
	unless (i = tbl.index(sym))
		i = tbl.size
		tbl << sym
	end
	"dvar[#{i}]"
end

#get_lvar(sym) ⇒ Object

Raises:



112
113
114
115
# File 'lib/ruby2cext/scopes.rb', line 112

def get_lvar(sym)
	raise Ruby2CExtError, "unknown lvar: #{sym}" unless (i = base_scope.tbl.index(sym))
	get_lvar_idx(i)
end

#get_lvar_aryObject



116
117
118
# File 'lib/ruby2cext/scopes.rb', line 116

def get_lvar_ary
	get_closure_ary(:lvar)
end

#get_lvar_idx(i) ⇒ Object

Raises:



108
109
110
111
# File 'lib/ruby2cext/scopes.rb', line 108

def get_lvar_idx(i)
	raise Ruby2CExtError, "wrong lvar index: #{i}" unless i >= 0 && i < base_scope.tbl.size
	get_closure_var(:lvar, i)
end

#init_c_codeObject



172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/ruby2cext/scopes.rb', line 172

def init_c_code
	return nil if tbl.empty?
	res = []
	if need_heap
		res << "VALUE *dvar;"
		res << "VALUE dvar_ary = rb_ary_new2(#{tbl.size});"
		res << "rb_mem_clear(RARRAY(dvar_ary)->ptr, #{tbl.size});"
		res << "RARRAY(dvar_ary)->len = #{tbl.size};"
		res << "dvar = RARRAY(dvar_ary)->ptr;"
	else
		res << "VALUE dvar[#{tbl.size}];\nrb_mem_clear(dvar, #{tbl.size});"
	end
	res.join("\n")
end

#new_dyna_scopeObject



164
165
166
# File 'lib/ruby2cext/scopes.rb', line 164

def new_dyna_scope
	DynaScope.new(base_scope, self, depth + 1)
end

#outer_closure_tblObject



89
90
91
# File 'lib/ruby2cext/scopes.rb', line 89

def outer_closure_tbl
	(outer_scope || base_scope).closure_tbl
end

#var_ptr_for_wrapObject



168
169
170
# File 'lib/ruby2cext/scopes.rb', line 168

def var_ptr_for_wrap
	tbl.empty? ? nil : "dvar"
end

#vmodeObject

blocks always has public vmode



154
155
156
# File 'lib/ruby2cext/scopes.rb', line 154

def vmode
	:public
end

#vmode_def_funObject



160
161
162
# File 'lib/ruby2cext/scopes.rb', line 160

def vmode_def_fun
	"rb_define_method"
end

#vmode_method?(method_id) ⇒ Boolean

Returns:

  • (Boolean)


157
158
159
# File 'lib/ruby2cext/scopes.rb', line 157

def vmode_method?(method_id)
	false
end