aboutsummaryrefslogtreecommitdiffstats
path: root/tool/mjit
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2022-09-21 22:32:28 +0900
committerTakashi Kokubun <takashikkbn@gmail.com>2022-09-23 06:44:28 +0900
commit2ce1460c6504bfefab85814c175de684b3e40381 (patch)
tree0ddf592c5aba6c11038aaa751c8f793760a334e8 /tool/mjit
parent4c6e1556b109367f598e276f72feacefc72805fc (diff)
downloadruby-2ce1460c6504bfefab85814c175de684b3e40381.tar.gz
Bindgen sizeof struct and union with builtin
Diffstat (limited to 'tool/mjit')
-rwxr-xr-xtool/mjit/bindgen.rb17
1 files changed, 11 insertions, 6 deletions
diff --git a/tool/mjit/bindgen.rb b/tool/mjit/bindgen.rb
index 793db965dd..06ece7d6fa 100755
--- a/tool/mjit/bindgen.rb
+++ b/tool/mjit/bindgen.rb
@@ -201,12 +201,12 @@ class BindingGenerator
# Generate code from a node. Used for constructing a complex nested node.
# @param node [Node]
- def generate_node(node)
+ def generate_node(node, sizeof_type: nil)
case node&.kind
when :struct, :union
# node.spelling is often empty for union, but we'd like to give it a name when it has one.
buf = +"CType::#{node.kind.to_s.sub(/\A[a-z]/, &:upcase)}.new(\n"
- buf << " \"#{node.spelling}\", #{node.sizeof_type},\n"
+ buf << " \"#{node.spelling}\", Primitive.cexpr!(\"SIZEOF(#{sizeof_type || node.type})\"),\n"
node.children.each do |child|
field_builder = proc do |field, type|
if node.kind == :struct
@@ -221,12 +221,17 @@ class BindingGenerator
# BitField is struct-specific. So it must be handled here.
in Node[kind: :field_decl, spelling:, bitwidth:, children: [_grandchild]] if bitwidth > 0
buf << field_builder.call(spelling, "CType::BitField.new(#{bitwidth}, #{node.offsetof.fetch(spelling) % 8})")
+ # "(unnamed ...)" struct and union are handled here, which are also struct-specific.
+ in Node[kind: :field_decl, spelling:, type:, children: [grandchild]] if type.match?(/\((unnamed|anonymous) [^)]+\)\z/)
+ if sizeof_type
+ child_type = "#{sizeof_type}.#{child.spelling}"
+ else
+ child_type = "((#{node.type} *)NULL)->#{child.spelling}"
+ end
+ buf << field_builder.call(spelling, generate_node(grandchild, sizeof_type: child_type).gsub(/^/, ' ').sub(/\A +/, ''))
# In most cases, we'd like to let generate_type handle the type unless it's "(unnamed ...)".
- in Node[kind: :field_decl, spelling:, type:] if !type.empty? && !type.match?(/\((unnamed|anonymous) [^)]+\)\z/)
+ in Node[kind: :field_decl, spelling:, type:] if !type.empty?
buf << field_builder.call(spelling, generate_type(type))
- # Lastly, "(unnamed ...)" struct and union are handled here, which are also struct-specific.
- in Node[kind: :field_decl, spelling:, children: [grandchild]]
- buf << field_builder.call(spelling, generate_node(grandchild).gsub(/^/, ' ').sub(/\A +/, ''))
else # forward declarations are ignored
end
end