diff options
Diffstat (limited to '')
7 files changed, 80 insertions, 25 deletions
diff --git a/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/ObjectTemplate.rb b/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/ObjectTemplate.rb index 677c5c729b..ba2caf7380 100644 --- a/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/ObjectTemplate.rb +++ b/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/ObjectTemplate.rb @@ -2,18 +2,18 @@ class {{ obj.name()|class_name_rb }} # A private helper for initializing instances of the class from a raw pointer, # bypassing any initialization logic and ensuring they are GC'd properly. - def self._uniffi_allocate(pointer) + def self.uniffi_allocate(pointer) pointer.autorelease = false inst = allocate inst.instance_variable_set :@pointer, pointer - ObjectSpace.define_finalizer(inst, _uniffi_define_finalizer_by_pointer(pointer, inst.object_id)) + ObjectSpace.define_finalizer(inst, uniffi_define_finalizer_by_pointer(pointer, inst.object_id)) return inst end # A private helper for registering an object finalizer. # N.B. it's important that this does not capture a reference # to the actual instance, only its underlying pointer. - def self._uniffi_define_finalizer_by_pointer(pointer, object_id) + def self.uniffi_define_finalizer_by_pointer(pointer, object_id) Proc.new do |_id| {{ ci.namespace()|class_name_rb }}.rust_call( :{{ obj.ffi_object_free().name() }}, @@ -25,31 +25,41 @@ class {{ obj.name()|class_name_rb }} # A private helper for lowering instances into a raw pointer. # This does an explicit typecheck, because accidentally lowering a different type of # object in a place where this type is expected, could lead to memory unsafety. - def self._uniffi_lower(inst) + def self.uniffi_check_lower(inst) if not inst.is_a? self raise TypeError.new "Expected a {{ obj.name()|class_name_rb }} instance, got #{inst}" end - return inst.instance_variable_get :@pointer + end + + def uniffi_clone_pointer() + return {{ ci.namespace()|class_name_rb }}.rust_call( + :{{ obj.ffi_object_clone().name() }}, + @pointer + ) + end + + def self.uniffi_lower(inst) + return inst.uniffi_clone_pointer() end {%- match obj.primary_constructor() %} {%- when Some with (cons) %} def initialize({% call rb::arg_list_decl(cons) -%}) - {%- call rb::coerce_args_extra_indent(cons) %} + {%- call rb::setup_args_extra_indent(cons) %} pointer = {% call rb::to_ffi_call(cons) %} @pointer = pointer - ObjectSpace.define_finalizer(self, self.class._uniffi_define_finalizer_by_pointer(pointer, self.object_id)) + ObjectSpace.define_finalizer(self, self.class.uniffi_define_finalizer_by_pointer(pointer, self.object_id)) end {%- when None %} {%- endmatch %} {% for cons in obj.alternate_constructors() -%} def self.{{ cons.name()|fn_name_rb }}({% call rb::arg_list_decl(cons) %}) - {%- call rb::coerce_args_extra_indent(cons) %} + {%- call rb::setup_args_extra_indent(cons) %} # Call the (fallible) function before creating any half-baked object instances. # Lightly yucky way to bypass the usual "initialize" logic # and just create a new instance with the required pointer. - return _uniffi_allocate({% call rb::to_ffi_call(cons) %}) + return uniffi_allocate({% call rb::to_ffi_call(cons) %}) end {% endfor %} @@ -58,15 +68,15 @@ class {{ obj.name()|class_name_rb }} {%- when Some with (return_type) -%} def {{ meth.name()|fn_name_rb }}({% call rb::arg_list_decl(meth) %}) - {%- call rb::coerce_args_extra_indent(meth) %} - result = {% call rb::to_ffi_call_with_prefix("@pointer", meth) %} + {%- call rb::setup_args_extra_indent(meth) %} + result = {% call rb::to_ffi_call_with_prefix("uniffi_clone_pointer()", meth) %} return {{ "result"|lift_rb(return_type) }} end {%- when None -%} def {{ meth.name()|fn_name_rb }}({% call rb::arg_list_decl(meth) %}) - {%- call rb::coerce_args_extra_indent(meth) %} - {% call rb::to_ffi_call_with_prefix("@pointer", meth) %} + {%- call rb::setup_args_extra_indent(meth) %} + {% call rb::to_ffi_call_with_prefix("uniffi_clone_pointer()", meth) %} end {% endmatch %} {% endfor %} diff --git a/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/RecordTemplate.rb b/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/RecordTemplate.rb index c940b31060..b5a201b248 100644 --- a/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/RecordTemplate.rb +++ b/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/RecordTemplate.rb @@ -2,7 +2,12 @@ class {{ rec.name()|class_name_rb }} attr_reader {% for field in rec.fields() %}:{{ field.name()|var_name_rb }}{% if loop.last %}{% else %}, {% endif %}{%- endfor %} - def initialize({% for field in rec.fields() %}{{ field.name()|var_name_rb }}{% if loop.last %}{% else %}, {% endif %}{% endfor %}) + def initialize({% for field in rec.fields() %}{{ field.name()|var_name_rb -}}: + {%- match field.default_value() %} + {%- when Some with(literal) %} {{ literal|literal_rb }} + {%- else %} + {%- endmatch %} + {%- if loop.last %}{% else %}, {% endif -%}{% endfor %}) {%- for field in rec.fields() %} @{{ field.name()|var_name_rb }} = {{ field.name()|var_name_rb }} {%- endfor %} diff --git a/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/RustBufferBuilder.rb b/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/RustBufferBuilder.rb index 8749139116..d15c0bbe76 100644 --- a/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/RustBufferBuilder.rb +++ b/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/RustBufferBuilder.rb @@ -163,7 +163,7 @@ class RustBufferBuilder # The Object type {{ object_name }}. def write_{{ canonical_type_name }}(obj) - pointer = {{ object_name|class_name_rb}}._uniffi_lower obj + pointer = {{ object_name|class_name_rb}}.uniffi_lower obj pack_into(8, 'Q>', pointer.address) end diff --git a/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/RustBufferStream.rb b/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/RustBufferStream.rb index b085dddf15..f9b0806abc 100644 --- a/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/RustBufferStream.rb +++ b/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/RustBufferStream.rb @@ -155,7 +155,7 @@ class RustBufferStream def read{{ canonical_type_name }} pointer = FFI::Pointer.new unpack_from 8, 'Q>' - return {{ object_name|class_name_rb }}._uniffi_allocate(pointer) + return {{ object_name|class_name_rb }}.uniffi_allocate(pointer) end {% when Type::Enum { name, module_path } -%} @@ -237,7 +237,7 @@ class RustBufferStream def read{{ canonical_type_name }} {{ rec.name()|class_name_rb }}.new( {%- for field in rec.fields() %} - read{{ canonical_name(field.as_type().borrow()).borrow()|class_name_rb }}{% if loop.last %}{% else %},{% endif %} + {{ field.name()|var_name_rb }}: read{{ canonical_name(field.as_type().borrow()).borrow()|class_name_rb }}{% if loop.last %}{% else %},{% endif %} {%- endfor %} ) end diff --git a/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/RustBufferTemplate.rb b/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/RustBufferTemplate.rb index 0194c9666d..452d9831cd 100644 --- a/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/RustBufferTemplate.rb +++ b/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/RustBufferTemplate.rb @@ -1,6 +1,6 @@ class RustBuffer < FFI::Struct - layout :capacity, :int32, - :len, :int32, + layout :capacity, :uint64, + :len, :uint64, :data, :pointer def self.alloc(size) @@ -128,6 +128,12 @@ class RustBuffer < FFI::Struct {%- let rec = ci|get_record_definition(record_name) -%} # The Record type {{ record_name }}. + def self.check_lower_{{ canonical_type_name }}(v) + {%- for field in rec.fields() %} + {{ "v.{}"|format(field.name()|var_name_rb)|check_lower_rb(field.as_type().borrow()) }} + {%- endfor %} + end + def self.alloc_from_{{ canonical_type_name }}(v) RustBuffer.allocWithBuilder do |builder| builder.write_{{ canonical_type_name }}(v) @@ -146,6 +152,19 @@ class RustBuffer < FFI::Struct {%- let e = ci|get_enum_definition(enum_name) -%} # The Enum type {{ enum_name }}. + def self.check_lower_{{ canonical_type_name }}(v) + {%- if !e.is_flat() %} + {%- for variant in e.variants() %} + if v.{{ variant.name()|var_name_rb }}? + {%- for field in variant.fields() %} + {{ "v.{}"|format(field.name())|check_lower_rb(field.as_type().borrow()) }} + {%- endfor %} + return + end + {%- endfor %} + {%- endif %} + end + def self.alloc_from_{{ canonical_type_name }}(v) RustBuffer.allocWithBuilder do |builder| builder.write_{{ canonical_type_name }}(v) @@ -163,6 +182,12 @@ class RustBuffer < FFI::Struct {% when Type::Optional { inner_type } -%} # The Optional<T> type for {{ canonical_name(inner_type) }}. + def self.check_lower_{{ canonical_type_name }}(v) + if not v.nil? + {{ "v"|check_lower_rb(inner_type.borrow()) }} + end + end + def self.alloc_from_{{ canonical_type_name }}(v) RustBuffer.allocWithBuilder do |builder| builder.write_{{ canonical_type_name }}(v) @@ -179,6 +204,12 @@ class RustBuffer < FFI::Struct {% when Type::Sequence { inner_type } -%} # The Sequence<T> type for {{ canonical_name(inner_type) }}. + def self.check_lower_{{ canonical_type_name }}(v) + v.each do |item| + {{ "item"|check_lower_rb(inner_type.borrow()) }} + end + end + def self.alloc_from_{{ canonical_type_name }}(v) RustBuffer.allocWithBuilder do |builder| builder.write_{{ canonical_type_name }}(v) @@ -195,6 +226,13 @@ class RustBuffer < FFI::Struct {% when Type::Map { key_type: k, value_type: inner_type } -%} # The Map<T> type for {{ canonical_name(inner_type) }}. + def self.check_lower_{{ canonical_type_name }}(v) + v.each do |k, v| + {{ "k"|check_lower_rb(k.borrow()) }} + {{ "v"|check_lower_rb(inner_type.borrow()) }} + end + end + def self.alloc_from_{{ canonical_type_name }}(v) RustBuffer.allocWithBuilder do |builder| builder.write_{{ canonical_type_name }}(v) diff --git a/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/TopLevelFunctionTemplate.rb b/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/TopLevelFunctionTemplate.rb index 13214cf31b..b6dce0effa 100644 --- a/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/TopLevelFunctionTemplate.rb +++ b/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/TopLevelFunctionTemplate.rb @@ -2,7 +2,7 @@ {%- when Some with (return_type) %} def self.{{ func.name()|fn_name_rb }}({%- call rb::arg_list_decl(func) -%}) - {%- call rb::coerce_args(func) %} + {%- call rb::setup_args(func) %} result = {% call rb::to_ffi_call(func) %} return {{ "result"|lift_rb(return_type) }} end @@ -10,7 +10,7 @@ end {% when None %} def self.{{ func.name()|fn_name_rb }}({%- call rb::arg_list_decl(func) -%}) - {%- call rb::coerce_args(func) %} + {%- call rb::setup_args(func) %} {% call rb::to_ffi_call(func) %} end {% endmatch %} diff --git a/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/macros.rb b/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/macros.rb index 8dc3e5e613..59fa4ef4cc 100644 --- a/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/macros.rb +++ b/third_party/rust/uniffi_bindgen/src/bindings/ruby/templates/macros.rb @@ -60,14 +60,16 @@ [{%- for arg in func.arguments() -%}{{ arg.type_().borrow()|type_ffi }}, {% endfor -%} RustCallStatus.by_ref] {%- endmacro -%} -{%- macro coerce_args(func) %} +{%- macro setup_args(func) %} {%- for arg in func.arguments() %} - {{ arg.name() }} = {{ arg.name()|coerce_rb(ci.namespace()|class_name_rb, arg.as_type().borrow()) -}} + {{ arg.name() }} = {{ arg.name()|coerce_rb(ci.namespace()|class_name_rb, arg.as_type().borrow()) }} + {{ arg.name()|check_lower_rb(arg.as_type().borrow()) }} {% endfor -%} {%- endmacro -%} -{%- macro coerce_args_extra_indent(func) %} - {%- for arg in func.arguments() %} +{%- macro setup_args_extra_indent(meth) %} + {%- for arg in meth.arguments() %} {{ arg.name() }} = {{ arg.name()|coerce_rb(ci.namespace()|class_name_rb, arg.as_type().borrow()) }} + {{ arg.name()|check_lower_rb(arg.as_type().borrow()) }} {%- endfor %} {%- endmacro -%} |