Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Sync from noir #5286

Merged
merged 3 commits into from
Mar 18, 2024
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
1 change: 1 addition & 0 deletions noir/noir-repo/.github/scripts/noir-wasm-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
set -eu

.github/scripts/wasm-pack-install.sh
yarn workspace @noir-lang/types build
yarn workspace @noir-lang/noir_wasm build
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,29 @@ impl<'block> BrilligBlock<'block> {
self.convert_ssa_array_len(arguments[0], result_variable.address, dfg);
}
}
Value::Intrinsic(Intrinsic::AsSlice) => {
let source_variable = self.convert_ssa_value(arguments[0], dfg);
let result_ids = dfg.instruction_results(instruction_id);
let destination_len_variable = self.variables.define_single_addr_variable(
self.function_context,
self.brillig_context,
result_ids[0],
dfg,
);
let destination_variable = self.variables.define_variable(
self.function_context,
self.brillig_context,
result_ids[1],
dfg,
);
let source_size_as_register =
self.convert_ssa_array_set(source_variable, destination_variable, None);

// we need to explicitly set the destination_len_variable
self.brillig_context
.mov_instruction(destination_len_variable.address, source_size_as_register);
self.brillig_context.deallocate_register(source_size_as_register);
}
Value::Intrinsic(
Intrinsic::SlicePushBack
| Intrinsic::SlicePopBack
Expand Down Expand Up @@ -610,13 +633,12 @@ impl<'block> BrilligBlock<'block> {
dfg,
);
self.validate_array_index(source_variable, index_register);

self.convert_ssa_array_set(
let source_size_as_register = self.convert_ssa_array_set(
source_variable,
destination_variable,
index_register.address,
value_variable,
Some((index_register.address, value_variable)),
);
self.brillig_context.deallocate_register(source_size_as_register);
}
Instruction::RangeCheck { value, max_bit_size, assert_message } => {
let value = self.convert_ssa_single_addr_value(*value, dfg);
Expand Down Expand Up @@ -811,23 +833,25 @@ impl<'block> BrilligBlock<'block> {

/// Array set operation in SSA returns a new array or slice that is a copy of the parameter array or slice
/// With a specific value changed.
///
/// Returns `source_size_as_register`, which is expected to be deallocated with:
/// `self.brillig_context.deallocate_register(source_size_as_register)`
fn convert_ssa_array_set(
&mut self,
source_variable: BrilligVariable,
destination_variable: BrilligVariable,
index_register: MemoryAddress,
value_variable: BrilligVariable,
) {
opt_index_and_value: Option<(MemoryAddress, BrilligVariable)>,
) -> MemoryAddress {
let destination_pointer = match destination_variable {
BrilligVariable::BrilligArray(BrilligArray { pointer, .. }) => pointer,
BrilligVariable::BrilligVector(BrilligVector { pointer, .. }) => pointer,
_ => unreachable!("ICE: array set returns non-array"),
_ => unreachable!("ICE: array_set SSA returns non-array"),
};

let reference_count = match source_variable {
BrilligVariable::BrilligArray(BrilligArray { rc, .. })
| BrilligVariable::BrilligVector(BrilligVector { rc, .. }) => rc,
_ => unreachable!("ICE: array set on non-array"),
_ => unreachable!("ICE: array_set SSA on non-array"),
};

let (source_pointer, source_size_as_register) = match source_variable {
Expand All @@ -841,7 +865,7 @@ impl<'block> BrilligBlock<'block> {
self.brillig_context.mov_instruction(source_size_register, size);
(pointer, source_size_register)
}
_ => unreachable!("ICE: array set on non-array"),
_ => unreachable!("ICE: array_set SSA on non-array"),
};

// Here we want to compare the reference count against 1.
Expand Down Expand Up @@ -884,18 +908,20 @@ impl<'block> BrilligBlock<'block> {
self.brillig_context.mov_instruction(target_size, source_size_as_register);
self.brillig_context.usize_const_instruction(target_rc, 1_usize.into());
}
_ => unreachable!("ICE: array set on non-array"),
_ => unreachable!("ICE: array_set SSA on non-array"),
}

// Then set the value in the newly created array
self.store_variable_in_array(
destination_pointer,
SingleAddrVariable::new_usize(index_register),
value_variable,
);
if let Some((index_register, value_variable)) = opt_index_and_value {
// Then set the value in the newly created array
self.store_variable_in_array(
destination_pointer,
SingleAddrVariable::new_usize(index_register),
value_variable,
);
}

self.brillig_context.deallocate_register(source_size_as_register);
self.brillig_context.deallocate_register(condition);
source_size_as_register
}

pub(crate) fn store_variable_in_array_with_ctx(
Expand Down Expand Up @@ -1351,6 +1377,7 @@ impl<'block> BrilligBlock<'block> {
Value::Param { .. } | Value::Instruction { .. } => {
// All block parameters and instruction results should have already been
// converted to registers so we fetch from the cache.

self.variables.get_allocation(self.function_context, value_id, dfg)
}
Value::NumericConstant { constant, .. } => {
Expand Down
54 changes: 52 additions & 2 deletions noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,13 @@ impl Context {
self.array_set_value(&store_value, result_block_id, &mut var_index)?;

let element_type_sizes = if !can_omit_element_sizes_array(&array_typ) {
Some(self.init_element_type_sizes_array(&array_typ, array_id, None, dfg)?)
let acir_value = self.convert_value(array_id, dfg);
Some(self.init_element_type_sizes_array(
&array_typ,
array_id,
Some(&acir_value),
dfg,
)?)
} else {
None
};
Expand Down Expand Up @@ -1246,7 +1252,8 @@ impl Context {
let read = self.acir_context.read_from_memory(source, &index_var)?;
Ok::<AcirValue, RuntimeError>(AcirValue::Var(read, AcirType::field()))
})?;
self.initialize_array(destination, array_len, Some(AcirValue::Array(init_values.into())))?;
let array: im::Vector<AcirValue> = init_values.into();
self.initialize_array(destination, array_len, Some(AcirValue::Array(array)))?;
Ok(())
}

Expand Down Expand Up @@ -1663,6 +1670,49 @@ impl Context {
};
Ok(vec![AcirValue::Var(self.acir_context.add_constant(len), AcirType::field())])
}
Intrinsic::AsSlice => {
let (slice_contents, slice_typ, block_id) =
self.check_array_is_initialized(arguments[0], dfg)?;
assert!(!slice_typ.is_nested_slice(), "ICE: Nested slice used in ACIR generation");

let result_block_id = self.block_id(&result_ids[1]);
let acir_value = self.convert_value(slice_contents, dfg);

let array_len = if !slice_typ.contains_slice_element() {
slice_typ.flattened_size()
} else {
self.flattened_slice_size(slice_contents, dfg)
};
let slice_length = self.acir_context.add_constant(array_len);
self.copy_dynamic_array(block_id, result_block_id, array_len)?;

let element_type_sizes = if !can_omit_element_sizes_array(&slice_typ) {
Some(self.init_element_type_sizes_array(
&slice_typ,
slice_contents,
Some(&acir_value),
dfg,
)?)
} else {
None
};

let value_types = self.convert_value(slice_contents, dfg).flat_numeric_types();
assert!(
array_len == value_types.len(),
"AsSlice: unexpected length difference: {:?} != {:?}",
array_len,
value_types.len()
);

let result = AcirValue::DynamicArray(AcirDynamicArray {
block_id: result_block_id,
len: value_types.len(),
value_types,
element_type_sizes,
});
Ok(vec![AcirValue::Var(slice_length, AcirType::field()), result])
}
Intrinsic::SlicePushBack => {
// arguments = [slice_length, slice_contents, ...elements_to_push]
let slice_length = self.convert_value(arguments[0], dfg).into_var()?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub(crate) type InstructionId = Id<Instruction>;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub(crate) enum Intrinsic {
ArrayLen,
AsSlice,
AssertConstant,
SlicePushBack,
SlicePushFront,
Expand All @@ -57,6 +58,7 @@ impl std::fmt::Display for Intrinsic {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Intrinsic::ArrayLen => write!(f, "array_len"),
Intrinsic::AsSlice => write!(f, "as_slice"),
Intrinsic::AssertConstant => write!(f, "assert_constant"),
Intrinsic::SlicePushBack => write!(f, "slice_push_back"),
Intrinsic::SlicePushFront => write!(f, "slice_push_front"),
Expand Down Expand Up @@ -89,6 +91,7 @@ impl Intrinsic {
Intrinsic::ToBits(_) | Intrinsic::ToRadix(_) => true,

Intrinsic::ArrayLen
| Intrinsic::AsSlice
| Intrinsic::SlicePushBack
| Intrinsic::SlicePushFront
| Intrinsic::SlicePopBack
Expand All @@ -109,6 +112,7 @@ impl Intrinsic {
pub(crate) fn lookup(name: &str) -> Option<Intrinsic> {
match name {
"array_len" => Some(Intrinsic::ArrayLen),
"as_slice" => Some(Intrinsic::AsSlice),
"assert_constant" => Some(Intrinsic::AssertConstant),
"apply_range_constraint" => Some(Intrinsic::ApplyRangeConstraint),
"slice_push_back" => Some(Intrinsic::SlicePushBack),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ pub(super) fn simplify_call(
SimplifyResult::None
}
}
Intrinsic::AsSlice => {
let slice = dfg.get_array_constant(arguments[0]);
if let Some((slice, element_type)) = slice {
let slice_length = dfg.make_constant(slice.len().into(), Type::length_type());
let new_slice = dfg.make_array(slice, element_type);
SimplifyResult::SimplifiedToMultiple(vec![slice_length, new_slice])
} else {
SimplifyResult::None
}
}
Intrinsic::SlicePushBack => {
let slice = dfg.get_array_constant(arguments[1]);
if let Some((mut slice, element_type)) = slice {
Expand Down
18 changes: 9 additions & 9 deletions noir/noir-repo/docs/docs/noir/standard_library/black_box_fns.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ The ACVM spec defines a set of blackbox functions which backends will be expecte

Here is a list of the current black box functions:

- [SHA256](./cryptographic_primitives/hashes#sha256)
- [Schnorr signature verification](./cryptographic_primitives/schnorr)
- [Blake2s](./cryptographic_primitives/hashes#blake2s)
- [Blake3](./cryptographic_primitives/hashes#blake3)
- [Pedersen Hash](./cryptographic_primitives/hashes#pedersen_hash)
- [Pedersen Commitment](./cryptographic_primitives/hashes#pedersen_commitment)
- [ECDSA signature verification](./cryptographic_primitives/ecdsa_sig_verification)
- [Fixed base scalar multiplication](./cryptographic_primitives/scalar)
- [SHA256](./cryptographic_primitives/hashes.mdx#sha256)
- [Schnorr signature verification](./cryptographic_primitives/schnorr.mdx)
- [Blake2s](./cryptographic_primitives/hashes.mdx#blake2s)
- [Blake3](./cryptographic_primitives/hashes.mdx#blake3)
- [Pedersen Hash](./cryptographic_primitives/hashes.mdx#pedersen_hash)
- [Pedersen Commitment](./cryptographic_primitives/hashes.mdx#pedersen_commitment)
- [ECDSA signature verification](./cryptographic_primitives/ecdsa_sig_verification.mdx)
- [Fixed base scalar multiplication](./cryptographic_primitives/scalar.mdx)
- AND
- XOR
- RANGE
- [Keccak256](./cryptographic_primitives/hashes#keccak256)
- [Keccak256](./cryptographic_primitives/hashes.mdx#keccak256)
- [Recursive proof verification](./recursion)

Most black box functions are included as part of the Noir standard library, however `AND`, `XOR` and `RANGE` are used as part of the Noir language syntax. For instance, using the bitwise operator `&` will invoke the `AND` black box function.
Expand Down
2 changes: 1 addition & 1 deletion noir/noir-repo/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"build": "yarn preprocess && yarn version::stables && docusaurus build",
"version::stables": "ts-node ./scripts/setStable.ts",
"serve": "serve build",
"version": "yarn preprocess && docusaurus docs:version"
"version": "yarn preprocess && docusaurus build && docusaurus docs:version"
},
"dependencies": {
"@docusaurus/core": "^3.0.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ The ACVM spec defines a set of blackbox functions which backends will be expecte

Here is a list of the current black box functions:

- [SHA256](./cryptographic_primitives/hashes#sha256)
- [Schnorr signature verification](./cryptographic_primitives/schnorr)
- [Blake2s](./cryptographic_primitives/hashes#blake2s)
- [Blake3](./cryptographic_primitives/hashes#blake3)
- [Pedersen Hash](./cryptographic_primitives/hashes#pedersen_hash)
- [Pedersen Commitment](./cryptographic_primitives/hashes#pedersen_commitment)
- [ECDSA signature verification](./cryptographic_primitives/ecdsa_sig_verification)
- [Fixed base scalar multiplication](./cryptographic_primitives/scalar)
- [SHA256](./cryptographic_primitives/hashes.mdx#sha256)
- [Schnorr signature verification](./cryptographic_primitives/schnorr.mdx)
- [Blake2s](./cryptographic_primitives/hashes.mdx#blake2s)
- [Blake3](./cryptographic_primitives/hashes.mdx#blake3)
- [Pedersen Hash](./cryptographic_primitives/hashes.mdx#pedersen_hash)
- [Pedersen Commitment](./cryptographic_primitives/hashes.mdx#pedersen_commitment)
- [ECDSA signature verification](./cryptographic_primitives/ecdsa_sig_verification.mdx)
- [Fixed base scalar multiplication](./cryptographic_primitives/scalar.mdx)
- AND
- XOR
- RANGE
- [Keccak256](./cryptographic_primitives/hashes#keccak256)
- [Keccak256](./cryptographic_primitives/hashes.mdx#keccak256)
- [Recursive proof verification](./recursion)

Most black box functions are included as part of the Noir standard library, however `AND`, `XOR` and `RANGE` are used as part of the Noir language syntax. For instance, using the bitwise operator `&` will invoke the `AND` black box function.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ The ACVM spec defines a set of blackbox functions which backends will be expecte

Here is a list of the current black box functions:

- [SHA256](./cryptographic_primitives/hashes#sha256)
- [Schnorr signature verification](./cryptographic_primitives/schnorr)
- [Blake2s](./cryptographic_primitives/hashes#blake2s)
- [Blake3](./cryptographic_primitives/hashes#blake3)
- [Pedersen Hash](./cryptographic_primitives/hashes#pedersen_hash)
- [Pedersen Commitment](./cryptographic_primitives/hashes#pedersen_commitment)
- [ECDSA signature verification](./cryptographic_primitives/ecdsa_sig_verification)
- [Fixed base scalar multiplication](./cryptographic_primitives/scalar)
- [SHA256](./cryptographic_primitives/hashes.mdx#sha256)
- [Schnorr signature verification](./cryptographic_primitives/schnorr.mdx)
- [Blake2s](./cryptographic_primitives/hashes.mdx#blake2s)
- [Blake3](./cryptographic_primitives/hashes.mdx#blake3)
- [Pedersen Hash](./cryptographic_primitives/hashes.mdx#pedersen_hash)
- [Pedersen Commitment](./cryptographic_primitives/hashes.mdx#pedersen_commitment)
- [ECDSA signature verification](./cryptographic_primitives/ecdsa_sig_verification.mdx)
- [Fixed base scalar multiplication](./cryptographic_primitives/scalar.mdx)
- AND
- XOR
- RANGE
- [Keccak256](./cryptographic_primitives/hashes#keccak256)
- [Keccak256](./cryptographic_primitives/hashes.mdx#keccak256)
- [Recursive proof verification](./recursion)

Most black box functions are included as part of the Noir standard library, however `AND`, `XOR` and `RANGE` are used as part of the Noir language syntax. For instance, using the bitwise operator `&` will invoke the `AND` black box function.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false.
Loading