Commit 5f316333 authored by Rico Tzschichholz's avatar Rico Tzschichholz

codegen: Support casting arbitary value-types to arrays

Also calculate a valid length for the resulting array.

This enables easier usage of common uint8[]-based buffer API.

https://bugzilla.gnome.org/show_bug.cgi?id=777194
parent 20a1536f
......@@ -5171,10 +5171,29 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
}
}
} else if (array_type != null) {
// cast from non-array to array, set invalid length
// required by string.data, e.g.
CCodeExpression array_length_expr;
var sizeof_to = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
sizeof_to.add_argument (new CCodeConstant (get_ccode_name (array_type.element_type)));
var sizeof_from = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
var value_type = expr.inner.value_type;
if (value_type is ValueType) {
var data_type = ((ValueType) value_type).data_type;
sizeof_from.add_argument (new CCodeConstant (get_ccode_name (data_type)));
array_length_expr = new CCodeBinaryExpression (CCodeBinaryOperator.DIV, sizeof_from, sizeof_to);
} else if (value_type is PointerType && ((PointerType) value_type).base_type is ValueType) {
var data_type = ((ValueType) (((PointerType) value_type).base_type)).data_type;
sizeof_from.add_argument (new CCodeConstant (get_ccode_name (data_type)));
array_length_expr = new CCodeBinaryExpression (CCodeBinaryOperator.DIV, sizeof_from, sizeof_to);
} else {
// cast from unsupported non-array to array, set invalid length
// required by string.data, e.g.
array_length_expr = new CCodeConstant ("-1");
}
for (int dim = 1; dim <= array_type.rank; dim++) {
append_array_length (expr, new CCodeConstant ("-1"));
append_array_length (expr, array_length_expr);
}
}
......@@ -5183,6 +5202,10 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
expr.inner.value_type is ValueType && expr.inner.value_type.nullable) {
// nullable integer or float or boolean or struct or enum cast to non-nullable
innercexpr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, innercexpr);
} else if (expr.type_reference is ArrayType
&& expr.inner.value_type is ValueType && !expr.inner.value_type.nullable) {
// integer or float or boolean or struct or enum to array cast
innercexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, innercexpr);
}
set_cvalue (expr, new CCodeCastExpression (innercexpr, get_ccode_name (expr.type_reference)));
......
......@@ -132,6 +132,7 @@ TESTS = \
structs/bug690380.vala \
structs/bug749952.vala \
structs/bug775761.vala \
structs/bug777194.vala \
delegates/delegates.vala \
delegates/bug539166.vala \
delegates/bug595610.vala \
......
struct Foo {
public int64 foo;
public int64 bar;
}
void bar (uint8[] a) {
unowned Foo[] f = (Foo[]) a;
assert (f[0].foo == 2LL << 62);
assert (f[0].bar == 2LL << 31);
}
void main () {
unowned uint8[] tu;
uint8[] to;
Foo fstack = { 2LL << 62 , 2LL << 31};
Foo? fheap = { 2LL << 62 , 2LL << 31};
bar ((uint8[]) &fstack);
tu = (uint8[]) &fstack;
assert (tu.length == 16);
bar (tu);
to = (uint8[]) &fstack;
assert (to.length == 16);
bar (to);
bar ((uint8[]) fstack);
tu = (uint8[]) fstack;
assert (tu.length == 16);
bar (tu);
to = (uint8[]) fstack;
assert (to.length == 16);
bar (to);
bar ((uint8[]) fheap);
tu = (uint8[]) fheap;
assert (tu.length == 16);
bar (tu);
to = (uint8[]) fheap;
assert (to.length == 16);
bar (to);
int32 i32 = 2 << 28;
tu = (uint8[]) i32;
assert (tu.length == 4);
tu = (uint8[]) &i32;
assert (tu.length == 4);
to = (uint8[]) i32;
assert (to.length == 4);
uint64 u64 = 2UL << 30;
tu = (uint8[]) u64;
assert (tu.length == 8);
tu = (uint8[]) &u64;
assert (tu.length == 8);
to = (uint8[]) u64;
assert (to.length == 8);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment