Bindgen immediate types with builtin

This commit is contained in:
Takashi Kokubun 2022-09-20 23:23:50 +09:00
parent 280ff1707e
commit 4c6e1556b1
Notes: git 2022-09-23 06:45:06 +09:00
4 changed files with 99 additions and 61 deletions

View File

@ -27,7 +27,7 @@ module RubyVM::MJIT
end end
module Immediate module Immediate
# @param fiddle_type [Integer] Fiddle::TYPE_* # @param fiddle_type [Integer]
def self.new(fiddle_type) def self.new(fiddle_type)
name = Fiddle.constants.find do |const| name = Fiddle.constants.find do |const|
const.start_with?('TYPE_') && Fiddle.const_get(const) == fiddle_type.abs const.start_with?('TYPE_') && Fiddle.const_get(const) == fiddle_type.abs
@ -40,6 +40,20 @@ module RubyVM::MJIT
CPointer::Immediate.define(fiddle_type) CPointer::Immediate.define(fiddle_type)
end end
end end
# @param type [String]
def self.parse(ctype)
new(Fiddle::Importer.parse_ctype(ctype))
end
def self.find(size, unsigned)
fiddle_type = TYPE_MAP.fetch(size)
fiddle_type = -fiddle_type if unsigned
new(fiddle_type)
end
TYPE_MAP = Fiddle::PackInfo::SIZE_MAP.map { |type, size| [size, type.abs] }.to_h
private_constant :TYPE_MAP
end end
module Bool module Bool

111
mjit_c.rb
View File

