Skip to content

Commit

Permalink
disallowed gm test
Browse files Browse the repository at this point in the history
  • Loading branch information
sezna committed Nov 4, 2021
1 parent d0f7a81 commit 22bb85b
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 0 deletions.
78 changes: 78 additions & 0 deletions core_lang/src/asm_generation/checks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//! Various checks and heuristics that are naively run on sequences of opcodes.
//!
//! This is _not_ the place for optimization passes.
use crate::asm_generation::FinalizedAsm;
use crate::asm_lang::allocated_ops::{AllocatedOp, AllocatedOpcode};
use crate::asm_lang::*;
use crate::error::*;
use fuel_asm::Opcode as VmOp;

/// Checks for disallowed opcodes in non-contract code.
/// i.e., if this is a script or predicate, we can't use certain contract opcodes.
/// See https://github.com/FuelLabs/sway/issues/350 for details.
pub fn check_invalid_opcodes<'sc>(asm: &FinalizedAsm<'sc>) -> CompileResult<'sc, ()> {
match asm {
FinalizedAsm::ContractAbi { .. } | FinalizedAsm::Library => ok((), vec![], vec![]),
FinalizedAsm::ScriptMain {
program_section, ..
} => check_for_contract_opcodes(&program_section.ops[..]),
FinalizedAsm::PredicateMain {
program_section, ..
} => check_for_contract_opcodes(&program_section.ops[..]),
}
}

/// Checks if an opcode is one that can only be executed from within a contract. If so, throw an
/// error.
fn check_for_contract_opcodes<'sc>(ops: &[AllocatedOp<'sc>]) -> CompileResult<'sc, ()> {
use AllocatedOpcode::*;
let default_span = crate::Span {
span: pest::Span::new("no span found for opcode", 0, 1).unwrap(),
path: None,
};
let mut warnings = vec![];
let mut errors = vec![];
for op in ops {
match op.opcode {
GM(_, VirtualImmediate18 { value: 1 }) | GM(_, VirtualImmediate18 { value: 2 }) => {
errors.push(CompileError::GMFromExternalContract {
span: op
.owning_span
.clone()
.unwrap_or_else(|| default_span.clone()),
});
}
MINT(..) => {
errors.push(CompileError::MintFromExternalContext {
span: op
.owning_span
.clone()
.unwrap_or_else(|| default_span.clone()),
});
}
BURN(..) => {
errors.push(CompileError::BurnFromExternalContext {
span: op
.owning_span
.clone()
.unwrap_or_else(|| default_span.clone()),
});
}
SWW(..) | SRW(..) | SRWQ(..) | SWWQ(..) => {
errors.push(CompileError::ContractStorageFromExternalContext {
span: op
.owning_span
.clone()
.unwrap_or_else(|| default_span.clone()),
});
}
_ => (),
}
}

if errors.is_empty() {
ok((), warnings, errors)
} else {
err(warnings, errors)
}
}
1 change: 1 addition & 0 deletions test/src/e2e_vm_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ pub fn run(filter_regex: Option<regex::Regex>) {
"dependencies_parsing_error",
"mut_error_message",
"reassignment_to_non_variable_message",
"disallowed_gm",
];
project_names.into_iter().for_each(|name| {
if filter(name) {
Expand Down
5 changes: 5 additions & 0 deletions test/src/e2e_vm_tests/test_programs/disallowed_gm/Forc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[project]
author = "Alexander Hansen"
license = "MIT"
name = "disallowed_opcodes"
entry = "main.sw"
8 changes: 8 additions & 0 deletions test/src/e2e_vm_tests/test_programs/disallowed_gm/src/main.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
script;

fn main() {
// GM should be disallowed
asm(r1) {
gm r1 i1;
};
}

0 comments on commit 22bb85b

Please # to comment.