diff --git a/test/mjsunit/wasm/stringrefs-invalid.js b/test/mjsunit/wasm/stringrefs-invalid.js new file mode 100644 index 0000000000..c6f19d60b9 --- /dev/null +++ b/test/mjsunit/wasm/stringrefs-invalid.js @@ -0,0 +1,45 @@ +// Copyright 2022 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-wasm --experimental-wasm-eh --experimental-wasm-gc + +d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); + +function assertInvalid(fn, message) { + let builder = new WasmModuleBuilder(); + fn(builder); + assertThrows(() => builder.toModule(), WebAssembly.CompileError, + `WebAssembly.Module(): ${message}`); +} + +let kStringSectionCodeStr = '0x0' + kStringRefSectionCode.toString(16); +assertInvalid(builder => builder.addLiteralStringRef("foo"), + `unknown section code #${kStringSectionCodeStr} @+10`); + +for (let [name, code] of [['string', kWasmStringRef], + ['stringview_wtf8', kWasmStringViewWtf8], + ['stringview_wtf16', kWasmStringViewWtf16], + ['stringview_iter', kWasmStringViewIter]]) { + let message = `invalid value type 0x${(code & kLeb128Mask).toString(16)}`; + let default_init = WasmInitExpr.RefNull(code); + + assertInvalid(b => b.addType(makeSig([code], [])), + `${message} @+13`); + assertInvalid(b => b.addStruct([makeField(code, true)]), + `${message} @+13`); + assertInvalid(b => b.addArray(code, true), + `${message} @+12`); + assertInvalid(b => b.addType(makeSig([], [code])), + `${message} @+14`); + assertInvalid(b => b.addGlobal(code, true, default_init), + `${message} @+11`); + assertInvalid(b => b.addTable(code, 0), + `${message} @+11`); + assertInvalid(b => b.addPassiveElementSegment([default_init], code), + `${message} @+12`); + assertInvalid(b => b.addTag(makeSig([code], [])), + `${message} @+13`); + assertInvalid(b => b.addFunction(undefined, kSig_v_v).addLocals(code, 1), + `Compiling function #0 failed: ${message} @+24`); +} diff --git a/test/mjsunit/wasm/wasm-module-builder.js b/test/mjsunit/wasm/wasm-module-builder.js index 84362ff00f..ef716003d8 100644 --- a/test/mjsunit/wasm/wasm-module-builder.js +++ b/test/mjsunit/wasm/wasm-module-builder.js @@ -68,7 +68,8 @@ let kCodeSectionCode = 10; // Function code let kDataSectionCode = 11; // Data segments let kDataCountSectionCode = 12; // Data segment count (between Element & Code) let kTagSectionCode = 13; // Tag section (between Memory & Global) -let kLastKnownSectionCode = 13; +let kStringRefSectionCode = 14; // Stringref literals section (between Tag & Global) +let kLastKnownSectionCode = 14; // Name section types let kModuleNameCode = 0; @@ -126,7 +127,11 @@ let kWasmExternRef = kWasmAnyRef; // Alias for test backwards compatibility. let kWasmEqRef = -0x13; let kWasmI31Ref = -0x16; let kWasmDataRef = -0x19; -let kWasmArrayRef = -0x20; +let kWasmArrayRef = -0x1a; +let kWasmStringRef = -0x1b; +let kWasmStringViewWtf8 = -0x1c; +let kWasmStringViewWtf16 = -0x1d; +let kWasmStringViewIter = -0x1e; // Use the positive-byte versions inside function bodies. let kLeb128Mask = 0x7f; @@ -138,6 +143,10 @@ let kEqRefCode = kWasmEqRef & kLeb128Mask; let kI31RefCode = kWasmI31Ref & kLeb128Mask; let kDataRefCode = kWasmDataRef & kLeb128Mask; let kArrayRefCode = kWasmArrayRef & kLeb128Mask; +let kStringRefCode = kWasmStringRef & kLeb128Mask; +let kStringViewWtf8Code = kWasmStringViewWtf8 & kLeb128Mask; +let kStringViewWtf16Code = kWasmStringViewWtf16 & kLeb128Mask; +let kStringViewIterCode = kWasmStringViewIter & kLeb128Mask; let kWasmOptRef = 0x6c; let kWasmRef = 0x6b; @@ -523,6 +532,31 @@ let kExprBrOnNonFunc = 0x63; let kExprBrOnNonData = 0x64; let kExprBrOnNonI31 = 0x65; let kExprBrOnNonArray = 0x67; +let kStringNewWtf8 = 0x80; +let kStringNewWtf16 = 0x81; +let kStringConst = 0x82; +let kStringMeasureUtf8 = 0x83; +let kStringMeasureWtf8 = 0x84; +let kStringMeasureWtf16 = 0x85; +let kStringEncodeWtf8 = 0x86; +let kStringEncodeWtf16 = 0x87; +let kStringConcat = 0x88; +let kStringEq = 0x89; +let kStringIsUsvSequence = 0x8a; +let kStringAsWtf8 = 0x90; +let kStringViewWtf8Advance = 0x91; +let kStringViewWtf8Encode = 0x92; +let kStringViewWtf8Slice = 0x93; +let kStringAsWtf16 = 0x98; +let kStringViewWtf16Length = 0x99; +let kStringViewWtf16GetCodeunit = 0x9a; +let kStringViewWtf16Encode = 0x9b; +let kStringViewWtf16Slice = 0x9c; +let kStringAsIter = 0xa0; +let kStringViewIterCur = 0xa1 +let kStringViewIterAdvance = 0xa2; +let kStringViewIterRewind = 0xa3 +let kStringViewIterSlice = 0xa4; // Numeric opcodes. let kExprI32SConvertSatF32 = 0x00; @@ -1396,6 +1430,7 @@ class WasmModuleBuilder { this.types = []; this.imports = []; this.exports = []; + this.stringrefs = []; this.globals = []; this.tables = []; this.tags = []; @@ -1478,6 +1513,11 @@ class WasmModuleBuilder { return this.types.length - 1; } + addLiteralStringRef(str) { + this.stringrefs.push(str); + return this.stringrefs.length - 1; + } + addStruct(fields, supertype_idx = kNoSuperType) { this.types.push(new WasmStruct(fields, supertype_idx)); return this.types.length - 1; @@ -1901,6 +1941,17 @@ class WasmModuleBuilder { }); } + // Add stringref section. + if (wasm.stringrefs.length > 0) { + if (debug) print('emitting stringrefs @ ' + binary.length); + binary.emit_section(kStringRefSectionCode, section => { + section.emit_u32v(wasm.stringrefs.length); + for (let str of wasm.stringrefs) { + section.emit_string(str); + } + }); + } + // Add global section. if (wasm.globals.length > 0) { if (debug) print('emitting globals @ ' + binary.length);