mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
chore: Harden instructions and program (#535)
Also enforce sane limits in program Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
This commit is contained in:
committed by
GitHub
parent
49958c2ece
commit
28891ef883
+118
-116
@@ -1,13 +1,8 @@
|
||||
#![allow(
|
||||
clippy::option_if_let_else,
|
||||
clippy::unused_trait_names,
|
||||
clippy::pattern_type_mismatch
|
||||
)]
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
use alloc::format;
|
||||
use alloc::string::{String, ToString};
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use super::{Instruction, InstructionData, LiteralOrRegister};
|
||||
@@ -15,129 +10,136 @@ use super::{Instruction, InstructionData, LiteralOrRegister};
|
||||
impl Instruction {
|
||||
/// Get detailed display string with parameter resolution for debugging
|
||||
pub fn display_with_params(&self, instruction_data: &InstructionData) -> String {
|
||||
match self {
|
||||
match *self {
|
||||
Instruction::LoopStart { params_index } => {
|
||||
if let Some(params) = instruction_data.get_loop_params(*params_index) {
|
||||
format!(
|
||||
"LOOP_START {:?} R({}) R({}) R({}) R({}) {} {}",
|
||||
params.mode,
|
||||
params.collection,
|
||||
params.key_reg,
|
||||
params.value_reg,
|
||||
params.result_reg,
|
||||
params.body_start,
|
||||
params.loop_end
|
||||
)
|
||||
} else {
|
||||
format!("LOOP_START P({}) [INVALID INDEX]", params_index)
|
||||
}
|
||||
}
|
||||
Instruction::BuiltinCall { params_index } => {
|
||||
if let Some(params) = instruction_data.get_builtin_call_params(*params_index) {
|
||||
let args_str = params
|
||||
.arg_registers()
|
||||
.iter()
|
||||
.map(|&r| format!("R({})", r))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ");
|
||||
format!(
|
||||
"BUILTIN_CALL R({}) B({}) [{}]",
|
||||
params.dest, params.builtin_index, args_str
|
||||
)
|
||||
} else {
|
||||
format!("BUILTIN_CALL P({}) [INVALID INDEX]", params_index)
|
||||
}
|
||||
instruction_data.get_loop_params(params_index).map_or_else(
|
||||
|| format!("LOOP_START P({}) [INVALID INDEX]", params_index),
|
||||
|params| {
|
||||
format!(
|
||||
"LOOP_START {:?} R({}) R({}) R({}) R({}) {} {}",
|
||||
params.mode,
|
||||
params.collection,
|
||||
params.key_reg,
|
||||
params.value_reg,
|
||||
params.result_reg,
|
||||
params.body_start,
|
||||
params.loop_end
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
Instruction::BuiltinCall { params_index } => instruction_data
|
||||
.get_builtin_call_params(params_index)
|
||||
.map_or_else(
|
||||
|| format!("BUILTIN_CALL P({}) [INVALID INDEX]", params_index),
|
||||
|params| {
|
||||
let args_str = params
|
||||
.arg_registers()
|
||||
.iter()
|
||||
.map(|&r| format!("R({})", r))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ");
|
||||
format!(
|
||||
"BUILTIN_CALL R({}) B({}) [{}]",
|
||||
params.dest, params.builtin_index, args_str
|
||||
)
|
||||
},
|
||||
),
|
||||
Instruction::HostAwait { dest, arg, id } => {
|
||||
format!("HOST_AWAIT R({}) R({}) R({})", dest, arg, id)
|
||||
}
|
||||
Instruction::FunctionCall { params_index } => {
|
||||
if let Some(params) = instruction_data.get_function_call_params(*params_index) {
|
||||
let args_str = params
|
||||
.arg_registers()
|
||||
.iter()
|
||||
.map(|&r| format!("R({})", r))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ");
|
||||
format!(
|
||||
"FUNCTION_CALL R({}) RULE({}) [{}]",
|
||||
params.dest, params.func_rule_index, args_str
|
||||
)
|
||||
} else {
|
||||
format!("FUNCTION_CALL P({}) [INVALID INDEX]", params_index)
|
||||
}
|
||||
}
|
||||
Instruction::FunctionCall { params_index } => instruction_data
|
||||
.get_function_call_params(params_index)
|
||||
.map_or_else(
|
||||
|| format!("FUNCTION_CALL P({}) [INVALID INDEX]", params_index),
|
||||
|params| {
|
||||
let args_str = params
|
||||
.arg_registers()
|
||||
.iter()
|
||||
.map(|&r| format!("R({})", r))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ");
|
||||
format!(
|
||||
"FUNCTION_CALL R({}) RULE({}) [{}]",
|
||||
params.dest, params.func_rule_index, args_str
|
||||
)
|
||||
},
|
||||
),
|
||||
Instruction::ObjectCreate { params_index } => {
|
||||
if let Some(params) = instruction_data.get_object_create_params(*params_index) {
|
||||
let mut field_parts = Vec::new();
|
||||
instruction_data
|
||||
.get_object_create_params(params_index)
|
||||
.map_or_else(
|
||||
|| format!("OBJECT_CREATE P({}) [INVALID INDEX]", params_index),
|
||||
|params| {
|
||||
let mut field_parts = Vec::new();
|
||||
|
||||
// Add literal key fields
|
||||
for &(literal_idx, value_reg) in params.literal_key_field_pairs() {
|
||||
field_parts.push(format!("L({}):R({})", literal_idx, value_reg));
|
||||
}
|
||||
// Add literal key fields
|
||||
for &(literal_idx, value_reg) in params.literal_key_field_pairs() {
|
||||
field_parts.push(format!("L({}):R({})", literal_idx, value_reg));
|
||||
}
|
||||
|
||||
// Add non-literal key fields
|
||||
for &(key_reg, value_reg) in params.field_pairs() {
|
||||
field_parts.push(format!("R({}):R({})", key_reg, value_reg));
|
||||
}
|
||||
// Add non-literal key fields
|
||||
for &(key_reg, value_reg) in params.field_pairs() {
|
||||
field_parts.push(format!("R({}):R({})", key_reg, value_reg));
|
||||
}
|
||||
|
||||
let fields_str = field_parts.join(" ");
|
||||
format!(
|
||||
"OBJECT_CREATE R({}) L({}) [{}]",
|
||||
params.dest, params.template_literal_idx, fields_str
|
||||
let fields_str = field_parts.join(" ");
|
||||
format!(
|
||||
"OBJECT_CREATE R({}) L({}) [{}]",
|
||||
params.dest, params.template_literal_idx, fields_str
|
||||
)
|
||||
},
|
||||
)
|
||||
} else {
|
||||
format!("OBJECT_CREATE P({}) [INVALID INDEX]", params_index)
|
||||
}
|
||||
}
|
||||
Instruction::VirtualDataDocumentLookup { params_index } => {
|
||||
if let Some(params) =
|
||||
instruction_data.get_virtual_data_document_lookup_params(*params_index)
|
||||
{
|
||||
let components_str = params
|
||||
.path_components
|
||||
.iter()
|
||||
.map(|comp| match comp {
|
||||
LiteralOrRegister::Literal(idx) => format!("L({})", idx),
|
||||
LiteralOrRegister::Register(reg) => format!("R({})", reg),
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(".");
|
||||
format!(
|
||||
"VIRTUAL_DATA_DOCUMENT_LOOKUP R({}) [data.{}]",
|
||||
params.dest, components_str
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"VIRTUAL_DATA_DOCUMENT_LOOKUP P({}) [INVALID INDEX]",
|
||||
params_index
|
||||
)
|
||||
}
|
||||
}
|
||||
Instruction::ComprehensionBegin { params_index } => {
|
||||
if let Some(params) = instruction_data.get_comprehension_begin_params(*params_index)
|
||||
{
|
||||
format!(
|
||||
"COMPREHENSION_BEGIN {:?} R({}) R({}) R({}) {} {}",
|
||||
params.mode,
|
||||
params.collection_reg,
|
||||
params.key_reg,
|
||||
params.value_reg,
|
||||
params.body_start,
|
||||
params.comprehension_end
|
||||
)
|
||||
} else {
|
||||
format!("COMPREHENSION_BEGIN P({}) [INVALID INDEX]", params_index)
|
||||
}
|
||||
}
|
||||
_ => self.to_string(),
|
||||
Instruction::VirtualDataDocumentLookup { params_index } => instruction_data
|
||||
.get_virtual_data_document_lookup_params(params_index)
|
||||
.map_or_else(
|
||||
|| {
|
||||
format!(
|
||||
"VIRTUAL_DATA_DOCUMENT_LOOKUP P({}) [INVALID INDEX]",
|
||||
params_index
|
||||
)
|
||||
},
|
||||
|params| {
|
||||
let components_str = params
|
||||
.path_components
|
||||
.iter()
|
||||
.map(|comp| match *comp {
|
||||
LiteralOrRegister::Literal(idx) => format!("L({})", idx),
|
||||
LiteralOrRegister::Register(reg) => format!("R({})", reg),
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(".");
|
||||
format!(
|
||||
"VIRTUAL_DATA_DOCUMENT_LOOKUP R({}) [data.{}]",
|
||||
params.dest, components_str
|
||||
)
|
||||
},
|
||||
),
|
||||
Instruction::ComprehensionBegin { params_index } => instruction_data
|
||||
.get_comprehension_begin_params(params_index)
|
||||
.map_or_else(
|
||||
|| format!("COMPREHENSION_BEGIN P({}) [INVALID INDEX]", params_index),
|
||||
|params| {
|
||||
format!(
|
||||
"COMPREHENSION_BEGIN {:?} R({}) R({}) R({}) {} {}",
|
||||
params.mode,
|
||||
params.collection_reg,
|
||||
params.key_reg,
|
||||
params.value_reg,
|
||||
params.body_start,
|
||||
params.comprehension_end
|
||||
)
|
||||
},
|
||||
),
|
||||
_ => format!("{}", self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Display for Instruction {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
let text = match self {
|
||||
let text = match *self {
|
||||
Instruction::Load { dest, literal_idx } => {
|
||||
format!("LOAD R({}) L({})", dest, literal_idx)
|
||||
}
|
||||
@@ -274,10 +276,10 @@ impl core::fmt::Display for Instruction {
|
||||
Instruction::ComprehensionBegin { params_index } => {
|
||||
format!("COMPREHENSION_BEGIN P({})", params_index)
|
||||
}
|
||||
Instruction::ComprehensionYield { value_reg, key_reg } => match key_reg {
|
||||
Some(k) => format!("COMPREHENSION_YIELD R({}) R({})", k, value_reg),
|
||||
None => format!("COMPREHENSION_YIELD R({})", value_reg),
|
||||
},
|
||||
Instruction::ComprehensionYield { value_reg, key_reg } => key_reg.as_ref().map_or_else(
|
||||
|| format!("COMPREHENSION_YIELD R({})", value_reg),
|
||||
|k| format!("COMPREHENSION_YIELD R({}) R({})", k, value_reg),
|
||||
),
|
||||
Instruction::ComprehensionEnd {} => String::from("COMPREHENSION_END"),
|
||||
};
|
||||
write!(f, "{}", text)
|
||||
|
||||
+12
-13
@@ -1,4 +1,3 @@
|
||||
#![allow(clippy::missing_const_for_fn)]
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
@@ -17,7 +16,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
/// RVM Instructions - simplified enum-based design
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
pub enum Instruction {
|
||||
/// Load literal value from literal table into register
|
||||
Load {
|
||||
@@ -320,47 +319,47 @@ pub enum Instruction {
|
||||
|
||||
impl Instruction {
|
||||
/// Create a new LoopStart instruction with parameter table index
|
||||
pub fn loop_start(params_index: u16) -> Self {
|
||||
pub const fn loop_start(params_index: u16) -> Self {
|
||||
Self::LoopStart { params_index }
|
||||
}
|
||||
|
||||
/// Create a new BuiltinCall instruction with parameter table index
|
||||
pub fn builtin_call(params_index: u16) -> Self {
|
||||
pub const fn builtin_call(params_index: u16) -> Self {
|
||||
Self::BuiltinCall { params_index }
|
||||
}
|
||||
|
||||
/// Create a new HostAwait instruction
|
||||
pub fn host_await(dest: u8, arg: u8, id: u8) -> Self {
|
||||
pub const fn host_await(dest: u8, arg: u8, id: u8) -> Self {
|
||||
Self::HostAwait { dest, arg, id }
|
||||
}
|
||||
|
||||
/// Create a new FunctionCall instruction with parameter table index
|
||||
pub fn function_call(params_index: u16) -> Self {
|
||||
pub const fn function_call(params_index: u16) -> Self {
|
||||
Self::FunctionCall { params_index }
|
||||
}
|
||||
|
||||
/// Create a new ObjectCreate instruction with parameter table index
|
||||
pub fn object_create(params_index: u16) -> Self {
|
||||
pub const fn object_create(params_index: u16) -> Self {
|
||||
Self::ObjectCreate { params_index }
|
||||
}
|
||||
|
||||
/// Create a new ArrayCreate instruction with parameter table index
|
||||
pub fn array_create(params_index: u16) -> Self {
|
||||
pub const fn array_create(params_index: u16) -> Self {
|
||||
Self::ArrayCreate { params_index }
|
||||
}
|
||||
|
||||
/// Create a new SetCreate instruction with parameter table index
|
||||
pub fn set_create(params_index: u16) -> Self {
|
||||
pub const fn set_create(params_index: u16) -> Self {
|
||||
Self::SetCreate { params_index }
|
||||
}
|
||||
|
||||
/// Create a new ComprehensionBegin instruction with parameter table index
|
||||
pub fn comprehension_begin(params_index: u16) -> Self {
|
||||
pub const fn comprehension_begin(params_index: u16) -> Self {
|
||||
Self::ComprehensionBegin { params_index }
|
||||
}
|
||||
|
||||
/// Create a new ComprehensionYield instruction
|
||||
pub fn comprehension_yield(value_reg: u8) -> Self {
|
||||
pub const fn comprehension_yield(value_reg: u8) -> Self {
|
||||
Self::ComprehensionYield {
|
||||
value_reg,
|
||||
key_reg: None,
|
||||
@@ -368,7 +367,7 @@ impl Instruction {
|
||||
}
|
||||
|
||||
/// Create a new ComprehensionYield instruction for object comprehensions
|
||||
pub fn comprehension_yield_object(key_reg: u8, value_reg: u8) -> Self {
|
||||
pub const fn comprehension_yield_object(key_reg: u8, value_reg: u8) -> Self {
|
||||
Self::ComprehensionYield {
|
||||
value_reg,
|
||||
key_reg: Some(key_reg),
|
||||
@@ -376,7 +375,7 @@ impl Instruction {
|
||||
}
|
||||
|
||||
/// Create a new ComprehensionEnd instruction
|
||||
pub fn comprehension_end() -> Self {
|
||||
pub const fn comprehension_end() -> Self {
|
||||
Self::ComprehensionEnd {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
#![allow(
|
||||
clippy::indexing_slicing,
|
||||
clippy::arithmetic_side_effects,
|
||||
clippy::missing_const_for_fn,
|
||||
clippy::as_conversions,
|
||||
clippy::pattern_type_mismatch
|
||||
)]
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -50,12 +42,13 @@ pub struct BuiltinCallParams {
|
||||
impl BuiltinCallParams {
|
||||
/// Get the number of arguments actually used
|
||||
pub fn arg_count(&self) -> usize {
|
||||
self.num_args as usize
|
||||
usize::from(self.num_args)
|
||||
}
|
||||
|
||||
/// Get argument register numbers as a slice
|
||||
pub fn arg_registers(&self) -> &[u8] {
|
||||
&self.args[..self.num_args as usize]
|
||||
let count = usize::from(self.num_args).min(self.args.len());
|
||||
self.args.get(..count).unwrap_or(&[])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,12 +69,13 @@ pub struct FunctionCallParams {
|
||||
impl FunctionCallParams {
|
||||
/// Get the number of arguments actually used
|
||||
pub fn arg_count(&self) -> usize {
|
||||
self.num_args as usize
|
||||
usize::from(self.num_args)
|
||||
}
|
||||
|
||||
/// Get argument register numbers as a slice
|
||||
pub fn arg_registers(&self) -> &[u8] {
|
||||
&self.args[..self.num_args as usize]
|
||||
let count = usize::from(self.num_args).min(self.args.len());
|
||||
self.args.get(..count).unwrap_or(&[])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,8 +96,10 @@ pub struct ObjectCreateParams {
|
||||
|
||||
impl ObjectCreateParams {
|
||||
/// Get the total number of fields
|
||||
pub fn field_count(&self) -> usize {
|
||||
self.literal_key_fields.len() + self.fields.len()
|
||||
pub const fn field_count(&self) -> usize {
|
||||
self.literal_key_fields
|
||||
.len()
|
||||
.saturating_add(self.fields.len())
|
||||
}
|
||||
|
||||
/// Get literal key field pairs as a slice
|
||||
@@ -129,7 +125,7 @@ pub struct ArrayCreateParams {
|
||||
|
||||
impl ArrayCreateParams {
|
||||
/// Get the number of elements
|
||||
pub fn element_count(&self) -> usize {
|
||||
pub const fn element_count(&self) -> usize {
|
||||
self.elements.len()
|
||||
}
|
||||
|
||||
@@ -151,7 +147,7 @@ pub struct SetCreateParams {
|
||||
|
||||
impl SetCreateParams {
|
||||
/// Get the number of elements
|
||||
pub fn element_count(&self) -> usize {
|
||||
pub const fn element_count(&self) -> usize {
|
||||
self.elements.len()
|
||||
}
|
||||
|
||||
@@ -175,7 +171,7 @@ pub struct VirtualDataDocumentLookupParams {
|
||||
|
||||
impl VirtualDataDocumentLookupParams {
|
||||
/// Get the number of path components
|
||||
pub fn component_count(&self) -> usize {
|
||||
pub const fn component_count(&self) -> usize {
|
||||
self.path_components.len()
|
||||
}
|
||||
|
||||
@@ -190,8 +186,8 @@ impl VirtualDataDocumentLookupParams {
|
||||
pub fn literal_indices(&self) -> Vec<u16> {
|
||||
self.path_components
|
||||
.iter()
|
||||
.filter_map(|c| match c {
|
||||
LiteralOrRegister::Literal(idx) => Some(*idx),
|
||||
.filter_map(|c| match *c {
|
||||
LiteralOrRegister::Literal(idx) => Some(idx),
|
||||
_ => None,
|
||||
})
|
||||
.collect()
|
||||
@@ -201,8 +197,8 @@ impl VirtualDataDocumentLookupParams {
|
||||
pub fn register_numbers(&self) -> Vec<u8> {
|
||||
self.path_components
|
||||
.iter()
|
||||
.filter_map(|c| match c {
|
||||
LiteralOrRegister::Register(reg) => Some(*reg),
|
||||
.filter_map(|c| match *c {
|
||||
LiteralOrRegister::Register(reg) => Some(reg),
|
||||
_ => None,
|
||||
})
|
||||
.collect()
|
||||
@@ -223,7 +219,7 @@ pub struct ChainedIndexParams {
|
||||
|
||||
impl ChainedIndexParams {
|
||||
/// Get the number of path components
|
||||
pub fn component_count(&self) -> usize {
|
||||
pub const fn component_count(&self) -> usize {
|
||||
self.path_components.len()
|
||||
}
|
||||
|
||||
@@ -238,8 +234,8 @@ impl ChainedIndexParams {
|
||||
pub fn literal_indices(&self) -> Vec<u16> {
|
||||
self.path_components
|
||||
.iter()
|
||||
.filter_map(|c| match c {
|
||||
LiteralOrRegister::Literal(idx) => Some(*idx),
|
||||
.filter_map(|c| match *c {
|
||||
LiteralOrRegister::Literal(idx) => Some(idx),
|
||||
_ => None,
|
||||
})
|
||||
.collect()
|
||||
@@ -249,8 +245,8 @@ impl ChainedIndexParams {
|
||||
pub fn register_numbers(&self) -> Vec<u8> {
|
||||
self.path_components
|
||||
.iter()
|
||||
.filter_map(|c| match c {
|
||||
LiteralOrRegister::Register(reg) => Some(*reg),
|
||||
.filter_map(|c| match *c {
|
||||
LiteralOrRegister::Register(reg) => Some(reg),
|
||||
_ => None,
|
||||
})
|
||||
.collect()
|
||||
@@ -302,8 +298,13 @@ pub struct InstructionData {
|
||||
}
|
||||
|
||||
impl InstructionData {
|
||||
fn ensure_u16_index(len: usize) -> u16 {
|
||||
debug_assert!(len <= usize::from(u16::MAX));
|
||||
u16::try_from(len).unwrap_or(u16::MAX)
|
||||
}
|
||||
|
||||
/// Create a new empty instruction data container
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
loop_params: Vec::new(),
|
||||
builtin_call_params: Vec::new(),
|
||||
@@ -319,74 +320,74 @@ impl InstructionData {
|
||||
|
||||
/// Add loop parameters and return the index
|
||||
pub fn add_loop_params(&mut self, params: LoopStartParams) -> u16 {
|
||||
let index = self.loop_params.len();
|
||||
let index = Self::ensure_u16_index(self.loop_params.len());
|
||||
self.loop_params.push(params);
|
||||
index as u16
|
||||
index
|
||||
}
|
||||
|
||||
/// Add builtin call parameters and return the index
|
||||
pub fn add_builtin_call_params(&mut self, params: BuiltinCallParams) -> u16 {
|
||||
let index = self.builtin_call_params.len();
|
||||
let index = Self::ensure_u16_index(self.builtin_call_params.len());
|
||||
self.builtin_call_params.push(params);
|
||||
index as u16
|
||||
index
|
||||
}
|
||||
|
||||
/// Add function call parameters and return the index
|
||||
pub fn add_function_call_params(&mut self, params: FunctionCallParams) -> u16 {
|
||||
let index = self.function_call_params.len();
|
||||
let index = Self::ensure_u16_index(self.function_call_params.len());
|
||||
self.function_call_params.push(params);
|
||||
index as u16
|
||||
index
|
||||
}
|
||||
|
||||
/// Add object create parameters and return the index
|
||||
pub fn add_object_create_params(&mut self, params: ObjectCreateParams) -> u16 {
|
||||
let index = self.object_create_params.len();
|
||||
let index = Self::ensure_u16_index(self.object_create_params.len());
|
||||
self.object_create_params.push(params);
|
||||
index as u16
|
||||
index
|
||||
}
|
||||
|
||||
/// Add array create parameters and return the index
|
||||
pub fn add_array_create_params(&mut self, params: ArrayCreateParams) -> u16 {
|
||||
let index = self.array_create_params.len();
|
||||
let index = Self::ensure_u16_index(self.array_create_params.len());
|
||||
self.array_create_params.push(params);
|
||||
index as u16
|
||||
index
|
||||
}
|
||||
|
||||
/// Add set create parameters and return the index
|
||||
pub fn add_set_create_params(&mut self, params: SetCreateParams) -> u16 {
|
||||
let index = self.set_create_params.len();
|
||||
let index = Self::ensure_u16_index(self.set_create_params.len());
|
||||
self.set_create_params.push(params);
|
||||
index as u16
|
||||
index
|
||||
}
|
||||
|
||||
/// Get loop parameters by index
|
||||
pub fn get_loop_params(&self, index: u16) -> Option<&LoopStartParams> {
|
||||
self.loop_params.get(index as usize)
|
||||
self.loop_params.get(usize::from(index))
|
||||
}
|
||||
|
||||
/// Get builtin call parameters by index
|
||||
pub fn get_builtin_call_params(&self, index: u16) -> Option<&BuiltinCallParams> {
|
||||
self.builtin_call_params.get(index as usize)
|
||||
self.builtin_call_params.get(usize::from(index))
|
||||
}
|
||||
|
||||
/// Get function call parameters by index
|
||||
pub fn get_function_call_params(&self, index: u16) -> Option<&FunctionCallParams> {
|
||||
self.function_call_params.get(index as usize)
|
||||
self.function_call_params.get(usize::from(index))
|
||||
}
|
||||
|
||||
/// Get object create parameters by index
|
||||
pub fn get_object_create_params(&self, index: u16) -> Option<&ObjectCreateParams> {
|
||||
self.object_create_params.get(index as usize)
|
||||
self.object_create_params.get(usize::from(index))
|
||||
}
|
||||
|
||||
/// Get array create parameters by index
|
||||
pub fn get_array_create_params(&self, index: u16) -> Option<&ArrayCreateParams> {
|
||||
self.array_create_params.get(index as usize)
|
||||
self.array_create_params.get(usize::from(index))
|
||||
}
|
||||
|
||||
/// Get set create parameters by index
|
||||
pub fn get_set_create_params(&self, index: u16) -> Option<&SetCreateParams> {
|
||||
self.set_create_params.get(index as usize)
|
||||
self.set_create_params.get(usize::from(index))
|
||||
}
|
||||
|
||||
/// Add virtual data document lookup parameters and return the index
|
||||
@@ -394,9 +395,9 @@ impl InstructionData {
|
||||
&mut self,
|
||||
params: VirtualDataDocumentLookupParams,
|
||||
) -> u16 {
|
||||
let index = self.virtual_data_document_lookup_params.len();
|
||||
let index = Self::ensure_u16_index(self.virtual_data_document_lookup_params.len());
|
||||
self.virtual_data_document_lookup_params.push(params);
|
||||
index as u16
|
||||
index
|
||||
}
|
||||
|
||||
/// Get virtual data document lookup parameters by index
|
||||
@@ -404,36 +405,37 @@ impl InstructionData {
|
||||
&self,
|
||||
index: u16,
|
||||
) -> Option<&VirtualDataDocumentLookupParams> {
|
||||
self.virtual_data_document_lookup_params.get(index as usize)
|
||||
self.virtual_data_document_lookup_params
|
||||
.get(usize::from(index))
|
||||
}
|
||||
|
||||
/// Add chained index parameters and return the index
|
||||
pub fn add_chained_index_params(&mut self, params: ChainedIndexParams) -> u16 {
|
||||
let index = self.chained_index_params.len();
|
||||
let index = Self::ensure_u16_index(self.chained_index_params.len());
|
||||
self.chained_index_params.push(params);
|
||||
index as u16
|
||||
index
|
||||
}
|
||||
|
||||
/// Get chained index parameters by index
|
||||
pub fn get_chained_index_params(&self, index: u16) -> Option<&ChainedIndexParams> {
|
||||
self.chained_index_params.get(index as usize)
|
||||
self.chained_index_params.get(usize::from(index))
|
||||
}
|
||||
|
||||
/// Get mutable reference to loop parameters by index
|
||||
pub fn get_loop_params_mut(&mut self, index: u16) -> Option<&mut LoopStartParams> {
|
||||
self.loop_params.get_mut(index as usize)
|
||||
self.loop_params.get_mut(usize::from(index))
|
||||
}
|
||||
|
||||
/// Add comprehension begin parameters and return the index
|
||||
pub fn add_comprehension_begin_params(&mut self, params: ComprehensionBeginParams) -> u16 {
|
||||
let index = self.comprehension_begin_params.len();
|
||||
let index = Self::ensure_u16_index(self.comprehension_begin_params.len());
|
||||
self.comprehension_begin_params.push(params);
|
||||
index as u16
|
||||
index
|
||||
}
|
||||
|
||||
/// Get comprehension begin parameters by index
|
||||
pub fn get_comprehension_begin_params(&self, index: u16) -> Option<&ComprehensionBeginParams> {
|
||||
self.comprehension_begin_params.get(index as usize)
|
||||
self.comprehension_begin_params.get(usize::from(index))
|
||||
}
|
||||
|
||||
/// Get mutable reference to comprehension begin parameters by index
|
||||
@@ -441,7 +443,7 @@ impl InstructionData {
|
||||
&mut self,
|
||||
index: u16,
|
||||
) -> Option<&mut ComprehensionBeginParams> {
|
||||
self.comprehension_begin_params.get_mut(index as usize)
|
||||
self.comprehension_begin_params.get_mut(usize::from(index))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user