@ -1,3 +1,4 @@
# frozen_string_literal: true
# Part of this file is generated by tool/mjit/bindgen.rb. # Part of this file is generated by tool/mjit/bindgen.rb.
# Run `make mjit-bindgen` to update code between "MJIT bindgen begin" and "MJIT bindgen end". # Run `make mjit-bindgen` to update code between "MJIT bindgen begin" and "MJIT bindgen end".
module RubyVM::MJIT module RubyVM::MJIT
@ -175,14 +176,10 @@ module RubyVM::MJIT
@RB_BUILTIN ||= self.rb_builtin_function @RB_BUILTIN ||= self.rb_builtin_function
end end
def C.VALUE
@VALUE ||= CType::Immediate.new(-5)
end
def C.compile_branch def C.compile_branch
@compile_branch ||= CType::Struct.new( @compile_branch ||= CType::Struct.new(
"compile_branch", 8, "compile_branch", 8,
stack_size: [0, CType::Immediate.new(-4)], stack_size: [0, CType::Immediate.parse("unsigned int")],
finish_p: [32, self._Bool], finish_p: [32, self._Bool],
) )
end end
@ -191,16 +188,16 @@ module RubyVM::MJIT
@compile_status ||= CType::Struct.new( @compile_status ||= CType::Struct.new(
"compile_status", 120, "compile_status", 120,
success: [0, self._Bool], success: [0, self._Bool],
stack_size_for_pos: [64, CType::Pointer.new { CType::Immediate.new(4) }], stack_size_for_pos: [64, CType::Pointer.new { CType::Immediate.parse("int") }],
local_stack_p: [128, self._Bool], local_stack_p: [128, self._Bool],
is_entries: [192, CType::Pointer.new { self.iseq_inline_storage_entry }], is_entries: [192, CType::Pointer.new { self.iseq_inline_storage_entry }],
cc_entries_index: [256, CType::Immediate.new(4)], cc_entries_index: [256, CType::Immediate.parse("int")],
compiled_iseq: [320, CType::Pointer.new { self.rb_iseq_constant_body }], compiled_iseq: [320, CType::Pointer.new { self.rb_iseq_constant_body }],
compiled_id: [384, CType::Immediate.new(4)], compiled_id: [384, CType::Immediate.parse("int")],
compile_info: [448, CType::Pointer.new { self.rb_mjit_compile_info }], compile_info: [448, CType::Pointer.new { self.rb_mjit_compile_info }],
merge_ivar_guards_p: [512, self._Bool], merge_ivar_guards_p: [512, self._Bool],
ivar_serial: [576, self.rb_serial_t], ivar_serial: [576, self.rb_serial_t],
max_ivar_index: [640, CType::Immediate.new(-5)], max_ivar_index: [640, CType::Immediate.parse("size_t")],
inlined_iseqs: [704, CType::Pointer.new { CType::Pointer.new { self.rb_iseq_constant_body } }], inlined_iseqs: [704, CType::Pointer.new { CType::Pointer.new { self.rb_iseq_constant_body } }],
inline_context: [768, self.inlined_call_context], inline_context: [768, self.inlined_call_context],
) )
@ -209,10 +206,10 @@ module RubyVM::MJIT
def C.inlined_call_context def C.inlined_call_context
@inlined_call_context ||= CType::Struct.new( @inlined_call_context ||= CType::Struct.new(
"inlined_call_context", 24, "inlined_call_context", 24,
orig_argc: [0, CType::Immediate.new(4)], orig_argc: [0, CType::Immediate.parse("int")],
me: [64, self.VALUE], me: [64, self.VALUE],
param_size: [128, CType::Immediate.new(4)], param_size: [128, CType::Immediate.parse("int")],
local_size: [160, CType::Immediate.new(4)], local_size: [160, CType::Immediate.parse("int")],
) )
end end
@ -262,11 +259,11 @@ module RubyVM::MJIT
save_temps: [8, self._Bool], save_temps: [8, self._Bool],
warnings: [16, self._Bool], warnings: [16, self._Bool],
debug: [24, self._Bool], debug: [24, self._Bool],
debug_flags: [64, CType::Pointer.new { CType::Immediate.new(2) }], debug_flags: [64, CType::Pointer.new { CType::Immediate.parse("char") }],
wait: [128, self._Bool], wait: [128, self._Bool],
min_calls: [160, CType::Immediate.new(-4)], min_calls: [160, CType::Immediate.parse("unsigned int")],
verbose: [192, CType::Immediate.new(4)], verbose: [192, CType::Immediate.parse("int")],
max_cache_size: [224, CType::Immediate.new(4)], max_cache_size: [224, CType::Immediate.parse("int")],
pause: [256, self._Bool], pause: [256, self._Bool],
custom: [264, self._Bool], custom: [264, self._Bool],
) )
@ -275,11 +272,11 @@ module RubyVM::MJIT
def C.rb_builtin_function def C.rb_builtin_function
@rb_builtin_function ||= CType::Struct.new( @rb_builtin_function ||= CType::Struct.new(
"rb_builtin_function", 32, "rb_builtin_function", 32,
func_ptr: [0, CType::Pointer.new { CType::Immediate.new(0) }], func_ptr: [0, CType::Pointer.new { CType::Immediate.parse("void") }],
argc: [64, CType::Immediate.new(4)], argc: [64, CType::Immediate.parse("int")],
index: [96, CType::Immediate.new(4)], index: [96, CType::Immediate.parse("int")],
name: [128, CType::Pointer.new { CType::Immediate.new(2) }], name: [128, CType::Pointer.new { CType::Immediate.parse("char") }],
compiler: [192, CType::Immediate.new(1)], compiler: [192, CType::Immediate.parse("void *")],
) )
end end
@ -311,7 +308,7 @@ module RubyVM::MJIT
call_: [192, self.vm_call_handler], call_: [192, self.vm_call_handler],
aux_: [256, CType::Union.new( aux_: [256, CType::Union.new(
"", 8, "", 8,
attr_index: CType::Immediate.new(-4), attr_index: CType::Immediate.parse("unsigned int"),
method_missing_reason: self.method_missing_reason, method_missing_reason: self.method_missing_reason,
v: self.VALUE, v: self.VALUE,
)], )],
@ -337,9 +334,9 @@ module RubyVM::MJIT
iseq: [128, CType::Pointer.new { self.rb_iseq_t }], iseq: [128, CType::Pointer.new { self.rb_iseq_t }],
self: [192, self.VALUE], self: [192, self.VALUE],
ep: [256, CType::Pointer.new { self.VALUE }], ep: [256, CType::Pointer.new { self.VALUE }],
block_code: [320, CType::Pointer.new { CType::Immediate.new(0) }], block_code: [320, CType::Pointer.new { CType::Immediate.parse("void") }],
__bp__: [384, CType::Pointer.new { self.VALUE }], __bp__: [384, CType::Pointer.new { self.VALUE }],
jit_return: [448, CType::Pointer.new { CType::Immediate.new(0) }], jit_return: [448, CType::Pointer.new { CType::Immediate.parse("void") }],
) )
end end
@ -358,7 +355,7 @@ module RubyVM::MJIT
@rb_execution_context_struct ||= CType::Struct.new( @rb_execution_context_struct ||= CType::Struct.new(
"rb_execution_context_struct", 1, "rb_execution_context_struct", 1,
vm_stack: [-1, CType::Pointer.new { self.VALUE }], vm_stack: [-1, CType::Pointer.new { self.VALUE }],
vm_stack_size: [-1, CType::Immediate.new(-5)], vm_stack_size: [-1, CType::Immediate.parse("size_t")],
cfp: [-1, CType::Pointer.new { self.rb_control_frame_t }], cfp: [-1, CType::Pointer.new { self.rb_control_frame_t }],
tag: [-1, CType::Pointer.new { self.rb_vm_tag }], tag: [-1, CType::Pointer.new { self.rb_vm_tag }],
interrupt_flag: [-1, self.rb_atomic_t], interrupt_flag: [-1, self.rb_atomic_t],
@ -374,15 +371,15 @@ module RubyVM::MJIT
trace_arg: [-1, CType::Pointer.new { self.rb_trace_arg_struct }], trace_arg: [-1, CType::Pointer.new { self.rb_trace_arg_struct }],
errinfo: [-1, self.VALUE], errinfo: [-1, self.VALUE],
passed_block_handler: [-1, self.VALUE], passed_block_handler: [-1, self.VALUE],
raised_flag: [-1, CType::Immediate.new(-2)], raised_flag: [-1, CType::Immediate.parse("uint8_t")],
method_missing_reason: [-1, self.method_missing_reason], method_missing_reason: [-1, self.method_missing_reason],
private_const_reference: [-1, self.VALUE], private_const_reference: [-1, self.VALUE],
machine: [-1, CType::Struct.new( machine: [-1, CType::Struct.new(
"", 1, "", 1,
stack_start: [-1, CType::Pointer.new { self.VALUE }], stack_start: [-1, CType::Pointer.new { self.VALUE }],
stack_end: [-1, CType::Pointer.new { self.VALUE }], stack_end: [-1, CType::Pointer.new { self.VALUE }],
stack_maxsize: [-1, CType::Immediate.new(-5)], stack_maxsize: [-1, CType::Immediate.parse("size_t")],
regs: [-1, CType::Immediate.new(4)], regs: [-1, CType::Immediate.parse("int")],
)], )],
) )
end end
@ -395,7 +392,7 @@ module RubyVM::MJIT
@rb_iseq_constant_body ||= CType::Struct.new( @rb_iseq_constant_body ||= CType::Struct.new(
"rb_iseq_constant_body", 336, "rb_iseq_constant_body", 336,
type: [0, self.rb_iseq_type], type: [0, self.rb_iseq_type],
iseq_size: [32, CType::Immediate.new(-4)], iseq_size: [32, CType::Immediate.parse("unsigned int")],
iseq_encoded: [64, CType::Pointer.new { self.VALUE }], iseq_encoded: [64, CType::Pointer.new { self.VALUE }],
param: [128, CType::Struct.new( param: [128, CType::Struct.new(
"", 48, "", 48,
@ -412,13 +409,13 @@ module RubyVM::MJIT
accepts_no_kwarg: [8, CType::BitField.new(1, 0)], accepts_no_kwarg: [8, CType::BitField.new(1, 0)],
ruby2_keywords: [9, CType::BitField.new(1, 1)], ruby2_keywords: [9, CType::BitField.new(1, 1)],
)], )],
size: [32, CType::Immediate.new(-4)], size: [32, CType::Immediate.parse("unsigned int")],
lead_num: [64, CType::Immediate.new(4)], lead_num: [64, CType::Immediate.parse("int")],
opt_num: [96, CType::Immediate.new(4)], opt_num: [96, CType::Immediate.parse("int")],
rest_start: [128, CType::Immediate.new(4)], rest_start: [128, CType::Immediate.parse("int")],
post_start: [160, CType::Immediate.new(4)], post_start: [160, CType::Immediate.parse("int")],
post_num: [192, CType::Immediate.new(4)], post_num: [192, CType::Immediate.parse("int")],
block_start: [224, CType::Immediate.new(4)], block_start: [224, CType::Immediate.parse("int")],
opt_table: [256, CType::Pointer.new { self.VALUE }], opt_table: [256, CType::Pointer.new { self.VALUE }],
keyword: [320, CType::Pointer.new { self.rb_iseq_param_keyword }], keyword: [320, CType::Pointer.new { self.rb_iseq_param_keyword }],
)], )],
@ -438,13 +435,13 @@ module RubyVM::MJIT
pc2branchindex: [192, self.VALUE], pc2branchindex: [192, self.VALUE],
original_iseq: [256, CType::Pointer.new { self.VALUE }], original_iseq: [256, CType::Pointer.new { self.VALUE }],
)], )],
local_table_size: [1920, CType::Immediate.new(-4)], local_table_size: [1920, CType::Immediate.parse("unsigned int")],
ic_size: [1952, CType::Immediate.new(-4)], ic_size: [1952, CType::Immediate.parse("unsigned int")],
ise_size: [1984, CType::Immediate.new(-4)], ise_size: [1984, CType::Immediate.parse("unsigned int")],
ivc_size: [2016, CType::Immediate.new(-4)], ivc_size: [2016, CType::Immediate.parse("unsigned int")],
icvarc_size: [2048, CType::Immediate.new(-4)], icvarc_size: [2048, CType::Immediate.parse("unsigned int")],
ci_size: [2080, CType::Immediate.new(-4)], ci_size: [2080, CType::Immediate.parse("unsigned int")],
stack_max: [2112, CType::Immediate.new(-4)], stack_max: [2112, CType::Immediate.parse("unsigned int")],
mark_bits: [2176, CType::Union.new( mark_bits: [2176, CType::Union.new(
"", 8, "", 8,
list: CType::Pointer.new { self.iseq_bits_t }, list: CType::Pointer.new { self.iseq_bits_t },
@ -454,10 +451,10 @@ module RubyVM::MJIT
builtin_inline_p: [2248, self._Bool], builtin_inline_p: [2248, self._Bool],
outer_variables: [2304, CType::Pointer.new { self.rb_id_table }], outer_variables: [2304, CType::Pointer.new { self.rb_id_table }],
mandatory_only_iseq: [2368, CType::Pointer.new { self.rb_iseq_t }], mandatory_only_iseq: [2368, CType::Pointer.new { self.rb_iseq_t }],
jit_func: [2432, CType::Immediate.new(1)], jit_func: [2432, CType::Immediate.parse("void *")],
total_calls: [2496, CType::Immediate.new(-5)], total_calls: [2496, CType::Immediate.parse("unsigned long")],
jit_unit: [2560, CType::Pointer.new { self.rb_mjit_unit }], jit_unit: [2560, CType::Pointer.new { self.rb_mjit_unit }],
yjit_payload: [2624, CType::Pointer.new { CType::Immediate.new(0) }], yjit_payload: [2624, CType::Pointer.new { CType::Immediate.parse("void") }],
) )
end end
@ -468,7 +465,7 @@ module RubyVM::MJIT
base_label: [64, self.VALUE, true], base_label: [64, self.VALUE, true],
label: [128, self.VALUE, true], label: [128, self.VALUE, true],
first_lineno: [192, self.VALUE, true], first_lineno: [192, self.VALUE, true],
node_id: [256, CType::Immediate.new(4)], node_id: [256, CType::Immediate.parse("int")],
code_location: [288, self.rb_code_location_t], code_location: [288, self.rb_code_location_t],
) )
end end
@ -485,7 +482,7 @@ module RubyVM::MJIT
loader: CType::Struct.new( loader: CType::Struct.new(
"", 16, "", 16,
obj: [0, self.VALUE], obj: [0, self.VALUE],
index: [64, CType::Immediate.new(4)], index: [64, CType::Immediate.parse("int")],
), ),
exec: CType::Struct.new( exec: CType::Struct.new(
"", 16, "", 16,
@ -503,7 +500,7 @@ module RubyVM::MJIT
def C.rb_iv_index_tbl_entry def C.rb_iv_index_tbl_entry
@rb_iv_index_tbl_entry ||= CType::Struct.new( @rb_iv_index_tbl_entry ||= CType::Struct.new(
"rb_iv_index_tbl_entry", 24, "rb_iv_index_tbl_entry", 24,
index: [0, CType::Immediate.new(-4)], index: [0, CType::Immediate.parse("uint32_t")],
class_serial: [64, self.rb_serial_t], class_serial: [64, self.rb_serial_t],
class_value: [128, self.VALUE], class_value: [128, self.VALUE],
) )
@ -528,7 +525,7 @@ module RubyVM::MJIT
optimized: self.rb_method_optimized_t, optimized: self.rb_method_optimized_t,
)], )],
original_id: [256, self.ID], original_id: [256, self.ID],
method_serial: [320, CType::Immediate.new(-5)], method_serial: [320, CType::Immediate.parse("uintptr_t")],
) )
end end
@ -541,7 +538,7 @@ module RubyVM::MJIT
end end
def C.rb_method_type_t def C.rb_method_type_t
@rb_method_type_t ||= CType::Immediate.new(4) @rb_method_type_t ||= CType::Immediate.parse("int")
end end
def C.rb_mjit_compile_info def C.rb_mjit_compile_info
@ -559,19 +556,23 @@ module RubyVM::MJIT
@rb_mjit_unit ||= CType::Struct.new( @rb_mjit_unit ||= CType::Struct.new(
"rb_mjit_unit", 64, "rb_mjit_unit", 64,
unode: [0, self.ccan_list_node], unode: [0, self.ccan_list_node],
id: [128, CType::Immediate.new(4)], id: [128, CType::Immediate.parse("int")],
handle: [192, CType::Pointer.new { CType::Immediate.new(0) }], handle: [192, CType::Pointer.new { CType::Immediate.parse("void") }],
iseq: [256, CType::Pointer.new { self.rb_iseq_t }], iseq: [256, CType::Pointer.new { self.rb_iseq_t }],
used_code_p: [320, self._Bool], used_code_p: [320, self._Bool],
compact_p: [328, self._Bool], compact_p: [328, self._Bool],
compile_info: [336, self.rb_mjit_compile_info], compile_info: [336, self.rb_mjit_compile_info],
cc_entries: [384, CType::Pointer.new { CType::Pointer.new { self.rb_callcache } }], cc_entries: [384, CType::Pointer.new { CType::Pointer.new { self.rb_callcache } }],
cc_entries_size: [448, CType::Immediate.new(-4)], cc_entries_size: [448, CType::Immediate.parse("unsigned int")],
) )
end end
def C.rb_serial_t def C.rb_serial_t
@rb_serial_t ||= CType::Immediate.new(-6) @rb_serial_t ||= CType::Immediate.parse("unsigned long long")
end
def C.VALUE
@VALUE ||= CType::Immediate.find(Primitive.cexpr!("SIZEOF(VALUE)"), Primitive.cexpr!("SIGNED_TYPE_P(VALUE)"))
end end
def C._Bool def C._Bool

