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
|
||||||
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
|
class Pointer
|
||||||
attr_reader :type
|
attr_reader :type
|
||||||
|
|
||||||
|
@ -62,6 +62,14 @@ module RubyVM::RJIT
|
|||||||
end
|
end
|
||||||
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
|
class Pointer
|
||||||
# This takes a block to avoid "stack level too deep" on a cyclic reference
|
# This takes a block to avoid "stack level too deep" on a cyclic reference
|
||||||
# @param block [Proc]
|
# @param block [Proc]
|
||||||
|
@ -820,7 +820,7 @@ module RubyVM::RJIT # :nodoc: all
|
|||||||
), Primitive.cexpr!("OFFSETOF(((struct RArray *)NULL)->as.heap, aux)")],
|
), Primitive.cexpr!("OFFSETOF(((struct RArray *)NULL)->as.heap, aux)")],
|
||||||
ptr: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF(((struct RArray *)NULL)->as.heap, ptr)")],
|
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)")],
|
), Primitive.cexpr!("OFFSETOF((*((struct RArray *)NULL)), as)")],
|
||||||
)
|
)
|
||||||
end
|
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)")],
|
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)")],
|
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)")],
|
), Primitive.cexpr!("OFFSETOF((*((struct RObject *)NULL)), as)")],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@ -871,7 +871,7 @@ module RubyVM::RJIT # :nodoc: all
|
|||||||
),
|
),
|
||||||
embed: CType::Struct.new(
|
embed: CType::Struct.new(
|
||||||
"", Primitive.cexpr!("SIZEOF(((struct RString *)NULL)->as.embed)"),
|
"", 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)")],
|
), 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)")],
|
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)")],
|
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)")],
|
), Primitive.cexpr!("OFFSETOF((*((struct RStruct *)NULL)), as)")],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -296,7 +296,7 @@ class BindingGenerator
|
|||||||
# @param type [String]
|
# @param type [String]
|
||||||
def generate_type(type)
|
def generate_type(type)
|
||||||
if type.match?(/\[\d+\]\z/)
|
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
|
end
|
||||||
type = type.delete_suffix('const')
|
type = type.delete_suffix('const')
|
||||||
if type.end_with?('*')
|
if type.end_with?('*')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user