Skip to content

Commit

Permalink
Fix bundled input and output initialization (#4)
Browse files Browse the repository at this point in the history
Structs with arrays of primitives are not initialized properly.

---------

Signed-off-by: jongyong <[email protected]>
Co-authored-by: jongyong <[email protected]>
  • Loading branch information
quic-nhaas and quic-jongyong authored Oct 17, 2024
1 parent e52a9cd commit 0384192
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 23 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

All notable changes to this project will be documented in this file.

## [0.1.4] - 2024-10-17

### Fixes
- C/CPP Codegen: Fixed bundled output initialization

## [0.1.3] - 2024-09-11

### Fixes
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ strip = true
panic = "abort"

[workspace.package]
version = "0.1.3"
version = "0.1.4"
3 changes: 2 additions & 1 deletion idlc_codegen_c/src/interface/functions/implementation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ impl idlc_codegen::functions::ParameterVisitor for Implementation {
let _idx = self.idx();

self.initializations.push(format!(
r#"{definition} o = {{{initialization}}};
r#"
{definition} o = {{{initialization}}};
"#
));
self.post_call.push(packer.post_bo_assignments());
Expand Down
25 changes: 21 additions & 4 deletions idlc_codegen_c/src/interface/functions/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,29 @@ impl<'a> PackedPrimitives<'a> {
embedded_objs
}

fn struct_init(s: &idlc_mir::StructInner, initialization: &mut String) {
pub fn struct_init(s: &idlc_mir::StructInner, initialization: &mut String) {
initialization.push('{');
for field in &s.fields {
match &field.val.0 {
idlc_mir::Type::Primitive(_) => initialization.push_str("0,"),
idlc_mir::Type::Struct(s) => Self::struct_init(s.as_ref(), initialization),
let (ty, size) = &field.val;
let count = size.get();
match ty {
idlc_mir::Type::Primitive(_) => {
if count > 1 {
initialization.push_str("{0},");
} else {
initialization.push_str("0,");
}
}
idlc_mir::Type::Struct(s) => {
if count > 1 {
initialization.push('{');
}
Self::struct_init(s.as_ref(), initialization);
if count > 1 {
initialization.pop();
initialization.push_str("},");
}
}
idlc_mir::Type::Interface(_) => initialization.push_str("Object_NULL,"),
_ => unreachable!(),
}
Expand Down
16 changes: 1 addition & 15 deletions idlc_codegen_cpp/src/interface/functions/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,20 +108,6 @@ impl<'a> PackedPrimitives<'a> {
assignments
}

fn struct_init(s: &idlc_mir::StructInner, initialization: &mut String) {
initialization.push('{');
for field in &s.fields {
match &field.val.0 {
idlc_mir::Type::Primitive(_) => initialization.push_str("0,"),
idlc_mir::Type::Struct(s) => Self::struct_init(s.as_ref(), initialization),
idlc_mir::Type::Interface(_) => initialization.push_str("Object_NULL,"),
_ => unreachable!(),
}
}
initialization.pop();
initialization.push_str("},");
}

#[inline]
fn generate_struct(
pairs: impl Iterator<Item = (&'a idlc_mir::Ident, &'a Type)>,
Expand All @@ -142,7 +128,7 @@ impl<'a> PackedPrimitives<'a> {
Cow::Borrowed(change_primitive(p))
}
Type::SmallStruct(s) => {
Self::struct_init(s, &mut initialization);
idlc_codegen_c::interface::functions::serialization::PackedPrimitives::struct_init(s, &mut initialization);
Cow::Owned(s.ident.to_string())
}
};
Expand Down
4 changes: 4 additions & 0 deletions tests/c/header.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ int32_t itest1_primitive_plus_struct_out(struct CTest1 *ctx,
SingleEncapsulated *encapsulated_ptr,
uint32_t *magic_ptr);

int32_t itest1_primitive_array_in_struct(struct CTest1 *ctx,
ArrInStruct *arr_ptr,
uint32_t *magic_ptr);

int32_t itest1_bundled_with_unbundled(struct CTest1 *ctx,
const SingleEncapsulated *bundled_ptr,
uint32_t magic_val,
Expand Down
14 changes: 14 additions & 0 deletions tests/c/invoke.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,20 @@ int32_t itest1_primitive_plus_struct_out(struct CTest1 *ctx,
return Object_OK;
}

int32_t itest1_primitive_array_in_struct(struct CTest1 *ctx,
ArrInStruct *arr_ptr,
uint32_t *magic_ptr) {
arr_ptr->a[0] = 7;
arr_ptr->a[1] = 8;
arr_ptr->c[0].a = 9;
arr_ptr->c[0].b = 7;
arr_ptr->c[1].a = 8;
arr_ptr->c[1].b = 9;
arr_ptr->d = SUCCESS_FLAG;
*magic_ptr = SUCCESS_FLAG;
return Object_OK;
}

int32_t itest1_bundled_with_unbundled(struct CTest1 *ctx,
const SingleEncapsulated *bundled_ptr,
uint32_t magic_val,
Expand Down
5 changes: 5 additions & 0 deletions tests/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ class ITest1Impl : public cpp::ITest1ImplBase {
return itest1_primitive_plus_struct_out(
&this->ctest, (SingleEncapsulated *)&encapsulated_ref, magic_ptr);
}
int32_t primitive_array_in_struct(cpp::ArrInStruct &arr_ref,
uint32_t *magic_ptr) {
return itest1_primitive_array_in_struct(
&this->ctest, (ArrInStruct *)&arr_ref, magic_ptr);
}
int32_t bundled_with_unbundled(const cpp::SingleEncapsulated &bundled_ref,
uint32_t magic_val,
const cpp::Collection &unbundled_ref) {
Expand Down
12 changes: 12 additions & 0 deletions tests/idl/ITest.idl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ struct Collection {
uint64 d;
};

struct F2 {
uint8 a;
uint8 b;
};

struct ArrInStruct {
uint8[2] a;
F2[2] c;
uint16 d;
};

const uint32 SUCCESS_FLAG = 0xdead;

interface ITest1 {
Expand All @@ -41,6 +52,7 @@ interface ITest1 {
method multiple_primitive(in buffer unused, out buffer unused2, in uint16 input, out uint16 output, in interface unused3, out interface unused4, in uint32 input2, out uint64 output2, out buffer unused5);
method primitive_plus_struct_in(in SingleEncapsulated encapsulated, in uint32 magic);
method primitive_plus_struct_out(out SingleEncapsulated encapsulated, out uint32 magic);
method primitive_array_in_struct(out ArrInStruct input_a, out uint32 input_b);
method bundled_with_unbundled(in SingleEncapsulated bundled, in uint32 magic, in Collection unbundled);
method struct_array_in(in Collection[] s_in);
method struct_array_out(out Collection[] s_out);
Expand Down
13 changes: 12 additions & 1 deletion tests/src/implementation/test1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: BSD-3-Clause

use super::{TRUTH, TRUTH2};
use crate::interfaces::itest::{self, SingleEncapsulated, SUCCESS_FLAG};
use crate::interfaces::itest::{self, ArrInStruct, SingleEncapsulated, F2, SUCCESS_FLAG};
use crate::interfaces::itest1::{self, IITest1};
use crate::interfaces::itest3::{self, IITest3};

Expand Down Expand Up @@ -136,6 +136,17 @@ macro_rules! generate_itest1_impl {
))
}

fn r#primitive_array_in_struct(&mut self) -> Result<(ArrInStruct, u32), itest1::Error> {
Ok((
ArrInStruct {
a: [7, 8],
c: [F2 { a: 9, b: 7 }, F2 { a: 8, b: 9 }],
d: 7,
},
SUCCESS_FLAG,
))
}

fn r#bundled_with_unbundled(
&mut self,
r#bundled: &crate::interfaces::itest::r#SingleEncapsulated,
Expand Down
2 changes: 1 addition & 1 deletion tests/src/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ impl Drop for Object {
fn drop(&mut self) {
if unsafe { self.invoke(OP_RELEASE, core::ptr::null_mut(), 0u32) } != 0 {
unreachable!(
"Object drop didn't succeed. This is the result of undefined
"Object drop didn't succeed. This is the result of undefined
behaviour, if you believe this is a bug please submit
reproduction/fix steps as an issue"
);
Expand Down

0 comments on commit 0384192

Please sign in to comment.