Skip to content

Commit 74dfc47

Browse files
committed
chore: sync wasm changes for argument errors
1 parent 186830c commit 74dfc47

File tree

1 file changed

+83
-9
lines changed

1 file changed

+83
-9
lines changed

clarity/src/vm/clarity_wasm.rs

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7803,6 +7803,15 @@ mod error_mapping {
78037803
/// usually triggered by `(unwrap!...)` and `(unwrap-err!...)`.
78047804
ShortReturnExpectedValue = 12,
78057805

7806+
/// Indicates an attempt to use a function with the wrong amount of arguments
7807+
ArgumentCountMismatch = 13,
7808+
7809+
/// Indicates an attempt to use a function with too few arguments
7810+
ArgumentCountAtLeast = 14,
7811+
7812+
/// Indicates an attempt to use a function with too many arguments
7813+
ArgumentCountAtMost = 15,
7814+
78067815
/// A catch-all for errors that are not mapped to specific error codes.
78077816
/// This might be used for unexpected or unclassified errors.
78087817
NotMapped = 99,
@@ -7825,6 +7834,9 @@ mod error_mapping {
78257834
10 => ErrorMap::ShortReturnExpectedValueResponse,
78267835
11 => ErrorMap::ShortReturnExpectedValueOptional,
78277836
12 => ErrorMap::ShortReturnExpectedValue,
7837+
13 => ErrorMap::ArgumentCountMismatch,
7838+
14 => ErrorMap::ArgumentCountAtLeast,
7839+
15 => ErrorMap::ArgumentCountAtMost,
78287840
_ => ErrorMap::NotMapped,
78297841
}
78307842
}
@@ -7948,8 +7960,7 @@ mod error_mapping {
79487960
Error::Runtime(RuntimeErrorType::UnwrapFailure, Some(Vec::new()))
79497961
}
79507962
ErrorMap::ShortReturnAssertionFailure => {
7951-
let clarity_val =
7952-
short_return_value(&instance, &mut store, epoch_id, clarity_version);
7963+
let clarity_val = short_return_value(&instance, &mut store, epoch_id, clarity_version);
79537964
Error::ShortReturn(ShortReturnType::AssertionFailed(clarity_val))
79547965
}
79557966
ErrorMap::ArithmeticPowError => Error::Runtime(
@@ -7976,23 +7987,35 @@ mod error_mapping {
79767987
Error::Unchecked(CheckErrors::NameAlreadyUsed(arg_name))
79777988
}
79787989
ErrorMap::ShortReturnExpectedValueResponse => {
7979-
let clarity_val =
7980-
short_return_value(&instance, &mut store, epoch_id, clarity_version);
7990+
let clarity_val = short_return_value(&instance, &mut store, epoch_id, clarity_version);
79817991
Error::ShortReturn(ShortReturnType::ExpectedValue(Value::Response(
79827992
ResponseData {
79837993
committed: false,
79847994
data: Box::new(clarity_val),
79857995
},
79867996
)))
79877997
}
7988-
ErrorMap::ShortReturnExpectedValueOptional => Error::ShortReturn(
7989-
ShortReturnType::ExpectedValue(Value::Optional(OptionalData { data: None })),
7990-
),
7998+
ErrorMap::ShortReturnExpectedValueOptional => {
7999+
Error::ShortReturn(ShortReturnType::ExpectedValue(Value::Optional(
8000+
clarity::vm::types::OptionalData { data: None },
8001+
)))
8002+
}
79918003
ErrorMap::ShortReturnExpectedValue => {
7992-
let clarity_val =
7993-
short_return_value(&instance, &mut store, epoch_id, clarity_version);
8004+
let clarity_val = short_return_value(&instance, &mut store, epoch_id, clarity_version);
79948005
Error::ShortReturn(ShortReturnType::ExpectedValue(clarity_val))
79958006
}
8007+
ErrorMap::ArgumentCountMismatch => {
8008+
let (expected, got) = get_runtime_error_arg_lengths(&instance, &mut store);
8009+
Error::Unchecked(CheckErrors::IncorrectArgumentCount(expected, got))
8010+
}
8011+
ErrorMap::ArgumentCountAtLeast => {
8012+
let (expected, got) = get_runtime_error_arg_lengths(&instance, &mut store);
8013+
Error::Unchecked(CheckErrors::RequiresAtLeastArguments(expected, got))
8014+
}
8015+
ErrorMap::ArgumentCountAtMost => {
8016+
let (expected, got) = get_runtime_error_arg_lengths(&instance, &mut store);
8017+
Error::Unchecked(CheckErrors::RequiresAtMostArguments(expected, got))
8018+
}
79968019
_ => panic!("Runtime error code {} not supported", runtime_error_code),
79978020
}
79988021
}
@@ -8014,6 +8037,28 @@ mod error_mapping {
80148037
.unwrap_or_else(|| panic!("Could not find ${} global with i32 value", name))
80158038
}
80168039

