Class: Ruby2CExtension::CFunction::Block
- Inherits:
-
Base
show all
- Defined in:
- lib/ruby2cext/c_function.rb
Constant Summary
Ruby2CExtension::CommonNodeComp::NON_ITER_PROC
Instance Attribute Summary
Attributes inherited from Base
#closure_tbl, #compiler, #need_class, #need_cref, #need_res, #need_self, #need_wrap, #scope
Class Method Summary
collapse
Instance Method Summary
collapse
Methods inherited from Base
#add_closure_need, #add_helper, #assign_res, #closure_buid_c_code, #comp_retry, #comp_return, #get_cbase, #get_class, #get_closure_ary_var, #get_cref, #get_cvar_cbase, #get_lines, #get_self, #get_wrap_ptr, #global_const, #global_var, #in_while?, #initialize, #l, #pop_while, #push_while, #return_allowed?, #sym, #un, #wrap_buid_c_code
#ensure_node_type
#build_args, #build_c_arr, #c_else, #c_for, #c_if, #c_scope, #c_scope_res, #c_static_once, #comp, #comp_alias, #comp_and, #comp_argscat, #comp_argspush, #comp_array, #comp_attrasgn, #comp_back_ref, #comp_begin, #comp_block, #comp_block_pass, #comp_call, #comp_case, #comp_cdecl, #comp_class, #comp_colon2, #comp_colon3, #comp_const, #comp_cvar, #comp_cvasgn, #comp_cvdecl, #comp_dasgn, #comp_dasgn_curr, #comp_defined, #comp_defn, #comp_defs, #comp_dot2, #comp_dot3, #comp_dregx, #comp_dregx_once, #comp_dstr, #comp_dsym, #comp_dvar, #comp_dxstr, #comp_ensure, #comp_evstr, #comp_false, #comp_fcall, #comp_flip2, #comp_flip3, #comp_for, #comp_gasgn, #comp_gvar, #comp_hash, #comp_iasgn, #comp_if, #comp_iter, #comp_ivar, #comp_lasgn, #comp_lit, #comp_lvar, #comp_masgn, #comp_match, #comp_match2, #comp_match3, #comp_module, #comp_nil, #comp_not, #comp_nth_ref, #comp_op_asgn1, #comp_op_asgn2, #comp_op_asgn_and, #comp_op_asgn_or, #comp_or, #comp_postexe, #comp_rescue, #comp_retry, #comp_return, #comp_sclass, #comp_self, #comp_splat, #comp_str, #comp_super, #comp_svalue, #comp_to_ary, #comp_true, #comp_undef, #comp_until, #comp_valias, #comp_vcall, #comp_when, #comp_while, #comp_xstr, #comp_yield, #comp_zarray, #comp_zsuper, #do_funcall, #get_global_entry, #handle_assign, #handle_dot, #handle_dyn_str, #handle_flip, #handle_iter, #handle_method_args, #handle_when, #helper_class_module_check, #helper_super_allowed_check, #make_block, #make_class_prefix
Class Method Details
.compile(outer, block_node, var_node) ⇒ Object
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
|
# File 'lib/ruby2cext/c_function.rb', line 326
def self.compile(outer, block_node, var_node)
ensure_node_type(block_node, :block)
cf = self.new(outer.compiler, outer.scope.new_dyna_scope)
cf.instance_eval {
if Array === var_node
if var_node.first == :masgn
dup_hash = var_node.last.dup
c_if("ruby_current_node->nd_state != 1") { c_if("bl_val == Qundef") {
l "bl_val = rb_ary_new2(0);"
}
c_else {
l "VALUE tmp = rb_check_array_type(bl_val);"
l "bl_val = (NIL_P(tmp) ? rb_ary_new3(1, bl_val) : tmp);"
}
}
dup_hash[:value] = "bl_val"
comp_masgn(dup_hash)
else
c_if("ruby_current_node->nd_state == 1") { l "if (RARRAY(bl_val)->len == 0) bl_val = Qnil;"
l "else if (RARRAY(bl_val)->len == 1) bl_val = RARRAY(bl_val)->ptr[0];"
}
handle_assign(var_node, "bl_val")
end
end
l "block_redo:"
l "return #{comp_block(block_node.last)};"
}
body = "#{cf.init_c_code(outer)}\n#{cf.get_lines}"
sig = "static VALUE FUNNAME(VALUE bl_val, VALUE closure_ary, VALUE bl_self) {"
fname = cf.compiler.add_fun("#{sig}\n#{body}\n}", "block")
[fname, cf.need_closure_ptr]
end
|
Instance Method Details
#break_allowed?(with_value) ⇒ Boolean
392
393
394
|
# File 'lib/ruby2cext/c_function.rb', line 392
def break_allowed?(with_value)
super || !with_value
end
|
#comp_break(hash) ⇒ Object
395
396
397
398
399
400
401
402
403
|
# File 'lib/ruby2cext/c_function.rb', line 395
def comp_break(hash)
if in_while?(:break)
super
else
raise Ruby2CExtError::NotSupported, "break with a value is not supported in a block" if hash[:stts]
l "rb_iter_break();"
"Qnil"
end
end
|
#comp_next(hash) ⇒ Object
408
409
410
411
412
413
414
415
|
# File 'lib/ruby2cext/c_function.rb', line 408
def comp_next(hash)
if in_while?(:next)
super
else
l "return #{comp(hash[:stts])};"
"Qnil"
end
end
|
#comp_redo(hash) ⇒ Object
420
421
422
423
424
425
426
427
|
# File 'lib/ruby2cext/c_function.rb', line 420
def comp_redo(hash)
if in_while?(:redo)
super
else
l "goto block_redo;"
"Qnil"
end
end
|
#get_cref_impl ⇒ Object
433
434
435
|
# File 'lib/ruby2cext/c_function.rb', line 433
def get_cref_impl
"cref"
end
|
#init_c_code(outer) ⇒ Object
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
|
# File 'lib/ruby2cext/c_function.rb', line 367
def init_c_code(outer)
cb_c_code = closure_buid_c_code outer.add_closure_need(:self) if need_self
outer.add_closure_need(:class) if need_class
outer.add_closure_need(:cref) if need_cref
res = []
res << "VALUE res;" if need_res
if need_closure_ptr
res << "VALUE *closure = RARRAY(closure_ary)->ptr;"
end
res << "VALUE self = (bl_self == Qundef ? closure[#{outer.closure_tbl.index(:self)}] : bl_self);" if need_self
res << "VALUE s_class = (bl_self == Qundef ? closure[#{outer.closure_tbl.index(:class)}] : ruby_class);" if need_class
if need_cref
res << "NODE *cref = (Check_Type(closure[#{outer.closure_tbl.index(:cref)}]," +
" T_DATA), (NODE*)DATA_PTR(closure[#{outer.closure_tbl.index(:cref)}]));"
end
res << "VALUE #{get_closure_ary_var};" if cb_c_code
res << "struct wrap the_wrap;" if need_wrap
res << scope.init_c_code
res << cb_c_code if cb_c_code
res << wrap_buid_c_code if need_wrap
res.compact.join("\n")
end
|
#need_closure_ptr ⇒ Object
429
430
431
|
# File 'lib/ruby2cext/c_function.rb', line 429
def need_closure_ptr
scope.need_closure || need_self || need_class || need_cref
end
|
#next_allowed? ⇒ Boolean
405
406
407
|
# File 'lib/ruby2cext/c_function.rb', line 405
def next_allowed?
true
end
|
#redo_allowed? ⇒ Boolean
417
418
419
|
# File 'lib/ruby2cext/c_function.rb', line 417
def redo_allowed?
true
end
|