Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions compiler/noirc_evaluator/src/ssa/ir/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ impl Display for Ssa {
Value::Global(_) => {
panic!("Value::Global should only be in the function dfg");
}
Value::Function(id) => {
writeln!(f, "{}", id)?;
}
_ => panic!("Expected only numeric constant or instruction"),
};
}
Expand Down
12 changes: 12 additions & 0 deletions compiler/noirc_evaluator/src/ssa/ir/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,18 @@ impl Type {
}
}
}

/// True if this is a function type or if it is a composite type which contains a function.
pub(crate) fn contains_function(&self) -> bool {
match self {
Type::Reference(element_type) => element_type.contains_function(),
Type::Function => true,
Type::Numeric(_) => false,
Type::Array(elements, _) | Type::Slice(elements) => {
elements.iter().any(|elem| elem.contains_function())
}
}
}
}

/// Composite Types are essentially flattened struct or tuple types.
Expand Down
9 changes: 8 additions & 1 deletion compiler/noirc_evaluator/src/ssa/parser/into_ssa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@

/// Computes the order in which blocks should be translated. The order will be according
/// to the block terminators, starting from the entry block. This is needed because a variable
/// in a block might refer to a variable that syntantically happens afterwards, but logically

Check warning on line 203 in compiler/noirc_evaluator/src/ssa/parser/into_ssa.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (syntantically)
/// happens before.
fn compute_blocks_order(
&self,
Expand Down Expand Up @@ -454,7 +454,14 @@
.globals_function
.dfg
.make_constant(constant.value, constant.typ.unwrap_numeric()),
ParsedValue::Variable(identifier) => self.lookup_global(identifier)?,
ParsedValue::Variable(identifier) => {
match self.lookup_global(identifier.clone()) {
Ok(global) => global,
Err(lookup_global_err) => self
.lookup_call_function(identifier)
.map_err(|_| lookup_global_err)?,
}
}
};
elements.push_back(element_id);
}
Expand Down
49 changes: 49 additions & 0 deletions compiler/noirc_evaluator/src/ssa/parser/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@
}

#[test]
fn parses_variable_from_a_syntantically_following_block_but_logically_preceding_block_with_jmp() {

Check warning on line 790 in compiler/noirc_evaluator/src/ssa/parser/tests.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (syntantically)
let src = "
acir(inline) impure fn main f0 {
b0():
Expand All @@ -805,7 +805,7 @@
}

#[test]
fn parses_variable_from_a_syntantically_following_block_but_logically_preceding_block_with_jmpif() {

Check warning on line 808 in compiler/noirc_evaluator/src/ssa/parser/tests.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (syntantically)
let src = "
acir(inline) impure fn main f0 {
b0(v0: u1):
Expand All @@ -823,3 +823,52 @@
";
assert_ssa_roundtrip(src);
}

#[test]
fn function_pointer_in_global_array() {
let src = "
g2 = make_array [f1, f2] : [function; 2]
acir(inline) fn main f0 {
b0(v3: u32, v4: Field):
v6 = call f1() -> Field
v8 = call f2() -> Field
v10 = lt v3, u32 2
constrain v10 == u1 1
v12 = array_get g2, index v3 -> function
v13 = call v12() -> Field
v14 = eq v13, v4
constrain v13 == v4
return
}
acir(inline) fn f1 f1 {
b0():
return Field 1
}
acir(inline) fn f2 f2 {
b0():
return Field 2
}
";
let _ = Ssa::from_str_no_validation(src).unwrap();
}

#[test]
#[should_panic(expected = "Unknown global")]
fn unknown_function_global_function_pointer() {
let src = "
g2 = make_array [f1, f2] : [function; 2]
acir(inline) fn main f0 {
b0(v3: u32, v4: Field):
v6 = call f1() -> Field
v8 = call f2() -> Field
v10 = lt v3, u32 2
constrain v10 == u1 1
v12 = array_get g2, index v3 -> function
v13 = call v12() -> Field
v14 = eq v13, v4
constrain v13 == v4
return
}
";
let _ = Ssa::from_str_no_validation(src).unwrap();
}
Loading
Loading