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.



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

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.



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

def base_scope
  @base_scope
end

#closure_tblObject

Returns the value of attribute closure_tbl.



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

def closure_tbl
  @closure_tbl
end

#depthObject (readonly)

Returns the value of attribute depth.



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

def depth
  @depth
end

#need_closureObject

Returns the value of attribute need_closure.



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

def need_closure
  @need_closure
end

#need_heapObject

Returns the value of attribute need_heap.



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

def need_heap
  @need_heap
end

#outer_scopeObject (readonly)

Returns the value of attribute outer_scope.



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

def outer_scope
  @outer_scope
end

#tblObject (readonly)

Returns the value of attribute tbl.



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

def tbl
  @tbl
end

Instance Method Details

#add_closure_need(need) ⇒ Object



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

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



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

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



106
107
108
# File 'lib/ruby2cext/scopes.rb', line 106

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

#get_dvar(sym) ⇒ Object



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

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



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

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



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

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

#get_lvar(sym) ⇒ Object

Raises:



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

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

#get_lvar_aryObject



118
119
120
# File 'lib/ruby2cext/scopes.rb', line 118

def get_lvar_ary
	get_closure_ary(:lvar)
end

#get_lvar_idx(i) ⇒ Object

Raises:



110
111
112
113
# File 'lib/ruby2cext/scopes.rb', line 110

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



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

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



166
167
168
# File 'lib/ruby2cext/scopes.rb', line 166

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

#outer_closure_tblObject



91
92
93
# File 'lib/ruby2cext/scopes.rb', line 91

def outer_closure_tbl
	(outer_scope || base_scope).closure_tbl
end

#var_ptr_for_wrapObject



170
171
172
# File 'lib/ruby2cext/scopes.rb', line 170

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

#vmodeObject

blocks always has public vmode



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

def vmode
	:public
end

#vmode_def_funObject



162
163
164
# File 'lib/ruby2cext/scopes.rb', line 162

def vmode_def_fun
	"rb_define_method"
end

#vmode_method?(method_id) ⇒ Boolean

Returns:

  • (Boolean)


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

def vmode_method?(method_id)
	false
end