Skip to content

Commit c092bae

Browse files
authored
Fix ref types validation; add null (bytecodealliance#131)
1 parent 3586c42 commit c092bae

6 files changed

Lines changed: 54 additions & 9 deletions

File tree

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "wasmparser"
3-
version = "0.37.2"
3+
version = "0.38.0"
44
authors = ["Yury Delendik <ydelendik@mozilla.com>"]
55
license = "Apache-2.0 WITH LLVM-exception"
66
repository = "https://github.com/yurydelendik/wasmparser.rs"
@@ -15,7 +15,7 @@ edition = "2018"
1515

1616
[dev-dependencies]
1717
criterion = "0.2"
18-
wabt = "0.9.1"
18+
wabt = "0.9.2"
1919

2020
[dependencies.hashbrown]
2121
version = "0.5.0"

src/operators_validator.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@ use crate::primitives::{
2424
};
2525

2626
/// Test if `subtype` is a subtype of `supertype`.
27-
fn is_subtype_supertype(subtype: Type, supertype: Type) -> bool {
27+
pub(crate) fn is_subtype_supertype(subtype: Type, supertype: Type) -> bool {
2828
match supertype {
29-
Type::AnyRef => subtype == Type::AnyRef || subtype == Type::AnyFunc,
29+
Type::AnyRef => {
30+
subtype == Type::AnyRef || subtype == Type::AnyFunc || subtype == Type::Null
31+
}
32+
Type::AnyFunc => subtype == Type::AnyFunc || subtype == Type::Null,
3033
_ => subtype == supertype,
3134
}
3235
}
@@ -1319,12 +1322,12 @@ impl OperatorValidator {
13191322
}
13201323
Operator::RefNull => {
13211324
self.check_reference_types_enabled()?;
1322-
self.func_state.change_frame_with_type(0, Type::AnyRef)?;
1325+
self.func_state.change_frame_with_type(0, Type::Null)?;
13231326
}
13241327
Operator::RefIsNull => {
13251328
self.check_reference_types_enabled()?;
13261329
self.check_operands(&[Type::AnyRef])?;
1327-
self.func_state.change_frame_with_type(0, Type::I32)?;
1330+
self.func_state.change_frame_with_type(1, Type::I32)?;
13281331
}
13291332
Operator::V128Load { ref memarg } => {
13301333
self.check_simd_enabled()?;

src/primitives.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ pub enum Type {
8484
AnyRef,
8585
Func,
8686
EmptyBlockType,
87+
Null,
8788
}
8889

8990
/// Either a value type or a function type.

src/tests.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,9 @@ mod wast_tests {
372372
if config.operator_config.enable_simd {
373373
features.enable_simd();
374374
}
375+
if config.operator_config.enable_reference_types {
376+
features.enable_reference_types();
377+
}
375378
features
376379
}
377380

@@ -473,6 +476,32 @@ mod wast_tests {
473476
_ => false,
474477
},
475478
);
479+
480+
run_proposal_tests(
481+
"reference-types",
482+
{
483+
let mut config: ValidatingParserConfig = default_config();
484+
config.operator_config.enable_reference_types = true;
485+
config
486+
},
487+
|name, line| match (name, line) {
488+
("ref_null.wast", _)
489+
| ("ref_is_null.wast", _)
490+
| ("ref_func.wast", _)
491+
| ("linking.wast", _)
492+
| ("globals.wast", _)
493+
| ("imports.wast", _)
494+
| ("br_table.wast", _)
495+
| ("select.wast", _)
496+
| ("table_get.wast", _)
497+
| ("table_set.wast", _)
498+
| ("table_size.wast", _)
499+
| ("table_fill.wast", _)
500+
| ("table_grow.wast", _)
501+
| ("exports.wast", _) => true,
502+
_ => false,
503+
},
504+
);
476505
}
477506

478507
#[test]

src/validator.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ use crate::primitives::{
3434
use crate::parser::{Parser, ParserInput, ParserState, WasmDecoder};
3535

3636
use crate::operators_validator::{
37-
FunctionEnd, OperatorValidator, OperatorValidatorConfig, WasmModuleResources,
38-
DEFAULT_OPERATOR_VALIDATOR_CONFIG,
37+
is_subtype_supertype, FunctionEnd, OperatorValidator, OperatorValidatorConfig,
38+
WasmModuleResources, DEFAULT_OPERATOR_VALIDATOR_CONFIG,
3939
};
4040

4141
use crate::readers::FunctionBody;
@@ -196,6 +196,12 @@ impl<'a> ValidatingParser<'a> {
196196
fn check_value_type(&self, ty: Type) -> ValidatorResult<'a, ()> {
197197
match ty {
198198
Type::I32 | Type::I64 | Type::F32 | Type::F64 => Ok(()),
199+
Type::Null | Type::AnyFunc | Type::AnyRef => {
200+
if !self.config.operator_config.enable_reference_types {
201+
return self.create_error("reference types support is not enabled");
202+
}
203+
Ok(())
204+
}
199205
Type::V128 => {
200206
if !self.config.operator_config.enable_simd {
201207
return self.create_error("SIMD support is not enabled");
@@ -301,6 +307,12 @@ impl<'a> ValidatingParser<'a> {
301307
Operator::I64Const { .. } => Type::I64,
302308
Operator::F32Const { .. } => Type::F32,
303309
Operator::F64Const { .. } => Type::F64,
310+
Operator::RefNull => {
311+
if !self.config.operator_config.enable_reference_types {
312+
return self.create_error("reference types support is not enabled");
313+
}
314+
Type::Null
315+
}
304316
Operator::V128Const { .. } => {
305317
if !self.config.operator_config.enable_simd {
306318
return self.create_error("SIMD support is not enabled");
@@ -315,7 +327,7 @@ impl<'a> ValidatingParser<'a> {
315327
}
316328
_ => return self.create_error("invalid init_expr operator"),
317329
};
318-
if ty != state.ty {
330+
if !is_subtype_supertype(ty, state.ty) {
319331
return self.create_error("invalid init_expr type");
320332
}
321333
Ok(())

tests/ref.wasm

61 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)