RJIT: Distinguish Pointer with Array
This is more convenient for accessing those fields.
This commit is contained in:
parent
40e3f782dd
commit
19d082dcfa
@ -238,6 +238,40 @@ module RubyVM::RJIT
|
||||
end
|
||||
end
|
||||
|
||||
# Basically Immediate but without #* to skip auto-dereference of structs.
|
||||
class Array
|
||||
attr_reader :type
|
||||
|
||||
# @param addr [Integer]
|
||||
# @param type [Class] RubyVM::RJIT::CType::*
|
||||
def initialize(addr, type)
|
||||
@addr = addr
|
||||
@type = type
|
||||
end
|
||||
|
||||
# Array access
|
||||
def [](index)
|
||||
@type.new(@addr)[index]
|
||||
end
|
||||
|
||||
# Array set
|
||||
# @param index [Integer]
|
||||
# @param value [Integer, RubyVM::RJIT::CPointer::Struct] an address itself or an object that return an address with to_i
|
||||
def []=(index, value)
|
||||
@type.new(@addr)[index] = value
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.define(block)
|
||||
Class.new(self) do
|
||||
define_method(:initialize) do |addr|
|
||||
super(addr, block.call)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Pointer
|
||||
attr_reader :type
|
||||
|
||||
|
@ -62,6 +62,14 @@ module RubyVM::RJIT
|
||||
end
|
||||
end
|
||||
|
||||
class Array
|
||||
def self.new(&block)
|
||||
CPointer.with_class_name('Array', block.object_id.to_s) do
|
||||
CPointer::Array.define(block)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Pointer
|
||||
# This takes a block to avoid "stack level too deep" on a cyclic reference
|
||||
# @param block [Proc]
|
||||
|
@ -820,7 +820,7 @@ module RubyVM::RJIT # :nodoc: all
|
||||
), Primitive.cexpr!("OFFSETOF(((struct RArray *)NULL)->as.heap, aux)")],
|
||||
ptr: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF(((struct RArray *)NULL)->as.heap, ptr)")],
|
||||
),
|
||||
ary: CType::Pointer.new { self.VALUE },
|
||||
ary: CType::Array.new { self.VALUE },
|
||||
), Primitive.cexpr!("OFFSETOF((*((struct RArray *)NULL)), as)")],
|
||||
)
|
||||
end
|
||||
@ -848,7 +848,7 @@ module RubyVM::RJIT # :nodoc: all
|
||||
ivptr: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF(((struct RObject *)NULL)->as.heap, ivptr)")],
|
||||
iv_index_tbl: [CType::Pointer.new { self.rb_id_table }, Primitive.cexpr!("OFFSETOF(((struct RObject *)NULL)->as.heap, iv_index_tbl)")],
|
||||
),
|
||||
ary: CType::Pointer.new { self.VALUE },
|
||||
ary: CType::Array.new { self.VALUE },
|
||||
), Primitive.cexpr!("OFFSETOF((*((struct RObject *)NULL)), as)")],
|
||||
)
|
||||
end
|
||||
@ -871,7 +871,7 @@ module RubyVM::RJIT # :nodoc: all
|
||||
),
|
||||
embed: CType::Struct.new(
|
||||
"", Primitive.cexpr!("SIZEOF(((struct RString *)NULL)->as.embed)"),
|
||||
ary: [CType::Pointer.new { CType::Immediate.parse("char") }, Primitive.cexpr!("OFFSETOF(((struct RString *)NULL)->as.embed, ary)")],
|
||||
ary: [CType::Array.new { CType::Immediate.parse("char") }, Primitive.cexpr!("OFFSETOF(((struct RString *)NULL)->as.embed, ary)")],
|
||||
),
|
||||
), Primitive.cexpr!("OFFSETOF((*((struct RString *)NULL)), as)")],
|
||||
)
|
||||
@ -888,7 +888,7 @@ module RubyVM::RJIT # :nodoc: all
|
||||
len: [CType::Immediate.parse("long"), Primitive.cexpr!("OFFSETOF(((struct RStruct *)NULL)->as.heap, len)")],
|
||||
ptr: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF(((struct RStruct *)NULL)->as.heap, ptr)")],
|
||||
),
|
||||
ary: CType::Pointer.new { self.VALUE },
|
||||
ary: CType::Array.new { self.VALUE },
|
||||
), Primitive.cexpr!("OFFSETOF((*((struct RStruct *)NULL)), as)")],
|
||||
)
|
||||
end
|
||||
|
@ -296,7 +296,7 @@ class BindingGenerator
|
||||
# @param type [String]
|
||||
def generate_type(type)
|
||||
if type.match?(/\[\d+\]\z/)
|
||||
return "CType::Pointer.new { #{generate_type(type.sub!(/\[\d+\]\z/, ''))} }"
|
||||
return "CType::Array.new { #{generate_type(type.sub!(/\[\d+\]\z/, ''))} }"
|
||||
end
|
||||
type = type.delete_suffix('const')
|
||||
if type.end_with?('*')
|
||||
|
Loading…
x
Reference in New Issue
Block a user