Skip to content

Commit 77ea5b6

Browse files
authored
Update spec test suite submodule (#2485)
* Update spec test suite submodule * Add support for `assert_{invalid,malformed}_custom` directives * Shuffle around how `@custom` is printed to improve round-trip-ability * Disallow multiple `@metadata.branch_hint` annotations on one instruction. * Skip a custom-page-sizes test for now until the test upstream is updated. * Adjust the `name` section emitted during text-to-binary to happen after user-specified `@custom` sections to make round-tripping work. * Fix warnings
1 parent e72080a commit 77ea5b6

129 files changed

Lines changed: 2980 additions & 1087 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ci/generate-spec-tests.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ fn copy_test(src: &Path, dst: &Path) {
4040
return;
4141
}
4242

43+
// FIXME(WebAssembly/custom-page-sizes#58)
44+
if src.ends_with("proposals/custom-page-sizes/custom-page-sizes-invalid.wast") {
45+
return;
46+
}
47+
4348
let directive = match dst.file_name().and_then(|s| s.to_str()) {
4449
// Disable tests by doing something like:
4550
// Some("exact-func-import.wast") => "FAIL",

crates/json-from-wast/src/build.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,19 @@ impl<'a> JsonBuilder<'a, '_> {
103103
file,
104104
}
105105
}
106+
WastDirective::AssertMalformedCustom {
107+
span: _,
108+
module,
109+
message,
110+
} => {
111+
let line = self.lineno(module.span());
112+
let (_name, file) = self.emit_file(module, true)?;
113+
crate::Command::AssertMalformedCustom {
114+
line,
115+
text: message.into(),
116+
file,
117+
}
118+
}
106119
WastDirective::AssertInvalid {
107120
span: _,
108121
module,
@@ -116,6 +129,19 @@ impl<'a> JsonBuilder<'a, '_> {
116129
file,
117130
}
118131
}
132+
WastDirective::AssertInvalidCustom {
133+
span: _,
134+
module,
135+
message,
136+
} => {
137+
let line = self.lineno(module.span());
138+
let (_name, file) = self.emit_file(module, false)?;
139+
crate::Command::AssertInvalidCustom {
140+
line,
141+
text: message.into(),
142+
file,
143+
}
144+
}
119145
WastDirective::Register {
120146
span: _,
121147
module,

crates/json-from-wast/src/lib.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,27 @@ pub enum Command<'a> {
9797
#[serde(borrow)]
9898
text: Cow<'a, str>,
9999
},
100+
AssertMalformedCustom {
101+
line: u32,
102+
#[serde(borrow, flatten)]
103+
file: WasmFile<'a>,
104+
#[serde(borrow)]
105+
text: Cow<'a, str>,
106+
},
100107
AssertInvalid {
101108
line: u32,
102109
#[serde(borrow, flatten)]
103110
file: WasmFile<'a>,
104111
#[serde(borrow)]
105112
text: Cow<'a, str>,
106113
},
114+
AssertInvalidCustom {
115+
line: u32,
116+
#[serde(borrow, flatten)]
117+
file: WasmFile<'a>,
118+
#[serde(borrow)]
119+
text: Cow<'a, str>,
120+
},
107121
Register {
108122
line: u32,
109123
#[serde(borrow, skip_serializing_if = "Option::is_none")]
@@ -197,7 +211,9 @@ impl Command<'_> {
197211
| ModuleDefinition { line, .. }
198212
| ModuleInstance { line, .. }
199213
| AssertMalformed { line, .. }
214+
| AssertMalformedCustom { line, .. }
200215
| AssertInvalid { line, .. }
216+
| AssertInvalidCustom { line, .. }
201217
| Register { line, .. }
202218
| AssertUnlinkable { line, .. }
203219
| AssertUninstantiable { line, .. }

crates/wasmprinter/src/lib.rs

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,7 @@ struct State {
165165
core: CoreState,
166166
#[cfg(feature = "component-model")]
167167
component: ComponentState,
168-
custom_section_place: Option<(&'static str, usize)>,
169-
// `custom_section_place` stores the text representation of the location where
170-
// a custom section should be serialized in the binary format.
171-
// The tuple elements are a str (e.g. "after elem") and the line number
172-
// where the custom section place was set. `update_custom_section_place` won't
173-
// update the custom section place unless the line number changes; this prevents
174-
// printing a place "after xxx" where the xxx section doesn't appear in the text format
175-
// (e.g. because it was present but empty in the binary format).
168+
custom_section_place: Option<&'static str>,
176169
}
177170

178171
impl State {
@@ -485,8 +478,7 @@ impl Printer<'_, '_> {
485478
match encoding {
486479
Encoding::Module => {
487480
states.push(State::new(Encoding::Module));
488-
states.last_mut().unwrap().custom_section_place =
489-
Some(("before first", self.line));
481+
states.last_mut().unwrap().custom_section_place = Some("before first");
490482
if states.len() > 1 {
491483
self.start_group("core module")?;
492484
} else {
@@ -546,7 +538,6 @@ impl Printer<'_, '_> {
546538
self.result
547539
.print_custom_section(c.name(), c.data_offset(), c.data())?;
548540
if printed {
549-
self.update_custom_section_line(&mut states);
550541
continue;
551542
}
552543

@@ -589,16 +580,19 @@ impl Printer<'_, '_> {
589580
}
590581
}
591582
assert!(self.nesting == start);
592-
self.update_custom_section_line(&mut states);
593583
}
594584
Payload::TypeSection(s) => {
585+
if s.count() > 0 {
586+
self.update_custom_section_place(&mut states, "after type");
587+
}
595588
self.print_types(states.last_mut().unwrap(), s)?;
596-
self.update_custom_section_place(&mut states, "after type");
597589
}
598590
Payload::ImportSection(s) => {
599591
Self::ensure_module(&states)?;
592+
if s.count() > 0 {
593+
self.update_custom_section_place(&mut states, "after import");
594+
}
600595
self.print_imports(states.last_mut().unwrap(), s)?;
601-
self.update_custom_section_place(&mut states, "after import");
602596
}
603597
Payload::FunctionSection(reader) => {
604598
Self::ensure_module(&states)?;
@@ -609,35 +603,47 @@ impl Printer<'_, '_> {
609603
MAX_WASM_FUNCTIONS
610604
);
611605
}
606+
if reader.count() > 0 {
607+
self.update_custom_section_place(&mut states, "after func");
608+
}
612609
for ty in reader {
613610
states.last_mut().unwrap().core.func_to_type.push(Some(ty?))
614611
}
615-
self.update_custom_section_place(&mut states, "after func");
616612
}
617613
Payload::TableSection(s) => {
618614
Self::ensure_module(&states)?;
615+
if s.count() > 0 {
616+
self.update_custom_section_place(&mut states, "after table");
617+
}
619618
self.print_tables(states.last_mut().unwrap(), s)?;
620-
self.update_custom_section_place(&mut states, "after table");
621619
}
622620
Payload::MemorySection(s) => {
623621
Self::ensure_module(&states)?;
622+
if s.count() > 0 {
623+
self.update_custom_section_place(&mut states, "after memory");
624+
}
624625
self.print_memories(states.last_mut().unwrap(), s)?;
625-
self.update_custom_section_place(&mut states, "after memory");
626626
}
627627
Payload::TagSection(s) => {
628628
Self::ensure_module(&states)?;
629+
if s.count() > 0 {
630+
self.update_custom_section_place(&mut states, "after tag");
631+
}
629632
self.print_tags(states.last_mut().unwrap(), s)?;
630-
self.update_custom_section_place(&mut states, "after tag");
631633
}
632634
Payload::GlobalSection(s) => {
633635
Self::ensure_module(&states)?;
636+
if s.count() > 0 {
637+
self.update_custom_section_place(&mut states, "after global");
638+
}
634639
self.print_globals(states.last_mut().unwrap(), s)?;
635-
self.update_custom_section_place(&mut states, "after global");
636640
}
637641
Payload::ExportSection(s) => {
638642
Self::ensure_module(&states)?;
643+
if s.count() > 0 {
644+
self.update_custom_section_place(&mut states, "after export");
645+
}
639646
self.print_exports(states.last().unwrap(), s)?;
640-
self.update_custom_section_place(&mut states, "after export");
641647
}
642648
Payload::StartSection { func, range } => {
643649
Self::ensure_module(&states)?;
@@ -649,8 +655,10 @@ impl Printer<'_, '_> {
649655
}
650656
Payload::ElementSection(s) => {
651657
Self::ensure_module(&states)?;
658+
if s.count() > 0 {
659+
self.update_custom_section_place(&mut states, "after elem");
660+
}
652661
self.print_elems(states.last_mut().unwrap(), s)?;
653-
self.update_custom_section_place(&mut states, "after elem");
654662
}
655663
Payload::CodeSectionStart { .. } => {
656664
Self::ensure_module(&states)?;
@@ -669,8 +677,10 @@ impl Printer<'_, '_> {
669677
}
670678
Payload::DataSection(s) => {
671679
Self::ensure_module(&states)?;
680+
if s.count() > 0 {
681+
self.update_custom_section_place(&mut states, "after data");
682+
}
672683
self.print_data(states.last_mut().unwrap(), s)?;
673-
self.update_custom_section_place(&mut states, "after data");
674684
}
675685

676686
#[cfg(feature = "component-model")]
@@ -774,19 +784,8 @@ impl Printer<'_, '_> {
774784

775785
fn update_custom_section_place(&self, states: &mut Vec<State>, place: &'static str) {
776786
if let Some(last) = states.last_mut() {
777-
if let Some((prev, prev_line)) = &mut last.custom_section_place {
778-
if *prev_line != self.line {
779-
*prev = place;
780-
*prev_line = self.line;
781-
}
782-
}
783-
}
784-
}
785-
786-
fn update_custom_section_line(&self, states: &mut Vec<State>) {
787-
if let Some(last) = states.last_mut() {
788-
if let Some((_, prev_line)) = &mut last.custom_section_place {
789-
*prev_line = self.line;
787+
if let Some(prev) = &mut last.custom_section_place {
788+
*prev = place;
790789
}
791790
}
792791
}
@@ -1997,7 +1996,7 @@ impl Printer<'_, '_> {
19971996
self.newline(section.range().start)?;
19981997
self.start_group("@custom ")?;
19991998
self.print_str(section.name())?;
2000-
if let Some((place, _)) = state.custom_section_place {
1999+
if let Some(place) = state.custom_section_place {
20012000
write!(self.result, " ({place})")?;
20022001
}
20032002
self.result.write_str(" ")?;

crates/wast/src/core/binary.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,10 @@ pub(crate) fn encode(
188188

189189
e.typed_section(&data);
190190

191+
e.custom_sections(AfterLast);
191192
if !names.is_empty() {
192193
e.wasm.section(&names.to_name_section());
193194
}
194-
e.custom_sections(AfterLast);
195195
if let Some(dwarf) = &mut dwarf {
196196
dwarf.emit(&mut e);
197197
}

crates/wast/src/core/expr.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -383,10 +383,16 @@ impl<'a> ExpressionParser<'a> {
383383
_ => return Err(parser.error("invalid value for branch hint")),
384384
};
385385

386-
self.branch_hints.push(BranchHint {
387-
instr_index: self.raw_instrs.len(),
388-
value,
389-
});
386+
let instr_index = self.raw_instrs.len();
387+
if let Some(prev) = self.branch_hints.last() {
388+
if prev.instr_index == instr_index {
389+
return Err(
390+
parser.error("@metadata.code.branch_hint annotation: duplicate annotation")
391+
);
392+
}
393+
}
394+
395+
self.branch_hints.push(BranchHint { instr_index, value });
390396
Ok(())
391397
}
392398

crates/wast/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,9 @@ pub mod kw {
396396
custom_keyword!(assert_exception);
397397
custom_keyword!(assert_exhaustion);
398398
custom_keyword!(assert_invalid);
399+
custom_keyword!(assert_invalid_custom);
399400
custom_keyword!(assert_malformed);
401+
custom_keyword!(assert_malformed_custom);
400402
custom_keyword!(assert_return);
401403
custom_keyword!(assert_trap);
402404
custom_keyword!(assert_unlinkable);

crates/wast/src/wast.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,13 @@ pub enum WastDirective<'a> {
9494
message: &'a str,
9595
},
9696

97+
/// Asserts the module has an invalid custom section.
98+
AssertInvalidCustom {
99+
span: Span,
100+
module: QuoteWat<'a>,
101+
message: &'a str,
102+
},
103+
97104
/// Registers the `module` instance with the given `name` to be available
98105
/// for importing in future module instances.
99106
Register {
@@ -149,6 +156,13 @@ pub enum WastDirective<'a> {
149156

150157
/// Waits for the specified thread to exit.
151158
Wait { span: Span, thread: Id<'a> },
159+
160+
/// Asserts that a custom section of `module` is malformed.
161+
AssertMalformedCustom {
162+
span: Span,
163+
module: QuoteWat<'a>,
164+
message: &'a str,
165+
},
152166
}
153167

154168
impl WastDirective<'_> {
@@ -163,12 +177,14 @@ impl WastDirective<'_> {
163177
| WastDirective::ModuleDefinition(QuoteWat::QuoteComponent(span, _)) => *span,
164178
WastDirective::ModuleInstance { span, .. }
165179
| WastDirective::AssertMalformed { span, .. }
180+
| WastDirective::AssertMalformedCustom { span, .. }
166181
| WastDirective::Register { span, .. }
167182
| WastDirective::AssertTrap { span, .. }
168183
| WastDirective::AssertReturn { span, .. }
169184
| WastDirective::AssertExhaustion { span, .. }
170185
| WastDirective::AssertUnlinkable { span, .. }
171186
| WastDirective::AssertInvalid { span, .. }
187+
| WastDirective::AssertInvalidCustom { span, .. }
172188
| WastDirective::AssertException { span, .. }
173189
| WastDirective::AssertSuspension { span, .. }
174190
| WastDirective::Wait { span, .. } => *span,
@@ -190,13 +206,27 @@ impl<'a> Parse<'a> for WastDirective<'a> {
190206
module: parser.parens(|p| p.parse())?,
191207
message: parser.parse()?,
192208
})
209+
} else if l.peek::<kw::assert_malformed_custom>()? {
210+
let span = parser.parse::<kw::assert_malformed_custom>()?.0;
211+
Ok(WastDirective::AssertMalformedCustom {
212+
span,
213+
module: parser.parens(|p| p.parse())?,
214+
message: parser.parse()?,
215+
})
193216
} else if l.peek::<kw::assert_invalid>()? {
194217
let span = parser.parse::<kw::assert_invalid>()?.0;
195218
Ok(WastDirective::AssertInvalid {
196219
span,
197220
module: parser.parens(|p| p.parse())?,
198221
message: parser.parse()?,
199222
})
223+
} else if l.peek::<kw::assert_invalid_custom>()? {
224+
let span = parser.parse::<kw::assert_invalid_custom>()?.0;
225+
Ok(WastDirective::AssertInvalidCustom {
226+
span,
227+
module: parser.parens(|p| p.parse())?,
228+
message: parser.parse()?,
229+
})
200230
} else if l.peek::<kw::register>()? {
201231
let span = parser.parse::<kw::register>()?.0;
202232
Ok(WastDirective::Register {

0 commit comments

Comments
 (0)