8040+
/// Retrieves the expected and actual argument counts from a byte-encoded string.
8041+
///
8042+
/// This function interprets a string as a sequence of bytes, where the first 4 bytes
8043+
/// represent the expected number of arguments, and the bytes at positions 16 to 19
8044+
/// represent the actual number of arguments received. It converts these byte sequences
8045+
/// into `usize` values and returns them as a tuple.
8046+
///
8047+
/// # Returns
8048+
///
8049+
/// A tuple `(expected, got)` where:
8050+
/// - `expected` is the number of arguments expected.
8051+
/// - `got` is the number of arguments actually received.
8052+
fn extract_expected_and_got(bytes: &[u8]) -> (usize, usize) {
8053+
// Assuming the first 4 bytes represent the expected value
8054+
let expected = u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]) as usize;
8055+
8056+
// Assuming the next 4 bytes represent the got value
8057+
let got = u32::from_le_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]) as usize;
8058+
8059+
(expected, got)
8060+
}
8061+
80178062
/// Retrieves and deserializes a Clarity value from WebAssembly memory in the context of a short return.
80188063
///
80198064
/// This function is used to extract a Clarity value that has been stored in WebAssembly memory
@@ -8047,4 +8092,33 @@ mod error_mapping {
80478092
read_from_wasm_indirect(memory, store, &value_ty, val_offset, *epoch_id)
80488093
.unwrap_or_else(|e| panic!("Could not read thrown value from memory: {}", e))
80498094
}
8095+
8096+
/// Retrieves the argument lengths from the runtime error global variables.
8097+
///
8098+
/// This function reads the global variables `runtime-error-arg-offset` and `runtime-error-arg-len`
8099+
/// from the WebAssembly instance and constructs a string representing the argument lengths.
8100+
///
8101+
/// # Returns
8102+
///
8103+
/// A string representing the argument lengths.
8104+
fn get_runtime_error_arg_lengths(
8105+
instance: &Instance,
8106+
store: &mut impl AsContextMut,
8107+
) -> (usize, usize) {
8108+
let runtime_error_arg_offset = get_global_i32(instance, store, "runtime-error-arg-offset");
8109+
let runtime_error_arg_len = get_global_i32(instance, store, "runtime-error-arg-len");
8110+
8111+
let memory = instance
8112+
.get_memory(&mut *store, "memory")
8113+
.unwrap_or_else(|| panic!("Could not find wasm instance memory"));
8114+
let arg_lengths = read_bytes_from_wasm(
8115+
memory,
8116+
store,
8117+
runtime_error_arg_offset,
8118+
runtime_error_arg_len,
8119+
)
8120+
.unwrap_or_else(|e| panic!("Could not recover arg_lengths: {e}"));
8121+
8122+
extract_expected_and_got(&arg_lengths)
8123+
}
80508124
}

0 commit comments

Comments
 (0)