mirror of
https://github.com/fluencelabs/wasmer
synced 2025-05-30 02:11:20 +00:00
Merge branch 'master' into feature/llvm-target-triple
This commit is contained in:
commit
c4c4adb7bf
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
## **[Unreleased]**
|
## **[Unreleased]**
|
||||||
|
|
||||||
|
- [#1335](https://github.com/wasmerio/wasmer/pull/1335) Change mutability of `memory` to `const` in `wasmer_memory_data_length` in the C API
|
||||||
- [#1329](https://github.com/wasmerio/wasmer/pull/1329) New numbers and strings instructions for WIT
|
- [#1329](https://github.com/wasmerio/wasmer/pull/1329) New numbers and strings instructions for WIT
|
||||||
- [#1332](https://github.com/wasmerio/wasmer/pull/1332) Add option to `CompilerConfig` to force compiler IR verification off even when `debug_assertions` are enabled. This can be used to make debug builds faster, which may be important if you're creating a library that wraps Wasmer and depend on the speed of debug builds.
|
- [#1332](https://github.com/wasmerio/wasmer/pull/1332) Add option to `CompilerConfig` to force compiler IR verification off even when `debug_assertions` are enabled. This can be used to make debug builds faster, which may be important if you're creating a library that wraps Wasmer and depend on the speed of debug builds.
|
||||||
- [#1320](https://github.com/wasmerio/wasmer/pull/1320) Change `custom_sections` field in `ModuleInfo` to be more standards compliant by allowing multiple custom sections with the same name. To get the old behavior with the new API, you can add `.last().unwrap()` to accesses. For example, `module_info.custom_sections["custom_section_name"].last().unwrap()`.
|
- [#1320](https://github.com/wasmerio/wasmer/pull/1320) Change `custom_sections` field in `ModuleInfo` to be more standards compliant by allowing multiple custom sections with the same name. To get the old behavior with the new API, you can add `.last().unwrap()` to accesses. For example, `module_info.custom_sections["custom_section_name"].last().unwrap()`.
|
||||||
|
@ -169,7 +169,7 @@ fn instruction<'input, E: ParseError<&'input [u8]>>(
|
|||||||
(
|
(
|
||||||
input,
|
input,
|
||||||
Instruction::CallCore {
|
Instruction::CallCore {
|
||||||
function_index: argument_0 as usize,
|
function_index: argument_0 as u32,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ impl<'a> Parse<'a> for Instruction {
|
|||||||
parser.parse::<keyword::call_core>()?;
|
parser.parse::<keyword::call_core>()?;
|
||||||
|
|
||||||
Ok(Instruction::CallCore {
|
Ok(Instruction::CallCore {
|
||||||
function_index: parser.parse::<u64>()? as usize,
|
function_index: parser.parse::<u32>()?,
|
||||||
})
|
})
|
||||||
} else if lookahead.peek::<keyword::s8_from_i32>() {
|
} else if lookahead.peek::<keyword::s8_from_i32>() {
|
||||||
parser.parse::<keyword::s8_from_i32>()?;
|
parser.parse::<keyword::s8_from_i32>()?;
|
||||||
|
@ -5,6 +5,7 @@ use crate::{ast::InterfaceType, interpreter::Instruction};
|
|||||||
use std::{
|
use std::{
|
||||||
error::Error,
|
error::Error,
|
||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
|
num::TryFromIntError,
|
||||||
result::Result,
|
result::Result,
|
||||||
string::{self, ToString},
|
string::{self, ToString},
|
||||||
};
|
};
|
||||||
@ -149,6 +150,12 @@ pub enum InstructionErrorKind {
|
|||||||
|
|
||||||
/// The string contains invalid UTF-8 encoding.
|
/// The string contains invalid UTF-8 encoding.
|
||||||
String(string::FromUtf8Error),
|
String(string::FromUtf8Error),
|
||||||
|
|
||||||
|
/// Out of range integral type conversion attempted.
|
||||||
|
NegativeValue {
|
||||||
|
/// The variable name that triggered the error.
|
||||||
|
subject: &'static str,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error for InstructionErrorKind {}
|
impl Error for InstructionErrorKind {}
|
||||||
@ -227,6 +234,18 @@ impl Display for InstructionErrorKind {
|
|||||||
"{}",
|
"{}",
|
||||||
error
|
error
|
||||||
),
|
),
|
||||||
|
|
||||||
|
Self::NegativeValue { subject } => write!(
|
||||||
|
formatter,
|
||||||
|
"attempted to convert `{}` but it appears to be a negative value",
|
||||||
|
subject
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<(TryFromIntError, &'static str)> for InstructionErrorKind {
|
||||||
|
fn from((_, subject): (TryFromIntError, &'static str)) -> Self {
|
||||||
|
InstructionErrorKind::NegativeValue { subject }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -12,7 +12,7 @@ pub enum Instruction {
|
|||||||
/// The `call-core` instruction.
|
/// The `call-core` instruction.
|
||||||
CallCore {
|
CallCore {
|
||||||
/// The function index.
|
/// The function index.
|
||||||
function_index: usize,
|
function_index: u32,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// The `s8.from_i32` instruction.
|
/// The `s8.from_i32` instruction.
|
||||||
|
@ -8,7 +8,7 @@ executable_instruction!(
|
|||||||
move |runtime| -> _ {
|
move |runtime| -> _ {
|
||||||
let invocation_inputs = runtime.invocation_inputs;
|
let invocation_inputs = runtime.invocation_inputs;
|
||||||
|
|
||||||
if index >= (invocation_inputs.len() as u32) {
|
if (index as usize) >= invocation_inputs.len() {
|
||||||
return Err(InstructionError::new(
|
return Err(InstructionError::new(
|
||||||
instruction,
|
instruction,
|
||||||
InstructionErrorKind::InvocationInputIsMissing { index },
|
InstructionErrorKind::InvocationInputIsMissing { index },
|
||||||
|
@ -8,16 +8,16 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
executable_instruction!(
|
executable_instruction!(
|
||||||
call_core(function_index: usize, instruction: Instruction) -> _ {
|
call_core(function_index: u32, instruction: Instruction) -> _ {
|
||||||
move |runtime| -> _ {
|
move |runtime| -> _ {
|
||||||
let instance = &mut runtime.wasm_instance;
|
let instance = &mut runtime.wasm_instance;
|
||||||
let index = FunctionIndex::new(function_index);
|
let index = FunctionIndex::new(function_index as usize);
|
||||||
|
|
||||||
let local_or_import = instance.local_or_import(index).ok_or_else(|| {
|
let local_or_import = instance.local_or_import(index).ok_or_else(|| {
|
||||||
InstructionError::new(
|
InstructionError::new(
|
||||||
instruction,
|
instruction,
|
||||||
InstructionErrorKind::LocalOrImportIsMissing {
|
InstructionErrorKind::LocalOrImportIsMissing {
|
||||||
function_index: function_index as u32,
|
function_index: function_index,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
@ -40,7 +40,7 @@ executable_instruction!(
|
|||||||
return Err(InstructionError::new(
|
return Err(InstructionError::new(
|
||||||
instruction,
|
instruction,
|
||||||
InstructionErrorKind::LocalOrImportSignatureMismatch {
|
InstructionErrorKind::LocalOrImportSignatureMismatch {
|
||||||
function_index: function_index as u32,
|
function_index: function_index,
|
||||||
expected: (local_or_import.inputs().to_vec(), vec![]),
|
expected: (local_or_import.inputs().to_vec(), vec![]),
|
||||||
received: (input_types, vec![]),
|
received: (input_types, vec![]),
|
||||||
},
|
},
|
||||||
@ -51,7 +51,7 @@ executable_instruction!(
|
|||||||
InstructionError::new(
|
InstructionError::new(
|
||||||
instruction,
|
instruction,
|
||||||
InstructionErrorKind::LocalOrImportCall {
|
InstructionErrorKind::LocalOrImportCall {
|
||||||
function_index: function_index as u32,
|
function_index: function_index,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
@ -10,7 +10,7 @@ use crate::{
|
|||||||
Instruction,
|
Instruction,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::cell::Cell;
|
use std::{cell::Cell, convert::TryInto};
|
||||||
|
|
||||||
executable_instruction!(
|
executable_instruction!(
|
||||||
string_lift_memory(instruction: Instruction) -> _ {
|
string_lift_memory(instruction: Instruction) -> _ {
|
||||||
@ -23,7 +23,6 @@ executable_instruction!(
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
let memory_index: u32 = 0;
|
let memory_index: u32 = 0;
|
||||||
|
|
||||||
let memory = runtime
|
let memory = runtime
|
||||||
.wasm_instance
|
.wasm_instance
|
||||||
.memory(memory_index as usize)
|
.memory(memory_index as usize)
|
||||||
@ -34,8 +33,14 @@ executable_instruction!(
|
|||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let pointer = to_native::<i32>(&inputs[0], instruction)? as usize;
|
let pointer: usize = to_native::<i32>(&inputs[0], instruction)?
|
||||||
let length = to_native::<i32>(&inputs[1], instruction)? as usize;
|
.try_into()
|
||||||
|
.map_err(|e| (e, "pointer").into())
|
||||||
|
.map_err(|k| InstructionError::new(instruction, k))?;
|
||||||
|
let length: usize = to_native::<i32>(&inputs[1], instruction)?
|
||||||
|
.try_into()
|
||||||
|
.map_err(|e| (e, "length").into())
|
||||||
|
.map_err(|k| InstructionError::new(instruction, k))?;
|
||||||
let memory_view = memory.view();
|
let memory_view = memory.view();
|
||||||
|
|
||||||
if length == 0 {
|
if length == 0 {
|
||||||
@ -102,7 +107,12 @@ executable_instruction!(
|
|||||||
|
|
||||||
let string: String = to_native(&string, instruction)?;
|
let string: String = to_native(&string, instruction)?;
|
||||||
let string_bytes = string.as_bytes();
|
let string_bytes = string.as_bytes();
|
||||||
let string_length = string_bytes.len() as i32;
|
let string_length: i32 = string_bytes.len().try_into().map_err(|_| {
|
||||||
|
InstructionError::new(
|
||||||
|
instruction,
|
||||||
|
InstructionErrorKind::NegativeValue { subject: "string_length" },
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
let outputs = allocator.call(&[InterfaceValue::I32(string_length)]).map_err(|_| {
|
let outputs = allocator.call(&[InterfaceValue::I32(string_length)]).map_err(|_| {
|
||||||
InstructionError::new(
|
InstructionError::new(
|
||||||
@ -110,7 +120,12 @@ executable_instruction!(
|
|||||||
InstructionErrorKind::LocalOrImportCall { function_index: allocator_index },
|
InstructionErrorKind::LocalOrImportCall { function_index: allocator_index },
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
let string_pointer: i32 = to_native(&outputs[0], instruction)?;
|
let string_pointer: u32 = to_native::<i32>(&outputs[0], instruction)?.try_into().map_err(|_| {
|
||||||
|
InstructionError::new(
|
||||||
|
instruction,
|
||||||
|
InstructionErrorKind::NegativeValue { subject: "string_pointer" },
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
let memory_index: u32 = 0;
|
let memory_index: u32 = 0;
|
||||||
let memory_view = instance
|
let memory_view = instance
|
||||||
@ -127,7 +142,7 @@ executable_instruction!(
|
|||||||
memory_view[string_pointer as usize + nth].set(*byte);
|
memory_view[string_pointer as usize + nth].set(*byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime.stack.push(InterfaceValue::I32(string_pointer));
|
runtime.stack.push(InterfaceValue::I32(string_pointer as i32));
|
||||||
runtime.stack.push(InterfaceValue::I32(string_length));
|
runtime.stack.push(InterfaceValue::I32(string_length));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -203,6 +218,42 @@ mod tests {
|
|||||||
stack: [InterfaceValue::String("".into())],
|
stack: [InterfaceValue::String("".into())],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test_executable_instruction!(
|
||||||
|
test_string_lift_memory__negative_pointer =
|
||||||
|
instructions: [
|
||||||
|
Instruction::ArgumentGet { index: 0 },
|
||||||
|
Instruction::ArgumentGet { index: 1 },
|
||||||
|
Instruction::StringLiftMemory,
|
||||||
|
],
|
||||||
|
invocation_inputs: [
|
||||||
|
InterfaceValue::I32(-42),
|
||||||
|
InterfaceValue::I32(13),
|
||||||
|
],
|
||||||
|
instance: Instance {
|
||||||
|
memory: Memory::new("Hello!".as_bytes().iter().map(|u| Cell::new(*u)).collect()),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
error: r#"`string.lift_memory` attempted to convert `pointer` but it appears to be a negative value"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
test_executable_instruction!(
|
||||||
|
test_string_lift_memory__negative_length =
|
||||||
|
instructions: [
|
||||||
|
Instruction::ArgumentGet { index: 0 },
|
||||||
|
Instruction::ArgumentGet { index: 1 },
|
||||||
|
Instruction::StringLiftMemory,
|
||||||
|
],
|
||||||
|
invocation_inputs: [
|
||||||
|
InterfaceValue::I32(0),
|
||||||
|
InterfaceValue::I32(-1),
|
||||||
|
],
|
||||||
|
instance: Instance {
|
||||||
|
memory: Memory::new("Hello!".as_bytes().iter().map(|u| Cell::new(*u)).collect()),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
error: r#"`string.lift_memory` attempted to convert `length` but it appears to be a negative value"#,
|
||||||
|
);
|
||||||
|
|
||||||
test_executable_instruction!(
|
test_executable_instruction!(
|
||||||
test_string_lift_memory__read_out_of_memory =
|
test_string_lift_memory__read_out_of_memory =
|
||||||
instructions: [
|
instructions: [
|
||||||
|
@ -198,7 +198,7 @@ pub extern "C" fn wasmer_memory_data(memory: *const wasmer_memory_t) -> *mut u8
|
|||||||
/// ```
|
/// ```
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasmer_memory_data_length(memory: *mut wasmer_memory_t) -> u32 {
|
pub extern "C" fn wasmer_memory_data_length(memory: *const wasmer_memory_t) -> u32 {
|
||||||
if memory.is_null() {
|
if memory.is_null() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1171,7 +1171,7 @@ uint8_t *wasmer_memory_data(const wasmer_memory_t *memory);
|
|||||||
* uint32_t memory_data_length = wasmer_memory_data_length(memory);
|
* uint32_t memory_data_length = wasmer_memory_data_length(memory);
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
uint32_t wasmer_memory_data_length(wasmer_memory_t *memory);
|
uint32_t wasmer_memory_data_length(const wasmer_memory_t *memory);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees memory for the given `wasmer_memory_t`.
|
* Frees memory for the given `wasmer_memory_t`.
|
||||||
|
@ -964,7 +964,7 @@ uint8_t *wasmer_memory_data(const wasmer_memory_t *memory);
|
|||||||
/// ```c
|
/// ```c
|
||||||
/// uint32_t memory_data_length = wasmer_memory_data_length(memory);
|
/// uint32_t memory_data_length = wasmer_memory_data_length(memory);
|
||||||
/// ```
|
/// ```
|
||||||
uint32_t wasmer_memory_data_length(wasmer_memory_t *memory);
|
uint32_t wasmer_memory_data_length(const wasmer_memory_t *memory);
|
||||||
|
|
||||||
/// Frees memory for the given `wasmer_memory_t`.
|
/// Frees memory for the given `wasmer_memory_t`.
|
||||||
///
|
///
|
||||||
|
Loading…
x
Reference in New Issue
Block a user