View File

@ -164,6 +164,9 @@ has_cache_for_send(rb_execution_context_t *ec, VALUE self, VALUE cc_addr, VALUE
extern bool rb_splat_or_kwargs_p(const struct rb_callinfo *restrict ci); extern bool rb_splat_or_kwargs_p(const struct rb_callinfo *restrict ci);
#define SIZEOF(type) RB_SIZE2NUM(sizeof(type))
#define SIGNED_TYPE_P(type) RBOOL((type)(-1) < (type)(0))
#include "mjit_c.rbinc" #include "mjit_c.rbinc"
#include "mjit_compiler.rbinc" #include "mjit_compiler.rbinc"

View File

@ -114,14 +114,16 @@ class BindingGenerator
# @param src_path [String] # @param src_path [String]
# @param uses [Array<String>] # @param uses [Array<String>]
# @param ints [Array<String>] # @param ints [Array<String>]
# @param types [Array<String>] Imported types # @param types [Array<String>]
# @param dynamic_types [Array<String>] #ifdef-dependent immediate types, which need Primitive.cexpr! for type detection
# @param ruby_fields [Hash{ Symbol => Array<String> }] Struct VALUE fields that are considered Ruby objects # @param ruby_fields [Hash{ Symbol => Array<String> }] Struct VALUE fields that are considered Ruby objects
def initialize(src_path:, uses:, ints:, types:, ruby_fields:) def initialize(src_path:, uses:, ints:, types:, dynamic_types:, ruby_fields:)
@preamble, @postamble = split_ambles(src_path) @preamble, @postamble = split_ambles(src_path)
@src = String.new @src = String.new
@uses = uses.sort @uses = uses.sort
@ints = ints.sort @ints = ints.sort
@types = types.sort @types = types.sort
@dynamic_types = dynamic_types.sort
@ruby_fields = ruby_fields.transform_keys(&:to_s) @ruby_fields = ruby_fields.transform_keys(&:to_s)
@references = Set.new @references = Set.new
end end
@ -159,8 +161,19 @@ class BindingGenerator
println println
end end
# Define dynamic types
@dynamic_types.each do |type|
unless generate_node(nodes_index[type])&.start_with?('CType::Immediate')
raise "Non-immediate type is given to dynamic_types: #{type}"
end
println " def C.#{type}"
println " @#{type} ||= CType::Immediate.find(Primitive.cexpr!(\"SIZEOF(#{type})\"), Primitive.cexpr!(\"SIGNED_TYPE_P(#{type})\"))"
println " end"
println
end
# Leave a stub for types that are referenced but not targeted # Leave a stub for types that are referenced but not targeted
(@references - @types).each do |type| (@references - @types - @dynamic_types).each do |type|
println " def C.#{type}" println " def C.#{type}"
println " #{DEFAULTS[type]}" println " #{DEFAULTS[type]}"
println " end" println " end"
@ -257,7 +270,12 @@ class BindingGenerator
push_target(type) push_target(type)
"self.#{type}" "self.#{type}"
else else
"CType::Immediate.new(#{ctype})" # Convert any function pointers to void* to workaround FILE* vs int*
if ctype == Fiddle::TYPE_VOIDP
"CType::Immediate.parse(\"void *\")"
else
"CType::Immediate.parse(#{type.dump})"
end
end end
end end
end end
@ -317,7 +335,6 @@ generator = BindingGenerator.new(
IC IC
IVC IVC
RB_BUILTIN RB_BUILTIN
VALUE
compile_branch compile_branch
compile_status compile_status
inlined_call_context inlined_call_context
@ -347,6 +364,9 @@ generator = BindingGenerator.new(
rb_mjit_unit rb_mjit_unit
rb_serial_t rb_serial_t
], ],
dynamic_types: %w[
VALUE
],
ruby_fields: { ruby_fields: {
rb_iseq_location_struct: %w[ rb_iseq_location_struct: %w[
base_label base_label