Fix for opaque pointers
This commit is contained in:
parent
3d4c59ed75
commit
4115e09c13
3 changed files with 30 additions and 18 deletions
|
@ -25,7 +25,7 @@ master = ["gccjit/master"]
|
||||||
gccjit = { git = "https://github.com/antoyo/gccjit.rs" }
|
gccjit = { git = "https://github.com/antoyo/gccjit.rs" }
|
||||||
|
|
||||||
# Local copy.
|
# Local copy.
|
||||||
# gccjit = { path = "../gccjit.rs" }
|
#gccjit = { path = "../gccjit.rs" }
|
||||||
|
|
||||||
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
|
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
|
||||||
|
|
||||||
|
|
|
@ -280,8 +280,17 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn function_ptr_call(&mut self, func_ptr: RValue<'gcc>, args: &[RValue<'gcc>], _funclet: Option<&Funclet>) -> RValue<'gcc> {
|
fn function_ptr_call(&mut self, typ: Type<'gcc>, mut func_ptr: RValue<'gcc>, args: &[RValue<'gcc>], _funclet: Option<&Funclet>) -> RValue<'gcc> {
|
||||||
let gcc_func = func_ptr.get_type().dyncast_function_ptr_type().expect("function ptr");
|
let gcc_func =
|
||||||
|
match func_ptr.get_type().dyncast_function_ptr_type() {
|
||||||
|
Some(func) => func,
|
||||||
|
None => {
|
||||||
|
// NOTE: due to opaque pointers now being used, we need to cast here.
|
||||||
|
let new_func_type = typ.dyncast_function_ptr_type().expect("function ptr");
|
||||||
|
func_ptr = self.context.new_cast(None, func_ptr, typ);
|
||||||
|
new_func_type
|
||||||
|
},
|
||||||
|
};
|
||||||
let func_name = format!("{:?}", func_ptr);
|
let func_name = format!("{:?}", func_ptr);
|
||||||
let previous_arg_count = args.len();
|
let previous_arg_count = args.len();
|
||||||
let orig_args = args;
|
let orig_args = args;
|
||||||
|
@ -424,16 +433,17 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||||
self.llbb().end_with_void_return(None)
|
self.llbb().end_with_void_return(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ret(&mut self, value: RValue<'gcc>) {
|
fn ret(&mut self, mut value: RValue<'gcc>) {
|
||||||
let value =
|
if self.structs_as_pointer.borrow().contains(&value) {
|
||||||
if self.structs_as_pointer.borrow().contains(&value) {
|
// NOTE: hack to workaround a limitation of the rustc API: see comment on
|
||||||
// NOTE: hack to workaround a limitation of the rustc API: see comment on
|
// CodegenCx.structs_as_pointer
|
||||||
// CodegenCx.structs_as_pointer
|
value = value.dereference(None).to_rvalue();
|
||||||
value.dereference(None).to_rvalue()
|
}
|
||||||
}
|
let expected_return_type = self.current_func().get_return_type();
|
||||||
else {
|
if !expected_return_type.is_compatible_with(value.get_type()) {
|
||||||
value
|
// NOTE: due to opaque pointers now being used, we need to cast here.
|
||||||
};
|
value = self.context.new_cast(None, value, expected_return_type);
|
||||||
|
}
|
||||||
self.llbb().end_with_return(None, value);
|
self.llbb().end_with_return(None, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -938,6 +948,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||||
element.get_address(None)
|
element.get_address(None)
|
||||||
}
|
}
|
||||||
else if let Some(struct_type) = value_type.is_struct() {
|
else if let Some(struct_type) = value_type.is_struct() {
|
||||||
|
// NOTE: due to opaque pointers now being used, we need to bitcast here.
|
||||||
|
let ptr = self.bitcast_if_needed(ptr, value_type.make_pointer());
|
||||||
ptr.dereference_field(None, struct_type.get_field(idx as i32)).get_address(None)
|
ptr.dereference_field(None, struct_type.get_field(idx as i32)).get_address(None)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1356,7 +1368,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||||
|
|
||||||
fn call(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
_typ: Type<'gcc>,
|
typ: Type<'gcc>,
|
||||||
_fn_attrs: Option<&CodegenFnAttrs>,
|
_fn_attrs: Option<&CodegenFnAttrs>,
|
||||||
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
|
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
|
||||||
func: RValue<'gcc>,
|
func: RValue<'gcc>,
|
||||||
|
@ -1370,7 +1382,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// If it's a not function that was defined, it's a function pointer.
|
// If it's a not function that was defined, it's a function pointer.
|
||||||
self.function_ptr_call(func, args, funclet)
|
self.function_ptr_call(typ, func, args, funclet)
|
||||||
};
|
};
|
||||||
if let Some(_fn_abi) = fn_abi {
|
if let Some(_fn_abi) = fn_abi {
|
||||||
// TODO(bjorn3): Apply function attributes
|
// TODO(bjorn3): Apply function attributes
|
||||||
|
|
|
@ -383,8 +383,8 @@ impl<'gcc, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fn_decl_backend_type(&self, _fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Type<'gcc> {
|
fn fn_decl_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Type<'gcc> {
|
||||||
// FIXME(antoyo): return correct type.
|
let (return_type, param_types, variadic, _) = fn_abi.gcc_type(self);
|
||||||
self.type_void()
|
self.context.new_function_pointer_type(None, return_type, ¶m_types, variadic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue