nac3core: do not alloc call if it is monomorphic

This commit is contained in:
pca006132 2021-09-22 15:56:53 +08:00
parent 5ed2b450d3
commit 1b5ac3cd25
2 changed files with 20 additions and 23 deletions

View File

@ -650,10 +650,18 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
) )
}); });
params.extend(kw_iter); params.extend(kw_iter);
let signature = self let call = self.calls.get(&expr.location.into());
.unifier let signature = match call {
.get_call_signature(*self.calls.get(&expr.location.into()).unwrap()) Some(call) => self.unifier.get_call_signature(*call).unwrap(),
.unwrap(); None => {
let ty = func.custom.unwrap();
if let TypeEnum::TFunc(sign) = &*self.unifier.get_ty(ty) {
sign.borrow().clone()
} else {
unreachable!()
}
}
};
match &func.as_ref().node { match &func.as_ref().node {
ExprKind::Name { id, .. } => { ExprKind::Name { id, .. } => {
// TODO: handle primitive casts and function pointers // TODO: handle primitive casts and function pointers

View File

@ -180,7 +180,9 @@ impl<'a> fold::Fold<()> for Inferencer<'a> {
Some(self.infer_attribute(value, attr)?) Some(self.infer_attribute(value, attr)?)
} }
ast::ExprKind::BoolOp { values, .. } => Some(self.infer_bool_ops(values)?), ast::ExprKind::BoolOp { values, .. } => Some(self.infer_bool_ops(values)?),
ast::ExprKind::BinOp { left, op, right } => Some(self.infer_bin_ops(expr.location, left, op, right)?), ast::ExprKind::BinOp { left, op, right } => {
Some(self.infer_bin_ops(expr.location, left, op, right)?)
}
ast::ExprKind::UnaryOp { op, operand } => Some(self.infer_unary_ops(op, operand)?), ast::ExprKind::UnaryOp { op, operand } => Some(self.infer_unary_ops(op, operand)?),
ast::ExprKind::Compare { left, ops, comparators } => { ast::ExprKind::Compare { left, ops, comparators } => {
Some(self.infer_compare(left, ops, comparators)?) Some(self.infer_compare(left, ops, comparators)?)
@ -246,17 +248,10 @@ impl<'a> Inferencer<'a> {
if let TypeEnum::TFunc(sign) = &*self.unifier.get_ty(*ty) { if let TypeEnum::TFunc(sign) = &*self.unifier.get_ty(*ty) {
let sign = sign.borrow(); let sign = sign.borrow();
if sign.vars.is_empty() { if sign.vars.is_empty() {
let call = self.unifier.add_call(Call {
posargs: params,
kwargs: HashMap::new(),
fun: RefCell::new(Some(*ty)),
ret: sign.ret,
});
if let Some(ret) = ret { if let Some(ret) = ret {
self.unifier.unify(sign.ret, ret).unwrap(); self.unifier.unify(sign.ret, ret).unwrap();
} }
self.calls.insert(location.into(), call); return Ok(sign.ret);
return Ok(sign.ret)
} }
} }
} }
@ -488,17 +483,11 @@ impl<'a> Inferencer<'a> {
if let TypeEnum::TFunc(sign) = &*self.unifier.get_ty(func.custom.unwrap()) { if let TypeEnum::TFunc(sign) = &*self.unifier.get_ty(func.custom.unwrap()) {
let sign = sign.borrow(); let sign = sign.borrow();
if sign.vars.is_empty() { if sign.vars.is_empty() {
let call = self.unifier.add_call(Call { return Ok(Located {
posargs: args.iter().map(|v| v.custom.unwrap()).collect(), location,
kwargs: keywords custom: Some(sign.ret),
.iter() node: ExprKind::Call { func, args, keywords },
.map(|v| (v.node.arg.as_ref().unwrap().clone(), v.custom.unwrap()))
.collect(),
fun: RefCell::new(func.custom),
ret: sign.ret,
}); });
self.calls.insert(location.into(), call);
return Ok(Located { location, custom: Some(sign.ret), node: ExprKind::Call { func, args, keywords } })
} }
} }