properly handling generic method calls
Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
parent
51bfbdf7ae
commit
3f11e19a91
|
@ -42,9 +42,6 @@ extern crate alloc;
|
||||||
#[cfg(any(feature = "std", test))]
|
#[cfg(any(feature = "std", test))]
|
||||||
extern crate std;
|
extern crate std;
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
const README: &str = include_str!("../README.md");
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! run_tests {
|
macro_rules! run_tests {
|
||||||
|
|
|
@ -4,12 +4,11 @@ use {
|
||||||
debug,
|
debug,
|
||||||
lexer::{self, TokenKind},
|
lexer::{self, TokenKind},
|
||||||
parser::Pos,
|
parser::Pos,
|
||||||
ty::{self, Loc, Offset, Types},
|
ty::{self, Loc, Types},
|
||||||
utils::{BitSet, Vc},
|
utils::{BitSet, Vc},
|
||||||
},
|
},
|
||||||
alloc::{string::String, vec::Vec},
|
alloc::{string::String, vec::Vec},
|
||||||
core::{
|
core::{
|
||||||
assert_matches::debug_assert_matches,
|
|
||||||
cell::Cell,
|
cell::Cell,
|
||||||
fmt::{self, Debug, Write},
|
fmt::{self, Debug, Write},
|
||||||
mem,
|
mem,
|
||||||
|
|
|
@ -28,7 +28,7 @@ use {
|
||||||
assert_matches::debug_assert_matches,
|
assert_matches::debug_assert_matches,
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
fmt::{self, Debug, Display, Write},
|
fmt::{self, Debug, Display, Write},
|
||||||
format_args as fa, mem,
|
format_args as fa, mem, usize,
|
||||||
},
|
},
|
||||||
hbbytecode::DisasmError,
|
hbbytecode::DisasmError,
|
||||||
};
|
};
|
||||||
|
@ -2602,7 +2602,7 @@ impl<'a> Codegen<'a> {
|
||||||
if let Some((_, f)) = self.tys.find_union_field(u, name) {
|
if let Some((_, f)) = self.tys.find_union_field(u, name) {
|
||||||
Some(Value::ptr(vtarget.id).ty(f.ty))
|
Some(Value::ptr(vtarget.id).ty(f.ty))
|
||||||
} else if let ty = self.find_type(pos, self.ci.file, u, name)
|
} else if let ty = self.find_type(pos, self.ci.file, u, name)
|
||||||
&& let ty::Kind::Func(_) = ty.expand()
|
&& let ty::Kind::Func(_) | ty::Kind::Template(_) = ty.expand()
|
||||||
{
|
{
|
||||||
return Some(Err((ty, vtarget)));
|
return Some(Err((ty, vtarget)));
|
||||||
} else {
|
} else {
|
||||||
|
@ -2626,7 +2626,7 @@ impl<'a> Codegen<'a> {
|
||||||
if let Some((offset, ty)) = OffsetIter::offset_of(self.tys, s, name) {
|
if let Some((offset, ty)) = OffsetIter::offset_of(self.tys, s, name) {
|
||||||
Some(Value::ptr(self.offset(vtarget.id, offset)).ty(ty))
|
Some(Value::ptr(self.offset(vtarget.id, offset)).ty(ty))
|
||||||
} else if let ty = self.find_type(pos, self.ci.file, s, name)
|
} else if let ty = self.find_type(pos, self.ci.file, s, name)
|
||||||
&& let ty::Kind::Func(_) = ty.expand()
|
&& let ty::Kind::Func(_) | ty::Kind::Template(_) = ty.expand()
|
||||||
{
|
{
|
||||||
return Some(Err((ty, vtarget)));
|
return Some(Err((ty, vtarget)));
|
||||||
} else {
|
} else {
|
||||||
|
@ -2788,7 +2788,7 @@ impl<'a> Codegen<'a> {
|
||||||
ref e => (self.ty(e), None),
|
ref e => (self.ty(e), None),
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(fu) = self.compute_signature(ty, func.pos(), args) else {
|
let Some(fu) = self.compute_signature(ty, func.pos(), args, caller.is_some()) else {
|
||||||
return Value::NEVER;
|
return Value::NEVER;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3170,7 +3170,13 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_signature(&mut self, func: ty::Id, pos: Pos, args: &[Expr]) -> Option<ty::Func> {
|
fn compute_signature(
|
||||||
|
&mut self,
|
||||||
|
func: ty::Id,
|
||||||
|
pos: Pos,
|
||||||
|
args: &[Expr],
|
||||||
|
implici_caller: bool,
|
||||||
|
) -> Option<ty::Func> {
|
||||||
let template = match func.expand() {
|
let template = match func.expand() {
|
||||||
ty::Kind::Func(f) => return Some(f),
|
ty::Kind::Func(f) => return Some(f),
|
||||||
ty::Kind::Template(t) => t,
|
ty::Kind::Template(t) => t,
|
||||||
|
@ -3191,7 +3197,11 @@ impl<'a> Codegen<'a> {
|
||||||
let arg_base = self.tys.tmp.args.len();
|
let arg_base = self.tys.tmp.args.len();
|
||||||
|
|
||||||
let base = self.ci.scope.vars.len();
|
let base = self.ci.scope.vars.len();
|
||||||
for (arg, carg) in args.iter().zip(cargs) {
|
if implici_caller {
|
||||||
|
let caller = self.ty_in(file, parent, &cargs[0].ty);
|
||||||
|
self.tys.tmp.args.push(caller);
|
||||||
|
}
|
||||||
|
for (arg, carg) in args.iter().zip(cargs.iter().skip(implici_caller as usize)) {
|
||||||
let ty = self.ty_in(file, parent, &carg.ty);
|
let ty = self.ty_in(file, parent, &carg.ty);
|
||||||
|
|
||||||
self.tys.tmp.args.push(ty);
|
self.tys.tmp.args.push(ty);
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
b:
|
||||||
|
CP r13, r3
|
||||||
|
CP r1, r13
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -32d
|
||||||
|
ST r31, r254, 8a, 24h
|
||||||
|
ADDI64 r32, r254, 0d
|
||||||
|
LI64 r33, 100d
|
||||||
|
ST r33, r254, 0a, 8h
|
||||||
|
CP r2, r32
|
||||||
|
CP r3, r33
|
||||||
|
JAL r31, r0, :b
|
||||||
|
CP r32, r1
|
||||||
|
CP r1, r32
|
||||||
|
LD r31, r254, 8a, 24h
|
||||||
|
ADDI64 r254, r254, 32d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 137
|
||||||
|
ret: 100
|
||||||
|
status: Ok(())
|
Loading…
Reference in a new issue