Class: Ruby2CExtension::CFunction::Block
- Inherits:
-
Base
- Object
- Base
- Ruby2CExtension::CFunction::Block
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
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
366
367
368
369
|
# File 'lib/ruby2cext/c_function.rb', line 330
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
396
397
398
|
# File 'lib/ruby2cext/c_function.rb', line 396
def break_allowed?(with_value)
super || !with_value
end
|
#comp_break(hash) ⇒ Object
399
400
401
402
403
404
405
406
407
|
# File 'lib/ruby2cext/c_function.rb', line 399
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
412
413
414
415
416
417
418
419
|
# File 'lib/ruby2cext/c_function.rb', line 412
def comp_next(hash)
if in_while?(:next)
super
else
l "return #{comp(hash[:stts])};"
"Qnil"
end
end
|
#comp_redo(hash) ⇒ Object
424
425
426
427
428
429
430
431
|
# File 'lib/ruby2cext/c_function.rb', line 424
def comp_redo(hash)
if in_while?(:redo)
super
else
l "goto block_redo;"
"Qnil"
end
end
|
#get_cref_impl ⇒ Object
437
438
439
|
# File 'lib/ruby2cext/c_function.rb', line 437
def get_cref_impl
"cref"
end
|
#init_c_code(outer) ⇒ Object
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
|
# File 'lib/ruby2cext/c_function.rb', line 371
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
433
434
435
|
# File 'lib/ruby2cext/c_function.rb', line 433
def need_closure_ptr
scope.need_closure || need_self || need_class || need_cref
end
|
#next_allowed? ⇒ Boolean
409
410
411
|
# File 'lib/ruby2cext/c_function.rb', line 409
def next_allowed?
true
end
|
#redo_allowed? ⇒ Boolean
421
422
423
|
# File 'lib/ruby2cext/c_function.rb', line 421
def redo_allowed?
true
end
|