forked from M-Labs/nac3
meta: Apply clippy suggested changes
This commit is contained in:
parent
ef04696b02
commit
d304afd333
|
@ -91,9 +91,9 @@ impl<'a> ArtiqCodeGenerator<'a> {
|
||||||
///
|
///
|
||||||
/// Direct-`parallel` block context refers to when the generator is generating statements whose
|
/// Direct-`parallel` block context refers to when the generator is generating statements whose
|
||||||
/// closest parent `with` statement is a `with parallel` block.
|
/// closest parent `with` statement is a `with parallel` block.
|
||||||
fn timeline_reset_start<'ctx, 'b>(
|
fn timeline_reset_start(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'b>
|
ctx: &mut CodeGenContext<'_, '_>
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
if let Some(start) = self.start.clone() {
|
if let Some(start) = self.start.clone() {
|
||||||
let start_val = self.gen_expr(ctx, &start)?
|
let start_val = self.gen_expr(ctx, &start)?
|
||||||
|
@ -117,9 +117,9 @@ impl<'a> ArtiqCodeGenerator<'a> {
|
||||||
///
|
///
|
||||||
/// * `store_name` - The LLVM value name for the pointer to `end`. `.addr` will be appended to
|
/// * `store_name` - The LLVM value name for the pointer to `end`. `.addr` will be appended to
|
||||||
/// the end of the provided value name.
|
/// the end of the provided value name.
|
||||||
fn timeline_update_end_max<'ctx, 'b>(
|
fn timeline_update_end_max(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'b>,
|
ctx: &mut CodeGenContext<'_, '_>,
|
||||||
end: Option<Expr<Option<Type>>>,
|
end: Option<Expr<Option<Type>>>,
|
||||||
store_name: Option<&str>,
|
store_name: Option<&str>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
|
@ -192,9 +192,9 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_call<'ctx, 'a>(
|
fn gen_call<'ctx>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
obj: Option<(Type, ValueEnum<'ctx>)>,
|
obj: Option<(Type, ValueEnum<'ctx>)>,
|
||||||
fun: (&FunSignature, DefinitionId),
|
fun: (&FunSignature, DefinitionId),
|
||||||
params: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
params: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
||||||
|
@ -210,9 +210,9 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_with<'ctx, 'a>(
|
fn gen_with(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'_, '_>,
|
||||||
stmt: &Stmt<Option<Type>>,
|
stmt: &Stmt<Option<Type>>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
if let StmtKind::With { items, body, .. } = &stmt.node {
|
if let StmtKind::With { items, body, .. } = &stmt.node {
|
||||||
|
@ -360,8 +360,8 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_rpc_tag<'ctx, 'a>(
|
fn gen_rpc_tag(
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'_, '_>,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
buffer: &mut Vec<u8>,
|
buffer: &mut Vec<u8>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
|
@ -406,8 +406,8 @@ fn gen_rpc_tag<'ctx, 'a>(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rpc_codegen_callback_fn<'ctx, 'a>(
|
fn rpc_codegen_callback_fn<'ctx>(
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
obj: Option<(Type, ValueEnum<'ctx>)>,
|
obj: Option<(Type, ValueEnum<'ctx>)>,
|
||||||
fun: (&FunSignature, DefinitionId),
|
fun: (&FunSignature, DefinitionId),
|
||||||
args: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
args: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
||||||
|
@ -617,8 +617,8 @@ fn rpc_codegen_callback_fn<'ctx, 'a>(
|
||||||
Ok(Some(result))
|
Ok(Some(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attributes_writeback<'ctx, 'a>(
|
pub fn attributes_writeback(
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'_, '_>,
|
||||||
generator: &mut dyn CodeGenerator,
|
generator: &mut dyn CodeGenerator,
|
||||||
inner_resolver: &InnerResolver,
|
inner_resolver: &InnerResolver,
|
||||||
host_attributes: PyObject,
|
host_attributes: PyObject,
|
||||||
|
|
|
@ -259,9 +259,8 @@ impl Nac3 {
|
||||||
};
|
};
|
||||||
if let Err(e) = unifier.unify(in_ty, *ty) {
|
if let Err(e) = unifier.unify(in_ty, *ty) {
|
||||||
return Some(format!(
|
return Some(format!(
|
||||||
"type error ({}) at parameter #{} when calling kernel function",
|
"type error ({}) at parameter #{i} when calling kernel function",
|
||||||
e.to_display(unifier).to_string(),
|
e.to_display(unifier),
|
||||||
i
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1020,7 +1019,7 @@ impl Nac3 {
|
||||||
let link_fn = |module: &Module| {
|
let link_fn = |module: &Module| {
|
||||||
let working_directory = self.working_directory.path().to_owned();
|
let working_directory = self.working_directory.path().to_owned();
|
||||||
target_machine
|
target_machine
|
||||||
.write_to_file(&module, FileType::Object, &working_directory.join("module.o"))
|
.write_to_file(module, FileType::Object, &working_directory.join("module.o"))
|
||||||
.expect("couldn't write module to file");
|
.expect("couldn't write module to file");
|
||||||
|
|
||||||
let filename_path = self.working_directory.path().join("module.elf");
|
let filename_path = self.working_directory.path().join("module.elf");
|
||||||
|
@ -1037,7 +1036,7 @@ impl Nac3 {
|
||||||
} else {
|
} else {
|
||||||
let link_fn = |module: &Module| {
|
let link_fn = |module: &Module| {
|
||||||
let object_mem = target_machine
|
let object_mem = target_machine
|
||||||
.write_to_memory_buffer(&module, FileType::Object)
|
.write_to_memory_buffer(module, FileType::Object)
|
||||||
.expect("couldn't write module to object file buffer");
|
.expect("couldn't write module to object file buffer");
|
||||||
if let Ok(dyn_lib) = Linker::ld(object_mem.as_slice()) {
|
if let Ok(dyn_lib) = Linker::ld(object_mem.as_slice()) {
|
||||||
Ok(PyBytes::new(py, &dyn_lib).into())
|
Ok(PyBytes::new(py, &dyn_lib).into())
|
||||||
|
|
|
@ -93,9 +93,9 @@ impl StaticValue for PythonValue {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_const_obj<'ctx, 'a>(
|
fn get_const_obj<'ctx>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
_: &mut dyn CodeGenerator,
|
_: &mut dyn CodeGenerator,
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
ctx.module
|
ctx.module
|
||||||
|
@ -148,10 +148,10 @@ impl StaticValue for PythonValue {
|
||||||
}).map_err(|e| e.to_string())
|
}).map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_field<'ctx, 'a>(
|
fn get_field<'ctx>(
|
||||||
&self,
|
&self,
|
||||||
name: StrRef,
|
name: StrRef,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
) -> Option<ValueEnum<'ctx>> {
|
) -> Option<ValueEnum<'ctx>> {
|
||||||
{
|
{
|
||||||
let field_to_val = self.resolver.field_to_val.read();
|
let field_to_val = self.resolver.field_to_val.read();
|
||||||
|
@ -256,9 +256,8 @@ impl InnerResolver {
|
||||||
Ok(_) => ty,
|
Ok(_) => ty,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Ok(Err(format!(
|
return Ok(Err(format!(
|
||||||
"inhomogeneous type ({}) at element #{} of the list",
|
"inhomogeneous type ({}) at element #{i} of the list",
|
||||||
e.to_display(unifier).to_string(),
|
e.to_display(unifier)
|
||||||
i
|
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -294,9 +293,7 @@ impl InnerResolver {
|
||||||
Ok(Ok((primitives.uint64, true)))
|
Ok(Ok((primitives.uint64, true)))
|
||||||
} else if ty_id == self.primitive_ids.bool {
|
} else if ty_id == self.primitive_ids.bool {
|
||||||
Ok(Ok((primitives.bool, true)))
|
Ok(Ok((primitives.bool, true)))
|
||||||
} else if ty_id == self.primitive_ids.float {
|
} else if ty_id == self.primitive_ids.float || ty_id == self.primitive_ids.float64 {
|
||||||
Ok(Ok((primitives.float, true)))
|
|
||||||
} else if ty_id == self.primitive_ids.float64 {
|
|
||||||
Ok(Ok((primitives.float, true)))
|
Ok(Ok((primitives.float, true)))
|
||||||
} else if ty_id == self.primitive_ids.exception {
|
} else if ty_id == self.primitive_ids.exception {
|
||||||
Ok(Ok((primitives.exception, true)))
|
Ok(Ok((primitives.exception, true)))
|
||||||
|
@ -577,7 +574,7 @@ impl InnerResolver {
|
||||||
object_id, methods, constructor, ..
|
object_id, methods, constructor, ..
|
||||||
} = &*def.read() {
|
} = &*def.read() {
|
||||||
if object_id == def_id && constructor.is_some() && methods.iter().any(|(s, _, _)| s == &"__init__".into()) {
|
if object_id == def_id && constructor.is_some() && methods.iter().any(|(s, _, _)| s == &"__init__".into()) {
|
||||||
return constructor.clone();
|
return *constructor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
@ -630,7 +627,7 @@ impl InnerResolver {
|
||||||
Ok(_) => Ok(Ok(unifier.add_ty(TypeEnum::TList { ty: *ty }))),
|
Ok(_) => Ok(Ok(unifier.add_ty(TypeEnum::TList { ty: *ty }))),
|
||||||
Err(e) => Ok(Err(format!(
|
Err(e) => Ok(Err(format!(
|
||||||
"type error ({}) for the list",
|
"type error ({}) for the list",
|
||||||
e.to_display(unifier).to_string()
|
e.to_display(unifier)
|
||||||
))),
|
))),
|
||||||
},
|
},
|
||||||
Err(e) => Ok(Err(e)),
|
Err(e) => Ok(Err(e)),
|
||||||
|
@ -734,9 +731,8 @@ impl InnerResolver {
|
||||||
if let Err(e) = unifier.unify(ty, field_ty) {
|
if let Err(e) = unifier.unify(ty, field_ty) {
|
||||||
// field type mismatch
|
// field type mismatch
|
||||||
return Ok(Err(format!(
|
return Ok(Err(format!(
|
||||||
"error when getting type of field `{}` ({})",
|
"error when getting type of field `{name}` ({})",
|
||||||
name,
|
e.to_display(unifier)
|
||||||
e.to_display(unifier).to_string()
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -797,11 +793,11 @@ impl InnerResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_obj_value<'ctx, 'a>(
|
pub fn get_obj_value<'ctx>(
|
||||||
&self,
|
&self,
|
||||||
py: Python,
|
py: Python,
|
||||||
obj: &PyAny,
|
obj: &PyAny,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
generator: &mut dyn CodeGenerator,
|
generator: &mut dyn CodeGenerator,
|
||||||
expected_ty: Type,
|
expected_ty: Type,
|
||||||
) -> PyResult<Option<BasicValueEnum<'ctx>>> {
|
) -> PyResult<Option<BasicValueEnum<'ctx>>> {
|
||||||
|
@ -1151,10 +1147,10 @@ impl SymbolResolver for Resolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_symbol_value<'ctx, 'a>(
|
fn get_symbol_value<'ctx>(
|
||||||
&self,
|
&self,
|
||||||
id: StrRef,
|
id: StrRef,
|
||||||
_: &mut CodeGenContext<'ctx, 'a>,
|
_: &mut CodeGenContext<'ctx, '_>,
|
||||||
) -> Option<ValueEnum<'ctx>> {
|
) -> Option<ValueEnum<'ctx>> {
|
||||||
let sym_value = {
|
let sym_value = {
|
||||||
let id_to_val = self.0.id_to_pyval.read();
|
let id_to_val = self.0.id_to_pyval.read();
|
||||||
|
|
|
@ -5,13 +5,13 @@ use nac3core::codegen::CodeGenContext;
|
||||||
pub trait TimeFns {
|
pub trait TimeFns {
|
||||||
|
|
||||||
/// Emits LLVM IR for `now_mu`.
|
/// Emits LLVM IR for `now_mu`.
|
||||||
fn emit_now_mu<'ctx, 'a>(&self, ctx: &mut CodeGenContext<'ctx, 'a>) -> BasicValueEnum<'ctx>;
|
fn emit_now_mu<'ctx>(&self, ctx: &mut CodeGenContext<'ctx, '_>) -> BasicValueEnum<'ctx>;
|
||||||
|
|
||||||
/// Emits LLVM IR for `at_mu`.
|
/// Emits LLVM IR for `at_mu`.
|
||||||
fn emit_at_mu<'ctx, 'a>(&self, ctx: &mut CodeGenContext<'ctx, 'a>, t: BasicValueEnum<'ctx>);
|
fn emit_at_mu<'ctx>(&self, ctx: &mut CodeGenContext<'ctx, '_>, t: BasicValueEnum<'ctx>);
|
||||||
|
|
||||||
/// Emits LLVM IR for `delay_mu`.
|
/// Emits LLVM IR for `delay_mu`.
|
||||||
fn emit_delay_mu<'ctx, 'a>(&self, ctx: &mut CodeGenContext<'ctx, 'a>, dt: BasicValueEnum<'ctx>);
|
fn emit_delay_mu<'ctx>(&self, ctx: &mut CodeGenContext<'ctx, '_>, dt: BasicValueEnum<'ctx>);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NowPinningTimeFns64 {}
|
pub struct NowPinningTimeFns64 {}
|
||||||
|
@ -19,7 +19,7 @@ pub struct NowPinningTimeFns64 {}
|
||||||
// For FPGA design reasons, on VexRiscv with 64-bit data bus, the "now" CSR is split into two 32-bit
|
// For FPGA design reasons, on VexRiscv with 64-bit data bus, the "now" CSR is split into two 32-bit
|
||||||
// values that are each padded to 64-bits.
|
// values that are each padded to 64-bits.
|
||||||
impl TimeFns for NowPinningTimeFns64 {
|
impl TimeFns for NowPinningTimeFns64 {
|
||||||
fn emit_now_mu<'ctx, 'a>(&self, ctx: &mut CodeGenContext<'ctx, 'a>) -> BasicValueEnum<'ctx> {
|
fn emit_now_mu<'ctx>(&self, ctx: &mut CodeGenContext<'ctx, '_>) -> BasicValueEnum<'ctx> {
|
||||||
let i64_type = ctx.ctx.i64_type();
|
let i64_type = ctx.ctx.i64_type();
|
||||||
let i32_type = ctx.ctx.i32_type();
|
let i32_type = ctx.ctx.i32_type();
|
||||||
let now = ctx
|
let now = ctx
|
||||||
|
@ -54,7 +54,7 @@ impl TimeFns for NowPinningTimeFns64 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_at_mu<'ctx, 'a>(&self, ctx: &mut CodeGenContext<'ctx, 'a>, t: BasicValueEnum<'ctx>) {
|
fn emit_at_mu<'ctx>(&self, ctx: &mut CodeGenContext<'ctx, '_>, t: BasicValueEnum<'ctx>) {
|
||||||
let i32_type = ctx.ctx.i32_type();
|
let i32_type = ctx.ctx.i32_type();
|
||||||
let i64_type = ctx.ctx.i64_type();
|
let i64_type = ctx.ctx.i64_type();
|
||||||
|
|
||||||
|
@ -96,9 +96,9 @@ impl TimeFns for NowPinningTimeFns64 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_delay_mu<'ctx, 'a>(
|
fn emit_delay_mu<'ctx>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
dt: BasicValueEnum<'ctx>,
|
dt: BasicValueEnum<'ctx>,
|
||||||
) {
|
) {
|
||||||
let i64_type = ctx.ctx.i64_type();
|
let i64_type = ctx.ctx.i64_type();
|
||||||
|
@ -168,7 +168,7 @@ pub static NOW_PINNING_TIME_FNS_64: NowPinningTimeFns64 = NowPinningTimeFns64 {}
|
||||||
pub struct NowPinningTimeFns {}
|
pub struct NowPinningTimeFns {}
|
||||||
|
|
||||||
impl TimeFns for NowPinningTimeFns {
|
impl TimeFns for NowPinningTimeFns {
|
||||||
fn emit_now_mu<'ctx, 'a>(&self, ctx: &mut CodeGenContext<'ctx, 'a>) -> BasicValueEnum<'ctx> {
|
fn emit_now_mu<'ctx>(&self, ctx: &mut CodeGenContext<'ctx, '_>) -> BasicValueEnum<'ctx> {
|
||||||
let i64_type = ctx.ctx.i64_type();
|
let i64_type = ctx.ctx.i64_type();
|
||||||
let now = ctx
|
let now = ctx
|
||||||
.module
|
.module
|
||||||
|
@ -186,7 +186,7 @@ impl TimeFns for NowPinningTimeFns {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_at_mu<'ctx, 'a>(&self, ctx: &mut CodeGenContext<'ctx, 'a>, t: BasicValueEnum<'ctx>) {
|
fn emit_at_mu<'ctx>(&self, ctx: &mut CodeGenContext<'ctx, '_>, t: BasicValueEnum<'ctx>) {
|
||||||
let i32_type = ctx.ctx.i32_type();
|
let i32_type = ctx.ctx.i32_type();
|
||||||
let i64_type = ctx.ctx.i64_type();
|
let i64_type = ctx.ctx.i64_type();
|
||||||
let i64_32 = i64_type.const_int(32, false);
|
let i64_32 = i64_type.const_int(32, false);
|
||||||
|
@ -228,9 +228,9 @@ impl TimeFns for NowPinningTimeFns {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_delay_mu<'ctx, 'a>(
|
fn emit_delay_mu<'ctx>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
dt: BasicValueEnum<'ctx>,
|
dt: BasicValueEnum<'ctx>,
|
||||||
) {
|
) {
|
||||||
let i32_type = ctx.ctx.i32_type();
|
let i32_type = ctx.ctx.i32_type();
|
||||||
|
@ -285,14 +285,14 @@ pub static NOW_PINNING_TIME_FNS: NowPinningTimeFns = NowPinningTimeFns {};
|
||||||
pub struct ExternTimeFns {}
|
pub struct ExternTimeFns {}
|
||||||
|
|
||||||
impl TimeFns for ExternTimeFns {
|
impl TimeFns for ExternTimeFns {
|
||||||
fn emit_now_mu<'ctx, 'a>(&self, ctx: &mut CodeGenContext<'ctx, 'a>) -> BasicValueEnum<'ctx> {
|
fn emit_now_mu<'ctx>(&self, ctx: &mut CodeGenContext<'ctx, '_>) -> BasicValueEnum<'ctx> {
|
||||||
let now_mu = ctx.module.get_function("now_mu").unwrap_or_else(|| {
|
let now_mu = ctx.module.get_function("now_mu").unwrap_or_else(|| {
|
||||||
ctx.module.add_function("now_mu", ctx.ctx.i64_type().fn_type(&[], false), None)
|
ctx.module.add_function("now_mu", ctx.ctx.i64_type().fn_type(&[], false), None)
|
||||||
});
|
});
|
||||||
ctx.builder.build_call(now_mu, &[], "now_mu").try_as_basic_value().left().unwrap()
|
ctx.builder.build_call(now_mu, &[], "now_mu").try_as_basic_value().left().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_at_mu<'ctx, 'a>(&self, ctx: &mut CodeGenContext<'ctx, 'a>, t: BasicValueEnum<'ctx>) {
|
fn emit_at_mu<'ctx>(&self, ctx: &mut CodeGenContext<'ctx, '_>, t: BasicValueEnum<'ctx>) {
|
||||||
let at_mu = ctx.module.get_function("at_mu").unwrap_or_else(|| {
|
let at_mu = ctx.module.get_function("at_mu").unwrap_or_else(|| {
|
||||||
ctx.module.add_function(
|
ctx.module.add_function(
|
||||||
"at_mu",
|
"at_mu",
|
||||||
|
@ -303,9 +303,9 @@ impl TimeFns for ExternTimeFns {
|
||||||
ctx.builder.build_call(at_mu, &[t.into()], "at_mu");
|
ctx.builder.build_call(at_mu, &[t.into()], "at_mu");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_delay_mu<'ctx, 'a>(
|
fn emit_delay_mu<'ctx>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
dt: BasicValueEnum<'ctx>,
|
dt: BasicValueEnum<'ctx>,
|
||||||
) {
|
) {
|
||||||
let delay_mu = ctx.module.get_function("delay_mu").unwrap_or_else(|| {
|
let delay_mu = ctx.module.get_function("delay_mu").unwrap_or_else(|| {
|
||||||
|
|
|
@ -194,7 +194,7 @@ impl ConcreteTypeStore {
|
||||||
ty: self.from_unifier_type(unifier, primitives, *ty, cache),
|
ty: self.from_unifier_type(unifier, primitives, *ty, cache),
|
||||||
},
|
},
|
||||||
TypeEnum::TFunc(signature) => {
|
TypeEnum::TFunc(signature) => {
|
||||||
self.from_signature(unifier, primitives, &*signature, cache)
|
self.from_signature(unifier, primitives, signature, cache)
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -237,7 +237,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
||||||
let ty = self.unifier.get_ty(ty);
|
let ty = self.unifier.get_ty(ty);
|
||||||
let types =
|
let types =
|
||||||
if let TypeEnum::TTuple { ty } = &*ty { ty.clone() } else { unreachable!() };
|
if let TypeEnum::TTuple { ty } = &*ty { ty.clone() } else { unreachable!() };
|
||||||
let values = zip(types.into_iter(), v.iter())
|
let values = zip(types, v.iter())
|
||||||
.map_while(|(ty, v)| self.gen_const(generator, v, ty))
|
.map_while(|(ty, v)| self.gen_const(generator, v, ty))
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
|
||||||
|
@ -609,7 +609,7 @@ pub fn gen_constructor<'ctx, 'a, G: CodeGenerator>(
|
||||||
match def {
|
match def {
|
||||||
TopLevelDef::Class { methods, .. } => {
|
TopLevelDef::Class { methods, .. } => {
|
||||||
// TODO: what about other fields that require alloca?
|
// TODO: what about other fields that require alloca?
|
||||||
let fun_id = methods.iter().find(|method| method.0 == "__init__".into()).and_then(|method| Some(method.2));
|
let fun_id = methods.iter().find(|method| method.0 == "__init__".into()).map(|method| method.2);
|
||||||
let ty = ctx.get_llvm_type(generator, signature.ret).into_pointer_type();
|
let ty = ctx.get_llvm_type(generator, signature.ret).into_pointer_type();
|
||||||
let zelf_ty: BasicTypeEnum = ty.get_element_type().try_into().unwrap();
|
let zelf_ty: BasicTypeEnum = ty.get_element_type().try_into().unwrap();
|
||||||
let zelf: BasicValueEnum<'ctx> = ctx.builder.build_alloca(zelf_ty, "alloca").into();
|
let zelf: BasicValueEnum<'ctx> = ctx.builder.build_alloca(zelf_ty, "alloca").into();
|
||||||
|
@ -631,8 +631,8 @@ pub fn gen_constructor<'ctx, 'a, G: CodeGenerator>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [CodeGenerator::gen_func_instance].
|
/// See [CodeGenerator::gen_func_instance].
|
||||||
pub fn gen_func_instance<'ctx, 'a>(
|
pub fn gen_func_instance<'ctx>(
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
obj: Option<(Type, ValueEnum<'ctx>)>,
|
obj: Option<(Type, ValueEnum<'ctx>)>,
|
||||||
fun: (&FunSignature, &mut TopLevelDef, String),
|
fun: (&FunSignature, &mut TopLevelDef, String),
|
||||||
id: usize,
|
id: usize,
|
||||||
|
@ -708,9 +708,9 @@ pub fn gen_func_instance<'ctx, 'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [CodeGenerator::gen_call].
|
/// See [CodeGenerator::gen_call].
|
||||||
pub fn gen_call<'ctx, 'a, G: CodeGenerator>(
|
pub fn gen_call<'ctx, G: CodeGenerator>(
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
obj: Option<(Type, ValueEnum<'ctx>)>,
|
obj: Option<(Type, ValueEnum<'ctx>)>,
|
||||||
fun: (&FunSignature, DefinitionId),
|
fun: (&FunSignature, DefinitionId),
|
||||||
params: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
params: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
||||||
|
@ -797,7 +797,7 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>(
|
||||||
instance_to_symbol.get(&key).cloned().ok_or_else(|| "".into())
|
instance_to_symbol.get(&key).cloned().ok_or_else(|| "".into())
|
||||||
}
|
}
|
||||||
TopLevelDef::Class { .. } => {
|
TopLevelDef::Class { .. } => {
|
||||||
return Ok(Some(generator.gen_constructor(ctx, fun.0, &*def, params)?))
|
return Ok(Some(generator.gen_constructor(ctx, fun.0, &def, params)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -814,7 +814,7 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>(
|
||||||
} else {
|
} else {
|
||||||
Some(ctx.get_llvm_abi_type(generator, fun.0.ret))
|
Some(ctx.get_llvm_abi_type(generator, fun.0.ret))
|
||||||
};
|
};
|
||||||
let has_sret = ret_type.map_or(false, |ret_type| need_sret(ctx.ctx, ret_type));
|
let has_sret = ret_type.map_or(false, |ret_type| need_sret(ret_type));
|
||||||
let mut byrefs = Vec::new();
|
let mut byrefs = Vec::new();
|
||||||
let mut params = args.iter().enumerate()
|
let mut params = args.iter().enumerate()
|
||||||
.map(|(i, arg)| match ctx.get_llvm_abi_type(generator, arg.ty) {
|
.map(|(i, arg)| match ctx.get_llvm_abi_type(generator, arg.ty) {
|
||||||
|
@ -858,7 +858,7 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>(
|
||||||
});
|
});
|
||||||
|
|
||||||
// Convert boolean parameter values into i1
|
// Convert boolean parameter values into i1
|
||||||
let param_vals = (&fun_val.get_params()).iter().zip(param_vals)
|
let param_vals = fun_val.get_params().iter().zip(param_vals)
|
||||||
.map(|(p, v)| {
|
.map(|(p, v)| {
|
||||||
if p.is_int_value() && v.is_int_value() {
|
if p.is_int_value() && v.is_int_value() {
|
||||||
let expected_ty = p.into_int_value().get_type();
|
let expected_ty = p.into_int_value().get_type();
|
||||||
|
@ -880,8 +880,8 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>(
|
||||||
|
|
||||||
/// Generates three LLVM variables representing the start, stop, and step values of a [range] class
|
/// Generates three LLVM variables representing the start, stop, and step values of a [range] class
|
||||||
/// respectively.
|
/// respectively.
|
||||||
pub fn destructure_range<'ctx, 'a>(
|
pub fn destructure_range<'ctx>(
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
range: PointerValue<'ctx>,
|
range: PointerValue<'ctx>,
|
||||||
) -> (IntValue<'ctx>, IntValue<'ctx>, IntValue<'ctx>) {
|
) -> (IntValue<'ctx>, IntValue<'ctx>, IntValue<'ctx>) {
|
||||||
let int32 = ctx.ctx.i32_type();
|
let int32 = ctx.ctx.i32_type();
|
||||||
|
@ -903,9 +903,9 @@ pub fn destructure_range<'ctx, 'a>(
|
||||||
/// Returns an instance of [PointerValue] pointing to the List structure. The List structure is
|
/// Returns an instance of [PointerValue] pointing to the List structure. The List structure is
|
||||||
/// defined as `type { ty*, size_t }` in LLVM, where the first element stores the pointer to the
|
/// defined as `type { ty*, size_t }` in LLVM, where the first element stores the pointer to the
|
||||||
/// data, and the second element stores the size of the List.
|
/// data, and the second element stores the size of the List.
|
||||||
pub fn allocate_list<'ctx, 'a, G: CodeGenerator>(
|
pub fn allocate_list<'ctx, G: CodeGenerator>(
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
ty: BasicTypeEnum<'ctx>,
|
ty: BasicTypeEnum<'ctx>,
|
||||||
length: IntValue<'ctx>,
|
length: IntValue<'ctx>,
|
||||||
name: Option<&str>,
|
name: Option<&str>,
|
||||||
|
@ -949,9 +949,9 @@ pub fn allocate_list<'ctx, 'a, G: CodeGenerator>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates LLVM IR for a [list comprehension expression][expr].
|
/// Generates LLVM IR for a [list comprehension expression][expr].
|
||||||
pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
pub fn gen_comprehension<'ctx, G: CodeGenerator>(
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
expr: &Expr<Option<Type>>,
|
expr: &Expr<Option<Type>>,
|
||||||
) -> Result<Option<BasicValueEnum<'ctx>>, String> {
|
) -> Result<Option<BasicValueEnum<'ctx>>, String> {
|
||||||
if let ExprKind::ListComp { elt, generators } = &expr.node {
|
if let ExprKind::ListComp { elt, generators } = &expr.node {
|
||||||
|
@ -1129,9 +1129,9 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
||||||
/// * `right` - The right-hand side of the binary operator.
|
/// * `right` - The right-hand side of the binary operator.
|
||||||
/// * `loc` - The location of the full expression.
|
/// * `loc` - The location of the full expression.
|
||||||
/// * `is_aug_assign` - Whether the binary operator expression is also an assignment operator.
|
/// * `is_aug_assign` - Whether the binary operator expression is also an assignment operator.
|
||||||
pub fn gen_binop_expr<'ctx, 'a, G: CodeGenerator>(
|
pub fn gen_binop_expr<'ctx, G: CodeGenerator>(
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
left: &Expr<Option<Type>>,
|
left: &Expr<Option<Type>>,
|
||||||
op: &Operator,
|
op: &Operator,
|
||||||
right: &Expr<Option<Type>>,
|
right: &Expr<Option<Type>>,
|
||||||
|
@ -1231,9 +1231,9 @@ pub fn gen_binop_expr<'ctx, 'a, G: CodeGenerator>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [CodeGenerator::gen_expr].
|
/// See [CodeGenerator::gen_expr].
|
||||||
pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
pub fn gen_expr<'ctx, G: CodeGenerator>(
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
expr: &Expr<Option<Type>>,
|
expr: &Expr<Option<Type>>,
|
||||||
) -> Result<Option<ValueEnum<'ctx>>, String> {
|
) -> Result<Option<ValueEnum<'ctx>>, String> {
|
||||||
ctx.current_loc = expr.location;
|
ctx.current_loc = expr.location;
|
||||||
|
|
|
@ -22,9 +22,9 @@ pub trait CodeGenerator {
|
||||||
/// - fun: Function signature and definition ID.
|
/// - fun: Function signature and definition ID.
|
||||||
/// - params: Function parameters. Note that this does not include the object even if the
|
/// - params: Function parameters. Note that this does not include the object even if the
|
||||||
/// function is a class method.
|
/// function is a class method.
|
||||||
fn gen_call<'ctx, 'a>(
|
fn gen_call<'ctx>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
obj: Option<(Type, ValueEnum<'ctx>)>,
|
obj: Option<(Type, ValueEnum<'ctx>)>,
|
||||||
fun: (&FunSignature, DefinitionId),
|
fun: (&FunSignature, DefinitionId),
|
||||||
params: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
params: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
||||||
|
@ -39,9 +39,9 @@ pub trait CodeGenerator {
|
||||||
/// - signature: Function signature of the constructor.
|
/// - signature: Function signature of the constructor.
|
||||||
/// - def: Class definition for the constructor class.
|
/// - def: Class definition for the constructor class.
|
||||||
/// - params: Function parameters.
|
/// - params: Function parameters.
|
||||||
fn gen_constructor<'ctx, 'a>(
|
fn gen_constructor<'ctx>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
signature: &FunSignature,
|
signature: &FunSignature,
|
||||||
def: &TopLevelDef,
|
def: &TopLevelDef,
|
||||||
params: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
params: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
||||||
|
@ -59,9 +59,9 @@ pub trait CodeGenerator {
|
||||||
/// function is a class method.
|
/// function is a class method.
|
||||||
/// Note that this function should check if the function is generated in another thread (due to
|
/// Note that this function should check if the function is generated in another thread (due to
|
||||||
/// possible race condition), see the default implementation for an example.
|
/// possible race condition), see the default implementation for an example.
|
||||||
fn gen_func_instance<'ctx, 'a>(
|
fn gen_func_instance<'ctx>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
obj: Option<(Type, ValueEnum<'ctx>)>,
|
obj: Option<(Type, ValueEnum<'ctx>)>,
|
||||||
fun: (&FunSignature, &mut TopLevelDef, String),
|
fun: (&FunSignature, &mut TopLevelDef, String),
|
||||||
id: usize,
|
id: usize,
|
||||||
|
@ -70,9 +70,9 @@ pub trait CodeGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate the code for an expression.
|
/// Generate the code for an expression.
|
||||||
fn gen_expr<'ctx, 'a>(
|
fn gen_expr<'ctx>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
expr: &Expr<Option<Type>>,
|
expr: &Expr<Option<Type>>,
|
||||||
) -> Result<Option<ValueEnum<'ctx>>, String>
|
) -> Result<Option<ValueEnum<'ctx>>, String>
|
||||||
where
|
where
|
||||||
|
@ -83,9 +83,9 @@ pub trait CodeGenerator {
|
||||||
|
|
||||||
/// Allocate memory for a variable and return a pointer pointing to it.
|
/// Allocate memory for a variable and return a pointer pointing to it.
|
||||||
/// The default implementation places the allocations at the start of the function.
|
/// The default implementation places the allocations at the start of the function.
|
||||||
fn gen_var_alloc<'ctx, 'a>(
|
fn gen_var_alloc<'ctx>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
ty: BasicTypeEnum<'ctx>,
|
ty: BasicTypeEnum<'ctx>,
|
||||||
name: Option<&str>,
|
name: Option<&str>,
|
||||||
) -> Result<PointerValue<'ctx>, String> {
|
) -> Result<PointerValue<'ctx>, String> {
|
||||||
|
@ -93,9 +93,9 @@ pub trait CodeGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a pointer pointing to the target of the expression.
|
/// Return a pointer pointing to the target of the expression.
|
||||||
fn gen_store_target<'ctx, 'a>(
|
fn gen_store_target<'ctx>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
pattern: &Expr<Option<Type>>,
|
pattern: &Expr<Option<Type>>,
|
||||||
name: Option<&str>,
|
name: Option<&str>,
|
||||||
) -> Result<Option<PointerValue<'ctx>>, String>
|
) -> Result<Option<PointerValue<'ctx>>, String>
|
||||||
|
@ -106,9 +106,9 @@ pub trait CodeGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate code for an assignment expression.
|
/// Generate code for an assignment expression.
|
||||||
fn gen_assign<'ctx, 'a>(
|
fn gen_assign<'ctx>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
target: &Expr<Option<Type>>,
|
target: &Expr<Option<Type>>,
|
||||||
value: ValueEnum<'ctx>,
|
value: ValueEnum<'ctx>,
|
||||||
) -> Result<(), String>
|
) -> Result<(), String>
|
||||||
|
@ -120,9 +120,9 @@ pub trait CodeGenerator {
|
||||||
|
|
||||||
/// Generate code for a while expression.
|
/// Generate code for a while expression.
|
||||||
/// Return true if the while loop must early return
|
/// Return true if the while loop must early return
|
||||||
fn gen_while<'ctx, 'a>(
|
fn gen_while(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'_, '_>,
|
||||||
stmt: &Stmt<Option<Type>>,
|
stmt: &Stmt<Option<Type>>,
|
||||||
) -> Result<(), String>
|
) -> Result<(), String>
|
||||||
where
|
where
|
||||||
|
@ -133,9 +133,9 @@ pub trait CodeGenerator {
|
||||||
|
|
||||||
/// Generate code for a while expression.
|
/// Generate code for a while expression.
|
||||||
/// Return true if the while loop must early return
|
/// Return true if the while loop must early return
|
||||||
fn gen_for<'ctx, 'a>(
|
fn gen_for(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'_, '_>,
|
||||||
stmt: &Stmt<Option<Type>>,
|
stmt: &Stmt<Option<Type>>,
|
||||||
) -> Result<(), String>
|
) -> Result<(), String>
|
||||||
where
|
where
|
||||||
|
@ -146,9 +146,9 @@ pub trait CodeGenerator {
|
||||||
|
|
||||||
/// Generate code for an if expression.
|
/// Generate code for an if expression.
|
||||||
/// Return true if the statement must early return
|
/// Return true if the statement must early return
|
||||||
fn gen_if<'ctx, 'a>(
|
fn gen_if(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'_, '_>,
|
||||||
stmt: &Stmt<Option<Type>>,
|
stmt: &Stmt<Option<Type>>,
|
||||||
) -> Result<(), String>
|
) -> Result<(), String>
|
||||||
where
|
where
|
||||||
|
@ -157,9 +157,9 @@ pub trait CodeGenerator {
|
||||||
gen_if(self, ctx, stmt)
|
gen_if(self, ctx, stmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_with<'ctx, 'a>(
|
fn gen_with(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'_, '_>,
|
||||||
stmt: &Stmt<Option<Type>>,
|
stmt: &Stmt<Option<Type>>,
|
||||||
) -> Result<(), String>
|
) -> Result<(), String>
|
||||||
where
|
where
|
||||||
|
@ -171,9 +171,9 @@ pub trait CodeGenerator {
|
||||||
/// Generate code for a statement
|
/// Generate code for a statement
|
||||||
///
|
///
|
||||||
/// Return true if the statement must early return
|
/// Return true if the statement must early return
|
||||||
fn gen_stmt<'ctx, 'a>(
|
fn gen_stmt(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'_, '_>,
|
||||||
stmt: &Stmt<Option<Type>>,
|
stmt: &Stmt<Option<Type>>,
|
||||||
) -> Result<(), String>
|
) -> Result<(), String>
|
||||||
where
|
where
|
||||||
|
@ -183,9 +183,9 @@ pub trait CodeGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates code for a block statement.
|
/// Generates code for a block statement.
|
||||||
fn gen_block<'ctx, 'a, 'b, I: Iterator<Item = &'b Stmt<Option<Type>>>>(
|
fn gen_block<'a, I: Iterator<Item = &'a Stmt<Option<Type>>>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'_, '_>,
|
||||||
stmts: I,
|
stmts: I,
|
||||||
) -> Result<(), String>
|
) -> Result<(), String>
|
||||||
where
|
where
|
||||||
|
@ -195,21 +195,21 @@ pub trait CodeGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [bool_to_i1].
|
/// See [bool_to_i1].
|
||||||
fn bool_to_i1<'ctx, 'a>(
|
fn bool_to_i1<'ctx>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &CodeGenContext<'ctx, 'a>,
|
ctx: &CodeGenContext<'ctx, '_>,
|
||||||
bool_value: IntValue<'ctx>
|
bool_value: IntValue<'ctx>
|
||||||
) -> IntValue<'ctx> {
|
) -> IntValue<'ctx> {
|
||||||
bool_to_i1(&ctx.builder, bool_value)
|
bool_to_i1(&ctx.builder, bool_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [bool_to_i8].
|
/// See [bool_to_i8].
|
||||||
fn bool_to_i8<'ctx, 'a>(
|
fn bool_to_i8<'ctx>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &CodeGenContext<'ctx, 'a>,
|
ctx: &CodeGenContext<'ctx, '_>,
|
||||||
bool_value: IntValue<'ctx>
|
bool_value: IntValue<'ctx>
|
||||||
) -> IntValue<'ctx> {
|
) -> IntValue<'ctx> {
|
||||||
bool_to_i8(&ctx.builder, &ctx.ctx, bool_value)
|
bool_to_i8(&ctx.builder, ctx.ctx, bool_value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ pub struct DefaultCodeGenerator {
|
||||||
|
|
||||||
impl DefaultCodeGenerator {
|
impl DefaultCodeGenerator {
|
||||||
pub fn new(name: String, size_t: u32) -> DefaultCodeGenerator {
|
pub fn new(name: String, size_t: u32) -> DefaultCodeGenerator {
|
||||||
assert!(size_t == 32 || size_t == 64);
|
assert!(matches!(size_t, 32 | 64));
|
||||||
DefaultCodeGenerator { name, size_t }
|
DefaultCodeGenerator { name, size_t }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,9 @@ pub fn load_irrt(ctx: &Context) -> Module {
|
||||||
|
|
||||||
// repeated squaring method adapted from GNU Scientific Library:
|
// repeated squaring method adapted from GNU Scientific Library:
|
||||||
// https://git.savannah.gnu.org/cgit/gsl.git/tree/sys/pow_int.c
|
// https://git.savannah.gnu.org/cgit/gsl.git/tree/sys/pow_int.c
|
||||||
pub fn integer_power<'ctx, 'a>(
|
pub fn integer_power<'ctx>(
|
||||||
generator: &mut dyn CodeGenerator,
|
generator: &mut dyn CodeGenerator,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
base: IntValue<'ctx>,
|
base: IntValue<'ctx>,
|
||||||
exp: IntValue<'ctx>,
|
exp: IntValue<'ctx>,
|
||||||
signed: bool,
|
signed: bool,
|
||||||
|
@ -74,9 +74,9 @@ pub fn integer_power<'ctx, 'a>(
|
||||||
.into_int_value()
|
.into_int_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn calculate_len_for_slice_range<'ctx, 'a>(
|
pub fn calculate_len_for_slice_range<'ctx>(
|
||||||
generator: &mut dyn CodeGenerator,
|
generator: &mut dyn CodeGenerator,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
start: IntValue<'ctx>,
|
start: IntValue<'ctx>,
|
||||||
end: IntValue<'ctx>,
|
end: IntValue<'ctx>,
|
||||||
step: IntValue<'ctx>,
|
step: IntValue<'ctx>,
|
||||||
|
@ -151,11 +151,11 @@ pub fn calculate_len_for_slice_range<'ctx, 'a>(
|
||||||
/// ,step
|
/// ,step
|
||||||
/// )
|
/// )
|
||||||
/// ```
|
/// ```
|
||||||
pub fn handle_slice_indices<'a, 'ctx, G: CodeGenerator>(
|
pub fn handle_slice_indices<'ctx, G: CodeGenerator>(
|
||||||
start: &Option<Box<Expr<Option<Type>>>>,
|
start: &Option<Box<Expr<Option<Type>>>>,
|
||||||
end: &Option<Box<Expr<Option<Type>>>>,
|
end: &Option<Box<Expr<Option<Type>>>>,
|
||||||
step: &Option<Box<Expr<Option<Type>>>>,
|
step: &Option<Box<Expr<Option<Type>>>>,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
list: PointerValue<'ctx>,
|
list: PointerValue<'ctx>,
|
||||||
) -> Result<Option<(IntValue<'ctx>, IntValue<'ctx>, IntValue<'ctx>)>, String> {
|
) -> Result<Option<(IntValue<'ctx>, IntValue<'ctx>, IntValue<'ctx>)>, String> {
|
||||||
|
@ -260,9 +260,9 @@ pub fn handle_slice_indices<'a, 'ctx, G: CodeGenerator>(
|
||||||
|
|
||||||
/// this function allows index out of range, since python
|
/// this function allows index out of range, since python
|
||||||
/// allows index out of range in slice (`a = [1,2,3]; a[1:10] == [2,3]`).
|
/// allows index out of range in slice (`a = [1,2,3]; a[1:10] == [2,3]`).
|
||||||
pub fn handle_slice_index_bound<'a, 'ctx, G: CodeGenerator>(
|
pub fn handle_slice_index_bound<'ctx, G: CodeGenerator>(
|
||||||
i: &Expr<Option<Type>>,
|
i: &Expr<Option<Type>>,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
length: IntValue<'ctx>,
|
length: IntValue<'ctx>,
|
||||||
) -> Result<Option<IntValue<'ctx>>, String> {
|
) -> Result<Option<IntValue<'ctx>>, String> {
|
||||||
|
@ -290,9 +290,9 @@ pub fn handle_slice_index_bound<'a, 'ctx, G: CodeGenerator>(
|
||||||
/// This function handles 'end' **inclusively**.
|
/// This function handles 'end' **inclusively**.
|
||||||
/// Order of tuples assign_idx and value_idx is ('start', 'end', 'step').
|
/// Order of tuples assign_idx and value_idx is ('start', 'end', 'step').
|
||||||
/// Negative index should be handled before entering this function
|
/// Negative index should be handled before entering this function
|
||||||
pub fn list_slice_assignment<'ctx, 'a>(
|
pub fn list_slice_assignment<'ctx>(
|
||||||
generator: &mut dyn CodeGenerator,
|
generator: &mut dyn CodeGenerator,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
ty: BasicTypeEnum<'ctx>,
|
ty: BasicTypeEnum<'ctx>,
|
||||||
dest_arr: PointerValue<'ctx>,
|
dest_arr: PointerValue<'ctx>,
|
||||||
dest_idx: (IntValue<'ctx>, IntValue<'ctx>, IntValue<'ctx>),
|
dest_idx: (IntValue<'ctx>, IntValue<'ctx>, IntValue<'ctx>),
|
||||||
|
@ -450,9 +450,9 @@ pub fn list_slice_assignment<'ctx, 'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a call to `isinf` in IR. Returns an `i1` representing the result.
|
/// Generates a call to `isinf` in IR. Returns an `i1` representing the result.
|
||||||
pub fn call_isinf<'ctx, 'a>(
|
pub fn call_isinf<'ctx>(
|
||||||
generator: &mut dyn CodeGenerator,
|
generator: &mut dyn CodeGenerator,
|
||||||
ctx: &CodeGenContext<'ctx, 'a>,
|
ctx: &CodeGenContext<'ctx, '_>,
|
||||||
v: FloatValue<'ctx>,
|
v: FloatValue<'ctx>,
|
||||||
) -> IntValue<'ctx> {
|
) -> IntValue<'ctx> {
|
||||||
let intrinsic_fn = ctx.module.get_function("__nac3_isinf").unwrap_or_else(|| {
|
let intrinsic_fn = ctx.module.get_function("__nac3_isinf").unwrap_or_else(|| {
|
||||||
|
@ -470,9 +470,9 @@ pub fn call_isinf<'ctx, 'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a call to `isnan` in IR. Returns an `i1` representing the result.
|
/// Generates a call to `isnan` in IR. Returns an `i1` representing the result.
|
||||||
pub fn call_isnan<'ctx, 'a>(
|
pub fn call_isnan<'ctx>(
|
||||||
generator: &mut dyn CodeGenerator,
|
generator: &mut dyn CodeGenerator,
|
||||||
ctx: &CodeGenContext<'ctx, 'a>,
|
ctx: &CodeGenContext<'ctx, '_>,
|
||||||
v: FloatValue<'ctx>,
|
v: FloatValue<'ctx>,
|
||||||
) -> IntValue<'ctx> {
|
) -> IntValue<'ctx> {
|
||||||
let intrinsic_fn = ctx.module.get_function("__nac3_isnan").unwrap_or_else(|| {
|
let intrinsic_fn = ctx.module.get_function("__nac3_isnan").unwrap_or_else(|| {
|
||||||
|
@ -490,8 +490,8 @@ pub fn call_isnan<'ctx, 'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a call to `gamma` in IR. Returns an `f64` representing the result.
|
/// Generates a call to `gamma` in IR. Returns an `f64` representing the result.
|
||||||
pub fn call_gamma<'ctx, 'a>(
|
pub fn call_gamma<'ctx>(
|
||||||
ctx: &CodeGenContext<'ctx, 'a>,
|
ctx: &CodeGenContext<'ctx, '_>,
|
||||||
v: FloatValue<'ctx>,
|
v: FloatValue<'ctx>,
|
||||||
) -> FloatValue<'ctx> {
|
) -> FloatValue<'ctx> {
|
||||||
let llvm_f64 = ctx.ctx.f64_type();
|
let llvm_f64 = ctx.ctx.f64_type();
|
||||||
|
@ -509,8 +509,8 @@ pub fn call_gamma<'ctx, 'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a call to `gammaln` in IR. Returns an `f64` representing the result.
|
/// Generates a call to `gammaln` in IR. Returns an `f64` representing the result.
|
||||||
pub fn call_gammaln<'ctx, 'a>(
|
pub fn call_gammaln<'ctx>(
|
||||||
ctx: &CodeGenContext<'ctx, 'a>,
|
ctx: &CodeGenContext<'ctx, '_>,
|
||||||
v: FloatValue<'ctx>,
|
v: FloatValue<'ctx>,
|
||||||
) -> FloatValue<'ctx> {
|
) -> FloatValue<'ctx> {
|
||||||
let llvm_f64 = ctx.ctx.f64_type();
|
let llvm_f64 = ctx.ctx.f64_type();
|
||||||
|
@ -528,8 +528,8 @@ pub fn call_gammaln<'ctx, 'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a call to `j0` in IR. Returns an `f64` representing the result.
|
/// Generates a call to `j0` in IR. Returns an `f64` representing the result.
|
||||||
pub fn call_j0<'ctx, 'a>(
|
pub fn call_j0<'ctx>(
|
||||||
ctx: &CodeGenContext<'ctx, 'a>,
|
ctx: &CodeGenContext<'ctx, '_>,
|
||||||
v: FloatValue<'ctx>,
|
v: FloatValue<'ctx>,
|
||||||
) -> FloatValue<'ctx> {
|
) -> FloatValue<'ctx> {
|
||||||
let llvm_f64 = ctx.ctx.f64_type();
|
let llvm_f64 = ctx.ctx.f64_type();
|
||||||
|
|
|
@ -112,7 +112,7 @@ impl CodeGenTargetMachineOptions {
|
||||||
) -> Option<TargetMachine> {
|
) -> Option<TargetMachine> {
|
||||||
let triple = TargetTriple::create(self.triple.as_str());
|
let triple = TargetTriple::create(self.triple.as_str());
|
||||||
let target = Target::from_triple(&triple)
|
let target = Target::from_triple(&triple)
|
||||||
.expect(format!("could not create target from target triple {}", self.triple).as_str());
|
.unwrap_or_else(|_| panic!("could not create target from target triple {}", self.triple));
|
||||||
|
|
||||||
target.create_target_machine(
|
target.create_target_machine(
|
||||||
&triple,
|
&triple,
|
||||||
|
@ -178,7 +178,7 @@ impl WithCall {
|
||||||
WithCall { fp }
|
WithCall { fp }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run<'ctx>(&self, m: &Module<'ctx>) {
|
pub fn run(&self, m: &Module) {
|
||||||
(self.fp)(m)
|
(self.fp)(m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -327,9 +327,11 @@ impl WorkerRegistry {
|
||||||
}
|
}
|
||||||
|
|
||||||
let pass_options = PassBuilderOptions::create();
|
let pass_options = PassBuilderOptions::create();
|
||||||
let target_machine = self.llvm_options.target.create_target_machine(
|
let target_machine = self
|
||||||
self.llvm_options.opt_level
|
.llvm_options
|
||||||
).expect(format!("could not create target machine from properties {:?}", self.llvm_options.target).as_str());
|
.target
|
||||||
|
.create_target_machine(self.llvm_options.opt_level)
|
||||||
|
.unwrap_or_else(|| panic!("could not create target machine from properties {:?}", self.llvm_options.target));
|
||||||
let passes = format!("default<O{}>", self.llvm_options.opt_level as u32);
|
let passes = format!("default<O{}>", self.llvm_options.opt_level as u32);
|
||||||
let result = module.run_passes(passes.as_str(), &target_machine, pass_options);
|
let result = module.run_passes(passes.as_str(), &target_machine, pass_options);
|
||||||
if let Err(err) = result {
|
if let Err(err) = result {
|
||||||
|
@ -500,17 +502,17 @@ fn get_llvm_abi_type<'ctx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn need_sret<'ctx>(ctx: &'ctx Context, ty: BasicTypeEnum<'ctx>) -> bool {
|
fn need_sret(ty: BasicTypeEnum) -> bool {
|
||||||
fn need_sret_impl<'ctx>(ctx: &'ctx Context, ty: BasicTypeEnum<'ctx>, maybe_large: bool) -> bool {
|
fn need_sret_impl(ty: BasicTypeEnum, maybe_large: bool) -> bool {
|
||||||
match ty {
|
match ty {
|
||||||
BasicTypeEnum::IntType(_) | BasicTypeEnum::PointerType(_) => false,
|
BasicTypeEnum::IntType(_) | BasicTypeEnum::PointerType(_) => false,
|
||||||
BasicTypeEnum::FloatType(_) if maybe_large => false,
|
BasicTypeEnum::FloatType(_) if maybe_large => false,
|
||||||
BasicTypeEnum::StructType(ty) if maybe_large && ty.count_fields() <= 2 =>
|
BasicTypeEnum::StructType(ty) if maybe_large && ty.count_fields() <= 2 =>
|
||||||
ty.get_field_types().iter().any(|ty| need_sret_impl(ctx, *ty, false)),
|
ty.get_field_types().iter().any(|ty| need_sret_impl(*ty, false)),
|
||||||
_ => true,
|
_ => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
need_sret_impl(ctx, ty, true)
|
need_sret_impl(ty, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementation for generating LLVM IR for a function.
|
/// Implementation for generating LLVM IR for a function.
|
||||||
|
@ -631,7 +633,7 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
|
||||||
Some(get_llvm_abi_type(context, &module, generator, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, &primitives, ret))
|
Some(get_llvm_abi_type(context, &module, generator, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, &primitives, ret))
|
||||||
};
|
};
|
||||||
|
|
||||||
let has_sret = ret_type.map_or(false, |ty| need_sret(context, ty));
|
let has_sret = ret_type.map_or(false, |ty| need_sret(ty));
|
||||||
let mut params = args
|
let mut params = args
|
||||||
.iter()
|
.iter()
|
||||||
.map(|arg| {
|
.map(|arg| {
|
||||||
|
@ -704,7 +706,7 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
|
||||||
let param_val = param.into_int_value();
|
let param_val = param.into_int_value();
|
||||||
|
|
||||||
if expected_ty.get_bit_width() == 8 && param_val.get_type().get_bit_width() == 1 {
|
if expected_ty.get_bit_width() == 8 && param_val.get_type().get_bit_width() == 1 {
|
||||||
bool_to_i8(&builder, &context, param_val)
|
bool_to_i8(&builder, context, param_val)
|
||||||
} else {
|
} else {
|
||||||
param_val
|
param_val
|
||||||
}.into()
|
}.into()
|
||||||
|
@ -914,8 +916,8 @@ fn bool_to_i8<'ctx>(
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Returns an `i1` [IntValue] representing the result of whether the `value` is in the range.
|
/// Returns an `i1` [IntValue] representing the result of whether the `value` is in the range.
|
||||||
fn gen_in_range_check<'ctx, 'a>(
|
fn gen_in_range_check<'ctx>(
|
||||||
ctx: &CodeGenContext<'ctx, 'a>,
|
ctx: &CodeGenContext<'ctx, '_>,
|
||||||
value: IntValue<'ctx>,
|
value: IntValue<'ctx>,
|
||||||
stop: IntValue<'ctx>,
|
stop: IntValue<'ctx>,
|
||||||
step: IntValue<'ctx>,
|
step: IntValue<'ctx>,
|
||||||
|
|
|
@ -25,8 +25,8 @@ use nac3parser::ast::{
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
/// See [CodeGenerator::gen_var_alloc].
|
/// See [CodeGenerator::gen_var_alloc].
|
||||||
pub fn gen_var<'ctx, 'a>(
|
pub fn gen_var<'ctx>(
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
ty: BasicTypeEnum<'ctx>,
|
ty: BasicTypeEnum<'ctx>,
|
||||||
name: Option<&str>,
|
name: Option<&str>,
|
||||||
) -> Result<PointerValue<'ctx>, String> {
|
) -> Result<PointerValue<'ctx>, String> {
|
||||||
|
@ -55,9 +55,9 @@ pub fn gen_var<'ctx, 'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [CodeGenerator::gen_store_target].
|
/// See [CodeGenerator::gen_store_target].
|
||||||
pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
|
pub fn gen_store_target<'ctx, G: CodeGenerator>(
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
pattern: &Expr<Option<Type>>,
|
pattern: &Expr<Option<Type>>,
|
||||||
name: Option<&str>,
|
name: Option<&str>,
|
||||||
) -> Result<Option<PointerValue<'ctx>>, String> {
|
) -> Result<Option<PointerValue<'ctx>>, String> {
|
||||||
|
@ -165,9 +165,9 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [CodeGenerator::gen_assign].
|
/// See [CodeGenerator::gen_assign].
|
||||||
pub fn gen_assign<'ctx, 'a, G: CodeGenerator>(
|
pub fn gen_assign<'ctx, G: CodeGenerator>(
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
target: &Expr<Option<Type>>,
|
target: &Expr<Option<Type>>,
|
||||||
value: ValueEnum<'ctx>,
|
value: ValueEnum<'ctx>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
|
@ -219,7 +219,7 @@ pub fn gen_assign<'ctx, 'a, G: CodeGenerator>(
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let name = if let ExprKind::Name { id, .. } = &target.node {
|
let name = if let ExprKind::Name { id, .. } = &target.node {
|
||||||
format!("{}.addr", id.to_string())
|
format!("{}.addr", id)
|
||||||
} else {
|
} else {
|
||||||
String::from("target.addr")
|
String::from("target.addr")
|
||||||
};
|
};
|
||||||
|
@ -242,9 +242,9 @@ pub fn gen_assign<'ctx, 'a, G: CodeGenerator>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [CodeGenerator::gen_for].
|
/// See [CodeGenerator::gen_for].
|
||||||
pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
pub fn gen_for<G: CodeGenerator>(
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'_, '_>,
|
||||||
stmt: &Stmt<Option<Type>>,
|
stmt: &Stmt<Option<Type>>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
if let StmtKind::For { iter, target, body, orelse, .. } = &stmt.node {
|
if let StmtKind::For { iter, target, body, orelse, .. } = &stmt.node {
|
||||||
|
@ -403,9 +403,9 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [CodeGenerator::gen_while].
|
/// See [CodeGenerator::gen_while].
|
||||||
pub fn gen_while<'ctx, 'a, G: CodeGenerator>(
|
pub fn gen_while<G: CodeGenerator>(
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'_, '_>,
|
||||||
stmt: &Stmt<Option<Type>>,
|
stmt: &Stmt<Option<Type>>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
if let StmtKind::While { test, body, orelse, .. } = &stmt.node {
|
if let StmtKind::While { test, body, orelse, .. } = &stmt.node {
|
||||||
|
@ -472,9 +472,9 @@ pub fn gen_while<'ctx, 'a, G: CodeGenerator>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [CodeGenerator::gen_if].
|
/// See [CodeGenerator::gen_if].
|
||||||
pub fn gen_if<'ctx, 'a, G: CodeGenerator>(
|
pub fn gen_if<G: CodeGenerator>(
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'_, '_>,
|
||||||
stmt: &Stmt<Option<Type>>,
|
stmt: &Stmt<Option<Type>>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
if let StmtKind::If { test, body, orelse, .. } = &stmt.node {
|
if let StmtKind::If { test, body, orelse, .. } = &stmt.node {
|
||||||
|
@ -541,8 +541,8 @@ pub fn gen_if<'ctx, 'a, G: CodeGenerator>(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn final_proxy<'ctx, 'a>(
|
pub fn final_proxy<'ctx>(
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
target: BasicBlock<'ctx>,
|
target: BasicBlock<'ctx>,
|
||||||
block: BasicBlock<'ctx>,
|
block: BasicBlock<'ctx>,
|
||||||
final_data: &mut (PointerValue, Vec<BasicBlock<'ctx>>, Vec<BasicBlock<'ctx>>),
|
final_data: &mut (PointerValue, Vec<BasicBlock<'ctx>>, Vec<BasicBlock<'ctx>>),
|
||||||
|
@ -560,9 +560,9 @@ pub fn final_proxy<'ctx, 'a>(
|
||||||
|
|
||||||
/// Inserts the declaration of the builtin function with the specified `symbol` name, and returns
|
/// Inserts the declaration of the builtin function with the specified `symbol` name, and returns
|
||||||
/// the function.
|
/// the function.
|
||||||
pub fn get_builtins<'ctx, 'a>(
|
pub fn get_builtins<'ctx>(
|
||||||
generator: &mut dyn CodeGenerator,
|
generator: &mut dyn CodeGenerator,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
symbol: &str,
|
symbol: &str,
|
||||||
) -> FunctionValue<'ctx> {
|
) -> FunctionValue<'ctx> {
|
||||||
ctx.module.get_function(symbol).unwrap_or_else(|| {
|
ctx.module.get_function(symbol).unwrap_or_else(|| {
|
||||||
|
@ -586,8 +586,8 @@ pub fn get_builtins<'ctx, 'a>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exn_constructor<'ctx, 'a>(
|
pub fn exn_constructor<'ctx>(
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
obj: Option<(Type, ValueEnum<'ctx>)>,
|
obj: Option<(Type, ValueEnum<'ctx>)>,
|
||||||
_fun: (&FunSignature, DefinitionId),
|
_fun: (&FunSignature, DefinitionId),
|
||||||
mut args: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
mut args: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
||||||
|
@ -661,9 +661,9 @@ pub fn exn_constructor<'ctx, 'a>(
|
||||||
///
|
///
|
||||||
/// * `exception` - The exception thrown by the `raise` statement.
|
/// * `exception` - The exception thrown by the `raise` statement.
|
||||||
/// * `loc` - The location where the exception is raised from.
|
/// * `loc` - The location where the exception is raised from.
|
||||||
pub fn gen_raise<'ctx, 'a>(
|
pub fn gen_raise<'ctx>(
|
||||||
generator: &mut dyn CodeGenerator,
|
generator: &mut dyn CodeGenerator,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
exception: Option<&BasicValueEnum<'ctx>>,
|
exception: Option<&BasicValueEnum<'ctx>>,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
) {
|
) {
|
||||||
|
@ -1035,9 +1035,9 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [CodeGenerator::gen_with].
|
/// See [CodeGenerator::gen_with].
|
||||||
pub fn gen_with<'ctx, 'a, G: CodeGenerator>(
|
pub fn gen_with<G: CodeGenerator>(
|
||||||
_: &mut G,
|
_: &mut G,
|
||||||
_: &mut CodeGenContext<'ctx, 'a>,
|
_: &mut CodeGenContext<'_, '_>,
|
||||||
stmt: &Stmt<Option<Type>>,
|
stmt: &Stmt<Option<Type>>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
// TODO: Implement with statement after finishing exceptions
|
// TODO: Implement with statement after finishing exceptions
|
||||||
|
@ -1045,9 +1045,9 @@ pub fn gen_with<'ctx, 'a, G: CodeGenerator>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates IR for a `return` statement.
|
/// Generates IR for a `return` statement.
|
||||||
pub fn gen_return<'ctx, 'a, G: CodeGenerator>(
|
pub fn gen_return<G: CodeGenerator>(
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'_, '_>,
|
||||||
value: &Option<Box<Expr<Option<Type>>>>,
|
value: &Option<Box<Expr<Option<Type>>>>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let func = ctx.builder.get_insert_block().and_then(|bb| bb.get_parent()).unwrap();
|
let func = ctx.builder.get_insert_block().and_then(|bb| bb.get_parent()).unwrap();
|
||||||
|
@ -1091,15 +1091,15 @@ pub fn gen_return<'ctx, 'a, G: CodeGenerator>(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let value = value.as_ref().map(|v| v as &dyn BasicValue);
|
let value = value.as_ref().map(|v| v as &dyn BasicValue);
|
||||||
ctx.builder.build_return(value.into());
|
ctx.builder.build_return(value);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [CodeGenerator::gen_stmt].
|
/// See [CodeGenerator::gen_stmt].
|
||||||
pub fn gen_stmt<'ctx, 'a, G: CodeGenerator>(
|
pub fn gen_stmt<G: CodeGenerator>(
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'_, '_>,
|
||||||
stmt: &Stmt<Option<Type>>,
|
stmt: &Stmt<Option<Type>>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
ctx.current_loc = stmt.location;
|
ctx.current_loc = stmt.location;
|
||||||
|
@ -1193,9 +1193,9 @@ pub fn gen_stmt<'ctx, 'a, G: CodeGenerator>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates IR for a block statement contains `stmts`.
|
/// Generates IR for a block statement contains `stmts`.
|
||||||
pub fn gen_block<'ctx, 'a, 'b, G: CodeGenerator, I: Iterator<Item = &'b Stmt<Option<Type>>>>(
|
pub fn gen_block<'a, G: CodeGenerator, I: Iterator<Item = &'a Stmt<Option<Type>>>>(
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'_, '_>,
|
||||||
stmts: I,
|
stmts: I,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
for stmt in stmts {
|
for stmt in stmts {
|
||||||
|
|
|
@ -70,19 +70,19 @@ impl SymbolValue {
|
||||||
Constant::Int(i) => {
|
Constant::Int(i) => {
|
||||||
if unifier.unioned(expected_ty, primitives.int32) {
|
if unifier.unioned(expected_ty, primitives.int32) {
|
||||||
i32::try_from(*i)
|
i32::try_from(*i)
|
||||||
.map(|val| SymbolValue::I32(val))
|
.map(SymbolValue::I32)
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
} else if unifier.unioned(expected_ty, primitives.int64) {
|
} else if unifier.unioned(expected_ty, primitives.int64) {
|
||||||
i64::try_from(*i)
|
i64::try_from(*i)
|
||||||
.map(|val| SymbolValue::I64(val))
|
.map(SymbolValue::I64)
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
} else if unifier.unioned(expected_ty, primitives.uint32) {
|
} else if unifier.unioned(expected_ty, primitives.uint32) {
|
||||||
u32::try_from(*i)
|
u32::try_from(*i)
|
||||||
.map(|val| SymbolValue::U32(val))
|
.map(SymbolValue::U32)
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
} else if unifier.unioned(expected_ty, primitives.uint64) {
|
} else if unifier.unioned(expected_ty, primitives.uint64) {
|
||||||
u64::try_from(*i)
|
u64::try_from(*i)
|
||||||
.map(|val| SymbolValue::U64(val))
|
.map(SymbolValue::U64)
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
} else {
|
} else {
|
||||||
Err(format!("Expected {}, but got int", unifier.stringify(expected_ty)))
|
Err(format!("Expected {}, but got int", unifier.stringify(expected_ty)))
|
||||||
|
@ -96,7 +96,8 @@ impl SymbolValue {
|
||||||
|
|
||||||
assert_eq!(ty.len(), t.len());
|
assert_eq!(ty.len(), t.len());
|
||||||
|
|
||||||
let elems = t.into_iter()
|
let elems = t
|
||||||
|
.iter()
|
||||||
.zip(ty)
|
.zip(ty)
|
||||||
.map(|(constant, ty)| Self::from_constant(constant, *ty, primitives, unifier))
|
.map(|(constant, ty)| Self::from_constant(constant, *ty, primitives, unifier))
|
||||||
.collect::<Result<Vec<SymbolValue>, _>>()?;
|
.collect::<Result<Vec<SymbolValue>, _>>()?;
|
||||||
|
@ -204,25 +205,25 @@ pub trait StaticValue {
|
||||||
/// Returns a unique identifier for this value.
|
/// Returns a unique identifier for this value.
|
||||||
fn get_unique_identifier(&self) -> u64;
|
fn get_unique_identifier(&self) -> u64;
|
||||||
|
|
||||||
fn get_const_obj<'ctx, 'a>(
|
fn get_const_obj<'ctx>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
generator: &mut dyn CodeGenerator,
|
generator: &mut dyn CodeGenerator,
|
||||||
) -> BasicValueEnum<'ctx>;
|
) -> BasicValueEnum<'ctx>;
|
||||||
|
|
||||||
/// Converts this value to a LLVM [BasicValueEnum].
|
/// Converts this value to a LLVM [BasicValueEnum].
|
||||||
fn to_basic_value_enum<'ctx, 'a>(
|
fn to_basic_value_enum<'ctx>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
generator: &mut dyn CodeGenerator,
|
generator: &mut dyn CodeGenerator,
|
||||||
expected_ty: Type,
|
expected_ty: Type,
|
||||||
) -> Result<BasicValueEnum<'ctx>, String>;
|
) -> Result<BasicValueEnum<'ctx>, String>;
|
||||||
|
|
||||||
/// Returns a field within this value.
|
/// Returns a field within this value.
|
||||||
fn get_field<'ctx, 'a>(
|
fn get_field<'ctx>(
|
||||||
&self,
|
&self,
|
||||||
name: StrRef,
|
name: StrRef,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
) -> Option<ValueEnum<'ctx>>;
|
) -> Option<ValueEnum<'ctx>>;
|
||||||
|
|
||||||
/// Returns a single element of this tuple.
|
/// Returns a single element of this tuple.
|
||||||
|
@ -292,10 +293,10 @@ pub trait SymbolResolver {
|
||||||
// get the top-level definition of identifiers
|
// get the top-level definition of identifiers
|
||||||
fn get_identifier_def(&self, str: StrRef) -> Result<DefinitionId, String>;
|
fn get_identifier_def(&self, str: StrRef) -> Result<DefinitionId, String>;
|
||||||
|
|
||||||
fn get_symbol_value<'ctx, 'a>(
|
fn get_symbol_value<'ctx>(
|
||||||
&self,
|
&self,
|
||||||
str: StrRef,
|
str: StrRef,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
) -> Option<ValueEnum<'ctx>>;
|
) -> Option<ValueEnum<'ctx>>;
|
||||||
|
|
||||||
fn get_default_param_value(&self, expr: &Expr) -> Option<SymbolValue>;
|
fn get_default_param_value(&self, expr: &Expr) -> Option<SymbolValue>;
|
||||||
|
|
|
@ -117,7 +117,7 @@ fn create_fn_by_codegen(
|
||||||
ty: p.0,
|
ty: p.0,
|
||||||
default_value: None,
|
default_value: None,
|
||||||
}).collect(),
|
}).collect(),
|
||||||
ret: ret_ty.clone(),
|
ret: ret_ty,
|
||||||
vars: var_map.clone(),
|
vars: var_map.clone(),
|
||||||
})),
|
})),
|
||||||
var_id: Default::default(),
|
var_id: Default::default(),
|
||||||
|
@ -163,14 +163,14 @@ fn create_fn_by_intrinsic(
|
||||||
let args_val = args_ty.iter().zip_eq(args.iter())
|
let args_val = args_ty.iter().zip_eq(args.iter())
|
||||||
.map(|(ty, arg)| {
|
.map(|(ty, arg)| {
|
||||||
arg.1.clone()
|
arg.1.clone()
|
||||||
.to_basic_value_enum(ctx, generator, ty.clone())
|
.to_basic_value_enum(ctx, generator, *ty)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
})
|
})
|
||||||
.map_into::<BasicMetadataValueEnum>()
|
.map_into::<BasicMetadataValueEnum>()
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
|
||||||
let intrinsic_fn = ctx.module.get_function(intrinsic_fn).unwrap_or_else(|| {
|
let intrinsic_fn = ctx.module.get_function(intrinsic_fn).unwrap_or_else(|| {
|
||||||
let ret_llvm_ty = ctx.get_llvm_abi_type(generator, ret_ty.clone());
|
let ret_llvm_ty = ctx.get_llvm_abi_type(generator, ret_ty);
|
||||||
let param_llvm_ty = param_tys.iter()
|
let param_llvm_ty = param_tys.iter()
|
||||||
.map(|p| ctx.get_llvm_abi_type(generator, *p))
|
.map(|p| ctx.get_llvm_abi_type(generator, *p))
|
||||||
.map_into::<BasicMetadataTypeEnum>()
|
.map_into::<BasicMetadataTypeEnum>()
|
||||||
|
@ -229,14 +229,14 @@ fn create_fn_by_extern(
|
||||||
let args_val = args_ty.iter().zip_eq(args.iter())
|
let args_val = args_ty.iter().zip_eq(args.iter())
|
||||||
.map(|(ty, arg)| {
|
.map(|(ty, arg)| {
|
||||||
arg.1.clone()
|
arg.1.clone()
|
||||||
.to_basic_value_enum(ctx, generator, ty.clone())
|
.to_basic_value_enum(ctx, generator, *ty)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
})
|
})
|
||||||
.map_into::<BasicMetadataValueEnum>()
|
.map_into::<BasicMetadataValueEnum>()
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
|
||||||
let intrinsic_fn = ctx.module.get_function(extern_fn).unwrap_or_else(|| {
|
let intrinsic_fn = ctx.module.get_function(extern_fn).unwrap_or_else(|| {
|
||||||
let ret_llvm_ty = ctx.get_llvm_abi_type(generator, ret_ty.clone());
|
let ret_llvm_ty = ctx.get_llvm_abi_type(generator, ret_ty);
|
||||||
let param_llvm_ty = param_tys.iter()
|
let param_llvm_ty = param_tys.iter()
|
||||||
.map(|p| ctx.get_llvm_abi_type(generator, *p))
|
.map(|p| ctx.get_llvm_abi_type(generator, *p))
|
||||||
.map_into::<BasicMetadataTypeEnum>()
|
.map_into::<BasicMetadataTypeEnum>()
|
||||||
|
@ -684,7 +684,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
"conv"
|
"conv"
|
||||||
);
|
);
|
||||||
|
|
||||||
val.into()
|
val
|
||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
@ -760,7 +760,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
"conv"
|
"conv"
|
||||||
);
|
);
|
||||||
|
|
||||||
val.into()
|
val
|
||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
@ -905,7 +905,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
.try_as_basic_value()
|
.try_as_basic_value()
|
||||||
.left()
|
.left()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Ok(Some(val.into()))
|
Ok(Some(val))
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
Arc::new(RwLock::new(TopLevelDef::Function {
|
Arc::new(RwLock::new(TopLevelDef::Function {
|
||||||
|
@ -1174,7 +1174,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
.try_as_basic_value()
|
.try_as_basic_value()
|
||||||
.left()
|
.left()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Ok(Some(val.into()))
|
Ok(Some(val))
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
create_fn_by_codegen(
|
create_fn_by_codegen(
|
||||||
|
@ -1261,7 +1261,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
.try_as_basic_value()
|
.try_as_basic_value()
|
||||||
.left()
|
.left()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Ok(Some(val.into()))
|
Ok(Some(val))
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
Arc::new(RwLock::new({
|
Arc::new(RwLock::new({
|
||||||
|
|
|
@ -755,7 +755,7 @@ impl TopLevelComposer {
|
||||||
// unification of previously assigned typevar
|
// unification of previously assigned typevar
|
||||||
let mut unification_helper = |ty, def| {
|
let mut unification_helper = |ty, def| {
|
||||||
let target_ty =
|
let target_ty =
|
||||||
get_type_from_type_annotation_kinds(&temp_def_list, unifier, primitives, &def, &mut subst_list)?;
|
get_type_from_type_annotation_kinds(&temp_def_list, unifier, &def, &mut subst_list)?;
|
||||||
unifier.unify(ty, target_ty).map_err(|e| e.to_display(unifier).to_string())?;
|
unifier.unify(ty, target_ty).map_err(|e| e.to_display(unifier).to_string())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
@ -918,7 +918,6 @@ impl TopLevelComposer {
|
||||||
let ty = get_type_from_type_annotation_kinds(
|
let ty = get_type_from_type_annotation_kinds(
|
||||||
temp_def_list.as_ref(),
|
temp_def_list.as_ref(),
|
||||||
unifier,
|
unifier,
|
||||||
primitives_store,
|
|
||||||
&type_annotation,
|
&type_annotation,
|
||||||
&mut None
|
&mut None
|
||||||
)?;
|
)?;
|
||||||
|
@ -987,7 +986,6 @@ impl TopLevelComposer {
|
||||||
get_type_from_type_annotation_kinds(
|
get_type_from_type_annotation_kinds(
|
||||||
&temp_def_list,
|
&temp_def_list,
|
||||||
unifier,
|
unifier,
|
||||||
primitives_store,
|
|
||||||
&return_ty_annotation,
|
&return_ty_annotation,
|
||||||
&mut None
|
&mut None
|
||||||
)?
|
)?
|
||||||
|
@ -1545,7 +1543,6 @@ impl TopLevelComposer {
|
||||||
let self_type = get_type_from_type_annotation_kinds(
|
let self_type = get_type_from_type_annotation_kinds(
|
||||||
&def_list,
|
&def_list,
|
||||||
unifier,
|
unifier,
|
||||||
primitives_ty,
|
|
||||||
&make_self_type_annotation(type_vars, *object_id),
|
&make_self_type_annotation(type_vars, *object_id),
|
||||||
&mut None
|
&mut None
|
||||||
)?;
|
)?;
|
||||||
|
@ -1714,7 +1711,6 @@ impl TopLevelComposer {
|
||||||
let self_ty = get_type_from_type_annotation_kinds(
|
let self_ty = get_type_from_type_annotation_kinds(
|
||||||
&def_list,
|
&def_list,
|
||||||
unifier,
|
unifier,
|
||||||
primitives_ty,
|
|
||||||
&ty_ann,
|
&ty_ann,
|
||||||
&mut None
|
&mut None
|
||||||
)?;
|
)?;
|
||||||
|
@ -1737,8 +1733,8 @@ impl TopLevelComposer {
|
||||||
let (type_var_subst_comb, no_range_vars) = {
|
let (type_var_subst_comb, no_range_vars) = {
|
||||||
let mut no_ranges: Vec<Type> = Vec::new();
|
let mut no_ranges: Vec<Type> = Vec::new();
|
||||||
let var_combs = vars
|
let var_combs = vars
|
||||||
.iter()
|
.values()
|
||||||
.map(|(_, ty)| {
|
.map(|ty| {
|
||||||
unifier.get_instantiations(*ty).unwrap_or_else(|| {
|
unifier.get_instantiations(*ty).unwrap_or_else(|| {
|
||||||
if let TypeEnum::TVar { name, loc, is_const_generic: false, .. } = &*unifier.get_ty(*ty)
|
if let TypeEnum::TVar { name, loc, is_const_generic: false, .. } = &*unifier.get_ty(*ty)
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,9 +53,9 @@ impl GenCall {
|
||||||
GenCall { fp }
|
GenCall { fp }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run<'ctx, 'a>(
|
pub fn run<'ctx>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
obj: Option<(Type, ValueEnum<'ctx>)>,
|
obj: Option<(Type, ValueEnum<'ctx>)>,
|
||||||
fun: (&FunSignature, DefinitionId),
|
fun: (&FunSignature, DefinitionId),
|
||||||
args: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
args: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
||||||
|
|
|
@ -146,7 +146,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
||||||
slice: &ast::Expr<T>,
|
slice: &ast::Expr<T>,
|
||||||
unifier: &mut Unifier,
|
unifier: &mut Unifier,
|
||||||
mut locked: HashMap<DefinitionId, Vec<Type>>| {
|
mut locked: HashMap<DefinitionId, Vec<Type>>| {
|
||||||
if vec!["virtual".into(), "Generic".into(), "list".into(), "tuple".into(), "Option".into()].contains(id)
|
if ["virtual".into(), "Generic".into(), "list".into(), "tuple".into(), "Option".into()].contains(id)
|
||||||
{
|
{
|
||||||
return Err(format!("keywords cannot be class name (at {})", expr.location));
|
return Err(format!("keywords cannot be class name (at {})", expr.location));
|
||||||
}
|
}
|
||||||
|
@ -329,8 +329,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
||||||
|
|
||||||
if matches!(value, SymbolValue::Str(_) | SymbolValue::Tuple(_) | SymbolValue::OptionSome(_)) {
|
if matches!(value, SymbolValue::Str(_) | SymbolValue::Tuple(_) | SymbolValue::OptionSome(_)) {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"expression {} is not allowed for constant type annotation (at {})",
|
"expression {value} is not allowed for constant type annotation (at {})",
|
||||||
value.to_string(),
|
|
||||||
expr.location
|
expr.location
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -351,7 +350,6 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
||||||
pub fn get_type_from_type_annotation_kinds(
|
pub fn get_type_from_type_annotation_kinds(
|
||||||
top_level_defs: &[Arc<RwLock<TopLevelDef>>],
|
top_level_defs: &[Arc<RwLock<TopLevelDef>>],
|
||||||
unifier: &mut Unifier,
|
unifier: &mut Unifier,
|
||||||
primitives: &PrimitiveStore,
|
|
||||||
ann: &TypeAnnotation,
|
ann: &TypeAnnotation,
|
||||||
subst_list: &mut Option<Vec<Type>>
|
subst_list: &mut Option<Vec<Type>>
|
||||||
) -> Result<Type, String> {
|
) -> Result<Type, String> {
|
||||||
|
@ -377,7 +375,6 @@ pub fn get_type_from_type_annotation_kinds(
|
||||||
get_type_from_type_annotation_kinds(
|
get_type_from_type_annotation_kinds(
|
||||||
top_level_defs,
|
top_level_defs,
|
||||||
unifier,
|
unifier,
|
||||||
primitives,
|
|
||||||
x,
|
x,
|
||||||
subst_list
|
subst_list
|
||||||
)
|
)
|
||||||
|
@ -466,7 +463,9 @@ pub fn get_type_from_type_annotation_kinds(
|
||||||
params: subst,
|
params: subst,
|
||||||
});
|
});
|
||||||
if need_subst {
|
if need_subst {
|
||||||
subst_list.as_mut().map(|wl| wl.push(ty));
|
if let Some(wl) = subst_list.as_mut() {
|
||||||
|
wl.push(ty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(ty)
|
Ok(ty)
|
||||||
}
|
}
|
||||||
|
@ -487,7 +486,6 @@ pub fn get_type_from_type_annotation_kinds(
|
||||||
let ty = get_type_from_type_annotation_kinds(
|
let ty = get_type_from_type_annotation_kinds(
|
||||||
top_level_defs,
|
top_level_defs,
|
||||||
unifier,
|
unifier,
|
||||||
primitives,
|
|
||||||
ty.as_ref(),
|
ty.as_ref(),
|
||||||
subst_list
|
subst_list
|
||||||
)?;
|
)?;
|
||||||
|
@ -497,7 +495,6 @@ pub fn get_type_from_type_annotation_kinds(
|
||||||
let ty = get_type_from_type_annotation_kinds(
|
let ty = get_type_from_type_annotation_kinds(
|
||||||
top_level_defs,
|
top_level_defs,
|
||||||
unifier,
|
unifier,
|
||||||
primitives,
|
|
||||||
ty.as_ref(),
|
ty.as_ref(),
|
||||||
subst_list
|
subst_list
|
||||||
)?;
|
)?;
|
||||||
|
@ -507,7 +504,7 @@ pub fn get_type_from_type_annotation_kinds(
|
||||||
let tys = tys
|
let tys = tys
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| {
|
.map(|x| {
|
||||||
get_type_from_type_annotation_kinds(top_level_defs, unifier, primitives, x, subst_list)
|
get_type_from_type_annotation_kinds(top_level_defs, unifier, x, subst_list)
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
Ok(unifier.add_ty(TypeEnum::TTuple { ty: tys }))
|
Ok(unifier.add_ty(TypeEnum::TTuple { ty: tys }))
|
||||||
|
|
|
@ -394,8 +394,7 @@ impl Unifier {
|
||||||
Some(
|
Some(
|
||||||
range
|
range
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ty| self.get_instantiations(*ty).unwrap_or_else(|| vec![*ty]))
|
.flat_map(|ty| self.get_instantiations(*ty).unwrap_or_else(|| vec![*ty]))
|
||||||
.flatten()
|
|
||||||
.collect_vec(),
|
.collect_vec(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -492,11 +491,11 @@ impl Unifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
let Call { posargs, kwargs, ret, fun, loc } = call;
|
let Call { posargs, kwargs, ret, fun, loc } = call;
|
||||||
let instantiated = self.instantiate_fun(b, &*signature);
|
let instantiated = self.instantiate_fun(b, signature);
|
||||||
let r = self.get_ty(instantiated);
|
let r = self.get_ty(instantiated);
|
||||||
let r = r.as_ref();
|
let r = r.as_ref();
|
||||||
let signature;
|
let signature;
|
||||||
if let TypeEnum::TFunc(s) = &*r {
|
if let TypeEnum::TFunc(s) = r {
|
||||||
signature = s;
|
signature = s;
|
||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
|
@ -1197,7 +1196,7 @@ impl Unifier {
|
||||||
}
|
}
|
||||||
if new_params.is_some() || new_ret.is_some() || matches!(new_args, Cow::Owned(..)) {
|
if new_params.is_some() || new_ret.is_some() || matches!(new_args, Cow::Owned(..)) {
|
||||||
let params = new_params.unwrap_or_else(|| params.clone());
|
let params = new_params.unwrap_or_else(|| params.clone());
|
||||||
let ret = new_ret.unwrap_or_else(|| *ret);
|
let ret = new_ret.unwrap_or(*ret);
|
||||||
let args = new_args.into_owned();
|
let args = new_args.into_owned();
|
||||||
Some(self.add_ty(TypeEnum::TFunc(FunSignature { args, ret, vars: params })))
|
Some(self.add_ty(TypeEnum::TFunc(FunSignature { args, ret, vars: params })))
|
||||||
} else {
|
} else {
|
||||||
|
@ -1313,7 +1312,7 @@ impl Unifier {
|
||||||
.try_collect()?;
|
.try_collect()?;
|
||||||
if ty.iter().any(Option::is_some) {
|
if ty.iter().any(Option::is_some) {
|
||||||
Ok(Some(self.add_ty(TTuple {
|
Ok(Some(self.add_ty(TTuple {
|
||||||
ty: zip(ty.into_iter(), ty1.iter()).map(|(a, b)| a.unwrap_or(*b)).collect(),
|
ty: zip(ty, ty1.iter()).map(|(a, b)| a.unwrap_or(*b)).collect(),
|
||||||
})))
|
})))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
|
|
@ -41,9 +41,9 @@ impl<'a> DwarfReader<'a> {
|
||||||
/// offsets previously applied to the other instance.
|
/// offsets previously applied to the other instance.
|
||||||
pub fn from_reader(other: &DwarfReader<'a>, reset_offset: bool) -> DwarfReader<'a> {
|
pub fn from_reader(other: &DwarfReader<'a>, reset_offset: bool) -> DwarfReader<'a> {
|
||||||
if reset_offset {
|
if reset_offset {
|
||||||
DwarfReader::new(&other.base_slice, other.base_virt_addr)
|
DwarfReader::new(other.base_slice, other.base_virt_addr)
|
||||||
} else {
|
} else {
|
||||||
DwarfReader::new(&other.slice, other.virt_addr)
|
DwarfReader::new(other.slice, other.virt_addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +267,7 @@ impl<'a> CFI_Record<'a> {
|
||||||
0xFFFFFFFF => unimplemented!(),
|
0xFFFFFFFF => unimplemented!(),
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
let mut fde_reader = DwarfReader::from_reader(&cie_reader, false);
|
let mut fde_reader = DwarfReader::from_reader(cie_reader, false);
|
||||||
fde_reader.offset(length);
|
fde_reader.offset(length);
|
||||||
fde_reader
|
fde_reader
|
||||||
}
|
}
|
||||||
|
@ -286,7 +286,7 @@ impl<'a> CFI_Record<'a> {
|
||||||
// Skip code/data alignment factors & return address register along the way as well
|
// Skip code/data alignment factors & return address register along the way as well
|
||||||
// We only tackle the case where 'z' and 'R' are part of the augmentation string, otherwise
|
// We only tackle the case where 'z' and 'R' are part of the augmentation string, otherwise
|
||||||
// we cannot get the addresses to make .eh_frame_hdr
|
// we cannot get the addresses to make .eh_frame_hdr
|
||||||
let mut aug_data_reader = DwarfReader::from_reader(&cie_reader, false);
|
let mut aug_data_reader = DwarfReader::from_reader(cie_reader, false);
|
||||||
let mut aug_str_len = 0;
|
let mut aug_str_len = 0;
|
||||||
loop {
|
loop {
|
||||||
if aug_data_reader.read_u8() == b'\0' {
|
if aug_data_reader.read_u8() == b'\0' {
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub const EI_MAG2: usize = 2;
|
||||||
pub const ELFMAG2: u8 = b'L';
|
pub const ELFMAG2: u8 = b'L';
|
||||||
pub const EI_MAG3: usize = 3;
|
pub const EI_MAG3: usize = 3;
|
||||||
pub const ELFMAG3: u8 = b'F';
|
pub const ELFMAG3: u8 = b'F';
|
||||||
pub const ELFMAG: &'static [u8; 5usize] = b"\x7fELF\x00";
|
pub const ELFMAG: &[u8; 5usize] = b"\x7fELF\x00";
|
||||||
pub const SELFMAG: usize = 4;
|
pub const SELFMAG: usize = 4;
|
||||||
pub const EI_CLASS: usize = 4;
|
pub const EI_CLASS: usize = 4;
|
||||||
pub const ELFCLASSNONE: u8 = 0;
|
pub const ELFCLASSNONE: u8 = 0;
|
||||||
|
@ -428,8 +428,8 @@ pub const VER_NDX_ELIMINATE: usize = 65281;
|
||||||
pub const VER_NEED_NONE: usize = 0;
|
pub const VER_NEED_NONE: usize = 0;
|
||||||
pub const VER_NEED_CURRENT: usize = 1;
|
pub const VER_NEED_CURRENT: usize = 1;
|
||||||
pub const VER_NEED_NUM: usize = 2;
|
pub const VER_NEED_NUM: usize = 2;
|
||||||
pub const ELF_NOTE_SOLARIS: &'static [u8; 13usize] = b"SUNW Solaris\x00";
|
pub const ELF_NOTE_SOLARIS: &[u8; 13usize] = b"SUNW Solaris\x00";
|
||||||
pub const ELF_NOTE_GNU: &'static [u8; 4usize] = b"GNU\x00";
|
pub const ELF_NOTE_GNU: &[u8; 4usize] = b"GNU\x00";
|
||||||
pub const ELF_NOTE_PAGESIZE_HINT: usize = 1;
|
pub const ELF_NOTE_PAGESIZE_HINT: usize = 1;
|
||||||
pub const NT_GNU_ABI_TAG: usize = 1;
|
pub const NT_GNU_ABI_TAG: usize = 1;
|
||||||
pub const ELF_NOTE_ABI: usize = 1;
|
pub const ELF_NOTE_ABI: usize = 1;
|
||||||
|
|
|
@ -74,7 +74,7 @@ fn read_unaligned<T: Copy>(data: &[u8], offset: usize) -> Result<T, ()> {
|
||||||
if data.len() < offset + mem::size_of::<T>() {
|
if data.len() < offset + mem::size_of::<T>() {
|
||||||
Err(())
|
Err(())
|
||||||
} else {
|
} else {
|
||||||
let ptr = data.as_ptr().wrapping_offset(offset as isize) as *const T;
|
let ptr = data.as_ptr().wrapping_add(offset) as *const T;
|
||||||
Ok(unsafe { ptr::read_unaligned(ptr) })
|
Ok(unsafe { ptr::read_unaligned(ptr) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ pub fn get_ref_slice<T: Copy>(data: &[u8], offset: usize, len: usize) -> Result<
|
||||||
if data.len() < offset + mem::size_of::<T>() * len {
|
if data.len() < offset + mem::size_of::<T>() * len {
|
||||||
Err(())
|
Err(())
|
||||||
} else {
|
} else {
|
||||||
let ptr = data.as_ptr().wrapping_offset(offset as isize) as *const T;
|
let ptr = data.as_ptr().wrapping_add(offset) as *const T;
|
||||||
Ok(unsafe { slice::from_raw_parts(ptr, len) })
|
Ok(unsafe { slice::from_raw_parts(ptr, len) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ impl<'a> Linker<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_section(&mut self, shdr: &Elf32_Shdr, sh_name_str: &'a str, data: Vec<u8>) -> usize {
|
fn load_section(&mut self, shdr: &Elf32_Shdr, sh_name_str: &'a str, data: Vec<u8>) -> usize {
|
||||||
let mut elf_shdr = shdr.clone();
|
let mut elf_shdr = *shdr;
|
||||||
|
|
||||||
// Maintain alignment requirement specified in sh_addralign
|
// Maintain alignment requirement specified in sh_addralign
|
||||||
let align = shdr.sh_addralign;
|
let align = shdr.sh_addralign;
|
||||||
|
@ -240,7 +240,7 @@ impl<'a> Linker<'a> {
|
||||||
let get_target_section_index = || -> Result<usize, Error> {
|
let get_target_section_index = || -> Result<usize, Error> {
|
||||||
self.section_map
|
self.section_map
|
||||||
.get(&(target_section as usize))
|
.get(&(target_section as usize))
|
||||||
.map(|&index| index)
|
.copied()
|
||||||
.ok_or(Error::Parsing("Cannot find section with matching sh_index"))
|
.ok_or(Error::Parsing("Cannot find section with matching sh_index"))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -314,13 +314,9 @@ impl<'a> Linker<'a> {
|
||||||
|
|
||||||
R_RISCV_PCREL_LO12_I => {
|
R_RISCV_PCREL_LO12_I => {
|
||||||
let expected_offset = sym_option.map_or(0, |sym| sym.st_value);
|
let expected_offset = sym_option.map_or(0, |sym| sym.st_value);
|
||||||
let indirect_reloc = if let Some(reloc) =
|
let indirect_reloc = relocs
|
||||||
relocs.iter().find(|reloc| reloc.offset() == expected_offset)
|
.iter()
|
||||||
{
|
.find(|reloc| reloc.offset() == expected_offset)?;
|
||||||
reloc
|
|
||||||
} else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
Some(RelocInfo {
|
Some(RelocInfo {
|
||||||
defined_val: {
|
defined_val: {
|
||||||
let indirect_sym =
|
let indirect_sym =
|
||||||
|
@ -603,8 +599,8 @@ impl<'a> Linker<'a> {
|
||||||
// Section table for the .elf paired with the section name
|
// Section table for the .elf paired with the section name
|
||||||
// To be formalized incrementally
|
// To be formalized incrementally
|
||||||
// Very hashmap-like structure, but the order matters, so it is a vector
|
// Very hashmap-like structure, but the order matters, so it is a vector
|
||||||
let mut elf_shdrs = Vec::new();
|
let elf_shdrs = vec![
|
||||||
elf_shdrs.push(SectionRecord {
|
SectionRecord {
|
||||||
shdr: Elf32_Shdr {
|
shdr: Elf32_Shdr {
|
||||||
sh_name: 0,
|
sh_name: 0,
|
||||||
sh_type: 0,
|
sh_type: 0,
|
||||||
|
@ -619,7 +615,8 @@ impl<'a> Linker<'a> {
|
||||||
},
|
},
|
||||||
name: "",
|
name: "",
|
||||||
data: vec![0; 0],
|
data: vec![0; 0],
|
||||||
});
|
},
|
||||||
|
];
|
||||||
let elf_sh_data_off = mem::size_of::<Elf32_Ehdr>() + mem::size_of::<Elf32_Phdr>() * 5;
|
let elf_sh_data_off = mem::size_of::<Elf32_Ehdr>() + mem::size_of::<Elf32_Phdr>() * 5;
|
||||||
|
|
||||||
// Image of the linked dynamic library, to be formalized incrementally
|
// Image of the linked dynamic library, to be formalized incrementally
|
||||||
|
@ -659,8 +656,8 @@ impl<'a> Linker<'a> {
|
||||||
linker.load_section(
|
linker.load_section(
|
||||||
&text_shdr,
|
&text_shdr,
|
||||||
".text",
|
".text",
|
||||||
(&data[text_shdr.sh_offset as usize
|
data[text_shdr.sh_offset as usize
|
||||||
..text_shdr.sh_offset as usize + text_shdr.sh_size as usize])
|
..text_shdr.sh_offset as usize + text_shdr.sh_size as usize]
|
||||||
.to_vec(),
|
.to_vec(),
|
||||||
);
|
);
|
||||||
linker.section_map.insert(text_shdr_index, 1);
|
linker.section_map.insert(text_shdr_index, 1);
|
||||||
|
@ -678,8 +675,8 @@ impl<'a> Linker<'a> {
|
||||||
let loaded_index = linker.load_section(
|
let loaded_index = linker.load_section(
|
||||||
&arm_exidx_shdr,
|
&arm_exidx_shdr,
|
||||||
".ARM.exidx",
|
".ARM.exidx",
|
||||||
(&data[arm_exidx_shdr.sh_offset as usize
|
data[arm_exidx_shdr.sh_offset as usize
|
||||||
..arm_exidx_shdr.sh_offset as usize + arm_exidx_shdr.sh_size as usize])
|
..arm_exidx_shdr.sh_offset as usize + arm_exidx_shdr.sh_size as usize]
|
||||||
.to_vec(),
|
.to_vec(),
|
||||||
);
|
);
|
||||||
linker.section_map.insert(arm_exidx_shdr_index, loaded_index);
|
linker.section_map.insert(arm_exidx_shdr_index, loaded_index);
|
||||||
|
@ -698,7 +695,7 @@ impl<'a> Linker<'a> {
|
||||||
let elf_shdrs_index = linker.load_section(
|
let elf_shdrs_index = linker.load_section(
|
||||||
shdr,
|
shdr,
|
||||||
str::from_utf8(section_name).unwrap(),
|
str::from_utf8(section_name).unwrap(),
|
||||||
(&data[shdr.sh_offset as usize..(shdr.sh_offset + shdr.sh_size) as usize]).to_vec(),
|
data[shdr.sh_offset as usize..(shdr.sh_offset + shdr.sh_size) as usize].to_vec(),
|
||||||
);
|
);
|
||||||
linker.section_map.insert(i, elf_shdrs_index);
|
linker.section_map.insert(i, elf_shdrs_index);
|
||||||
}
|
}
|
||||||
|
@ -918,7 +915,7 @@ impl<'a> Linker<'a> {
|
||||||
dynsym_names.push((0, 0));
|
dynsym_names.push((0, 0));
|
||||||
|
|
||||||
for rela_dyn_sym_index in rela_dyn_sym_indices {
|
for rela_dyn_sym_index in rela_dyn_sym_indices {
|
||||||
let mut sym = linker.symtab[rela_dyn_sym_index as usize].clone();
|
let mut sym = linker.symtab[rela_dyn_sym_index as usize];
|
||||||
let sym_name = name_starting_at_slice(strtab, sym.st_name as usize)
|
let sym_name = name_starting_at_slice(strtab, sym.st_name as usize)
|
||||||
.map_err(|_| "cannot read symbol name from the original .strtab")?;
|
.map_err(|_| "cannot read symbol name from the original .strtab")?;
|
||||||
let dynstr_start_index = dynstr.len();
|
let dynstr_start_index = dynstr.len();
|
||||||
|
@ -928,7 +925,7 @@ impl<'a> Linker<'a> {
|
||||||
let elf_shdr_index = linker
|
let elf_shdr_index = linker
|
||||||
.section_map
|
.section_map
|
||||||
.get(&(sym.st_shndx as usize))
|
.get(&(sym.st_shndx as usize))
|
||||||
.map(|&index| index)
|
.copied()
|
||||||
.ok_or(Error::Parsing("Cannot find section with matching sh_index"))?;
|
.ok_or(Error::Parsing("Cannot find section with matching sh_index"))?;
|
||||||
let elf_shdr_offset = linker.elf_shdrs[elf_shdr_index].shdr.sh_offset;
|
let elf_shdr_offset = linker.elf_shdrs[elf_shdr_index].shdr.sh_offset;
|
||||||
sym.st_value += elf_shdr_offset;
|
sym.st_value += elf_shdr_offset;
|
||||||
|
@ -955,7 +952,7 @@ impl<'a> Linker<'a> {
|
||||||
let modinit_shdr_index = linker
|
let modinit_shdr_index = linker
|
||||||
.section_map
|
.section_map
|
||||||
.get(&(modinit_sym.st_shndx as usize))
|
.get(&(modinit_sym.st_shndx as usize))
|
||||||
.map(|&index| index)
|
.copied()
|
||||||
.ok_or(Error::Parsing("Cannot find section with matching sh_index"))?;
|
.ok_or(Error::Parsing("Cannot find section with matching sh_index"))?;
|
||||||
let modinit_shdr = linker.elf_shdrs[modinit_shdr_index].shdr;
|
let modinit_shdr = linker.elf_shdrs[modinit_shdr_index].shdr;
|
||||||
|
|
||||||
|
@ -1013,9 +1010,8 @@ impl<'a> Linker<'a> {
|
||||||
let mut hash_bucket: Vec<u32> = vec![0; dynsym.len()];
|
let mut hash_bucket: Vec<u32> = vec![0; dynsym.len()];
|
||||||
let mut hash_chain: Vec<u32> = vec![0; dynsym.len()];
|
let mut hash_chain: Vec<u32> = vec![0; dynsym.len()];
|
||||||
|
|
||||||
for sym_index in 1..dynsym.len() {
|
for (sym_index, (str_start, str_end)) in dynsym_names.iter().enumerate().take(dynsym.len()).skip(1) {
|
||||||
let (str_start, str_end) = dynsym_names[sym_index];
|
let hash = elf_hash(&dynstr[*str_start..*str_end]);
|
||||||
let hash = elf_hash(&dynstr[str_start..str_end]);
|
|
||||||
let mut hash_index = hash as usize % hash_bucket.len();
|
let mut hash_index = hash as usize % hash_bucket.len();
|
||||||
|
|
||||||
if hash_bucket[hash_index] == 0 {
|
if hash_bucket[hash_index] == 0 {
|
||||||
|
@ -1104,7 +1100,7 @@ impl<'a> Linker<'a> {
|
||||||
let elf_shdrs_index = linker.load_section(
|
let elf_shdrs_index = linker.load_section(
|
||||||
shdr,
|
shdr,
|
||||||
str::from_utf8(section_name).unwrap(),
|
str::from_utf8(section_name).unwrap(),
|
||||||
(&data[shdr.sh_offset as usize..(shdr.sh_offset + shdr.sh_size) as usize])
|
data[shdr.sh_offset as usize..(shdr.sh_offset + shdr.sh_size) as usize]
|
||||||
.to_vec(),
|
.to_vec(),
|
||||||
);
|
);
|
||||||
linker.section_map.insert(i, elf_shdrs_index);
|
linker.section_map.insert(i, elf_shdrs_index);
|
||||||
|
@ -1208,7 +1204,7 @@ impl<'a> Linker<'a> {
|
||||||
let elf_shdrs_index = linker.load_section(
|
let elf_shdrs_index = linker.load_section(
|
||||||
shdr,
|
shdr,
|
||||||
section_name,
|
section_name,
|
||||||
(&data[shdr.sh_offset as usize..(shdr.sh_offset + shdr.sh_size) as usize])
|
data[shdr.sh_offset as usize..(shdr.sh_offset + shdr.sh_size) as usize]
|
||||||
.to_vec(),
|
.to_vec(),
|
||||||
);
|
);
|
||||||
linker.section_map.insert(i, elf_shdrs_index);
|
linker.section_map.insert(i, elf_shdrs_index);
|
||||||
|
@ -1262,7 +1258,7 @@ impl<'a> Linker<'a> {
|
||||||
let bss_elf_index = linker.load_section(
|
let bss_elf_index = linker.load_section(
|
||||||
shdr,
|
shdr,
|
||||||
section_name,
|
section_name,
|
||||||
(&data[shdr.sh_offset as usize..(shdr.sh_offset + shdr.sh_size) as usize])
|
data[shdr.sh_offset as usize..(shdr.sh_offset + shdr.sh_size) as usize]
|
||||||
.to_vec(),
|
.to_vec(),
|
||||||
);
|
);
|
||||||
linker.section_map.insert(bss_section_index, bss_elf_index);
|
linker.section_map.insert(bss_section_index, bss_elf_index);
|
||||||
|
|
|
@ -53,10 +53,10 @@ impl SymbolResolver for Resolver {
|
||||||
self.0.id_to_type.lock().get(&str).cloned().ok_or(format!("cannot get type of {}", str))
|
self.0.id_to_type.lock().get(&str).cloned().ok_or(format!("cannot get type of {}", str))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_symbol_value<'ctx, 'a>(
|
fn get_symbol_value<'ctx>(
|
||||||
&self,
|
&self,
|
||||||
_: StrRef,
|
_: StrRef,
|
||||||
_: &mut CodeGenContext<'ctx, 'a>,
|
_: &mut CodeGenContext<'ctx, '_>,
|
||||||
) -> Option<ValueEnum<'ctx>> {
|
) -> Option<ValueEnum<'ctx>> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@ fn handle_typevar_definition(
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
get_type_from_type_annotation_kinds(
|
get_type_from_type_annotation_kinds(
|
||||||
def_list, unifier, primitives, &ty, &mut None
|
def_list, unifier, &ty, &mut None
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
@ -138,7 +138,7 @@ fn handle_typevar_definition(
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
let constraint = get_type_from_type_annotation_kinds(
|
let constraint = get_type_from_type_annotation_kinds(
|
||||||
def_list, unifier, primitives, &ty, &mut None
|
def_list, unifier, &ty, &mut None
|
||||||
)?;
|
)?;
|
||||||
let loc = func.location;
|
let loc = func.location;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue