Bug 1313024: Allow data sections to be displayed on several lines; r=luke

MozReview-Commit-ID: 2gBp7UAM4fF

--HG--
extra : rebase_source : 1f506c9d8f693396f000d38091055fe0a30ff9b6
extra : histedit_source : 20a88b42a8af3a93c2c8770e4bd48117156316b0
This commit is contained in:
Benjamin Bouvier 2016-10-26 16:44:47 +02:00
parent 9af34d5468
commit b1a0a1cb81
7 changed files with 92 additions and 41 deletions

View File

@ -701,15 +701,15 @@ class AstExport : public AstNode
class AstDataSegment : public AstNode class AstDataSegment : public AstNode
{ {
AstExpr* offset_; AstExpr* offset_;
AstName text_; AstNameVector fragments_;
public: public:
AstDataSegment(AstExpr* offset, AstName text) AstDataSegment(AstExpr* offset, AstNameVector&& fragments)
: offset_(offset), text_(text) : offset_(offset), fragments_(Move(fragments))
{} {}
AstExpr* offset() const { return offset_; } AstExpr* offset() const { return offset_; }
AstName text() const { return text_; } const AstNameVector& fragments() const { return fragments_; }
}; };
typedef AstVector<AstDataSegment*> AstDataSegmentVector; typedef AstVector<AstDataSegment*> AstDataSegmentVector;

View File

@ -2027,6 +2027,9 @@ AstDecodeCodeSection(AstDecodeContext &c)
return true; return true;
} }
// Number of bytes to display in a single fragment of a data section (per line).
static const size_t WRAP_DATA_BYTES = 30;
static bool static bool
AstDecodeDataSection(AstDecodeContext &c) AstDecodeDataSection(AstDecodeContext &c)
{ {
@ -2049,8 +2052,14 @@ AstDecodeDataSection(AstDecodeContext &c)
if (!offset) if (!offset)
return false; return false;
AstName name(buffer, s.length); AstNameVector fragments(c.lifo);
AstDataSegment* segment = new(c.lifo) AstDataSegment(offset, name); for (size_t start = 0; start < s.length; start += WRAP_DATA_BYTES) {
AstName name(buffer + start, Min(WRAP_DATA_BYTES, s.length - start));
if (!fragments.append(name))
return false;
}
AstDataSegment* segment = new(c.lifo) AstDataSegment(offset, Move(fragments));
if (!segment || !c.module().append(segment)) if (!segment || !c.module().append(segment))
return false; return false;
} }

View File

@ -1773,7 +1773,7 @@ PrintDataSection(WasmPrintContext& c, const AstModule& module)
const Limits& memory = module.memories()[0].limits; const Limits& memory = module.memories()[0].limits;
MOZ_ASSERT(memory.initial % PageSize == 0); MOZ_ASSERT(memory.initial % PageSize == 0);
if (!PrintInt32(c, memory.initial / PageSize)) if (!PrintInt32(c, memory.initial / PageSize))
return false; return false;
if (memory.maximum) { if (memory.maximum) {
MOZ_ASSERT(*memory.maximum % PageSize == 0); MOZ_ASSERT(*memory.maximum % PageSize == 0);
@ -1787,29 +1787,41 @@ PrintDataSection(WasmPrintContext& c, const AstModule& module)
uint32_t numSegments = module.dataSegments().length(); uint32_t numSegments = module.dataSegments().length();
if (!numSegments) { if (!numSegments) {
if (!c.buffer.append(" {}\n\n")) if (!c.buffer.append(" {}\n\n"))
return false; return false;
return true; return true;
} }
if (!c.buffer.append(" {\n")) if (!c.buffer.append(" {\n"))
return false; return false;
for (uint32_t i = 0; i < numSegments; i++) { for (uint32_t i = 0; i < numSegments; i++) {
const AstDataSegment* segment = module.dataSegments()[i]; const AstDataSegment* segment = module.dataSegments()[i];
if (!PrintIndent(c)) if (!PrintIndent(c))
return false; return false;
if (!c.buffer.append("segment ")) if (!c.buffer.append("segment "))
return false; return false;
if (!PrintInt32(c, segment->offset()->as<AstConst>().val().i32())) if (!PrintInt32(c, segment->offset()->as<AstConst>().val().i32()))
return false; return false;
if (!c.buffer.append(" \"")) if (!c.buffer.append("\n"))
return false; return false;
PrintEscapedString(c, segment->text()); c.indent++;
for (const AstName& fragment : segment->fragments()) {
if (!PrintIndent(c))
return false;
if (!c.buffer.append("\""))
return false;
if (!PrintEscapedString(c, fragment))
return false;
if (!c.buffer.append("\"\n"))
return false;
}
c.indent--;
if (!c.buffer.append("\";\n")) if (!PrintIndent(c))
return false; return false;
if (!c.buffer.append(";\n"))
return false;
} }
c.indent--; c.indent--;

View File

@ -1630,11 +1630,25 @@ RenderDataSection(WasmRenderContext& c, const AstModule& module)
return false; return false;
if (!RenderInlineExpr(c, *seg->offset())) if (!RenderInlineExpr(c, *seg->offset()))
return false; return false;
if (!c.buffer.append(" \"")) if (!c.buffer.append("\n"))
return false; return false;
if (!RenderEscapedString(c, seg->text()))
c.indent++;
for (const AstName& fragment : seg->fragments()) {
if (!RenderIndent(c))
return false;
if (!c.buffer.append("\""))
return false;
if (!RenderEscapedString(c, fragment))
return false;
if (!c.buffer.append("\"\n"))
return false;
}
c.indent--;
if (!RenderIndent(c))
return false; return false;
if (!c.buffer.append("\")\n")) if (!c.buffer.append(")\n"))
return false; return false;
} }

View File

@ -2738,11 +2738,15 @@ ParseDataSegment(WasmParseContext& c)
if (!offset) if (!offset)
return nullptr; return nullptr;
WasmToken text; AstNameVector fragments(c.lifo);
if (!c.ts.getIf(WasmToken::Text, &text))
return new(c.lifo) AstDataSegment(offset, AstName());
return new(c.lifo) AstDataSegment(offset, text.text()); WasmToken text;
while (c.ts.getIf(WasmToken::Text, &text)) {
if (!fragments.append(text.text()))
return nullptr;
}
return new(c.lifo) AstDataSegment(offset, Move(fragments));
} }
static bool static bool
@ -2800,18 +2804,27 @@ ParseMemory(WasmParseContext& c, WasmToken token, AstModule* module)
if (!c.ts.match(WasmToken::Data, c.error)) if (!c.ts.match(WasmToken::Data, c.error))
return false; return false;
WasmToken text; AstNameVector fragments(c.lifo);
WasmToken data;
size_t pages = 0; size_t pages = 0;
if (c.ts.getIf(WasmToken::Text, &text)) { size_t totalLength = 0;
while (c.ts.getIf(WasmToken::Text, &data)) {
if (!fragments.append(data.text()))
return false;
totalLength += data.text().length();
}
if (fragments.length()) {
AstExpr* offset = new(c.lifo) AstConst(Val(uint32_t(0))); AstExpr* offset = new(c.lifo) AstConst(Val(uint32_t(0)));
if (!offset) if (!offset)
return false; return false;
AstDataSegment* segment = new(c.lifo) AstDataSegment(offset, text.text()); AstDataSegment* segment = new(c.lifo) AstDataSegment(offset, Move(fragments));
if (!segment || !module->append(segment)) if (!segment || !module->append(segment))
return false; return false;
pages = AlignBytes<size_t>(segment->text().length(), PageSize) / PageSize; pages = AlignBytes<size_t>(totalLength, PageSize) / PageSize;
if (pages != uint32_t(pages)) if (pages != uint32_t(pages))
return false; return false;
} }
@ -4621,18 +4634,22 @@ EncodeDataSegment(Encoder& e, AstDataSegment& segment)
if (!e.writeExpr(Expr::End)) if (!e.writeExpr(Expr::End))
return false; return false;
AstName text = segment.text(); size_t totalLength = 0;
for (const AstName& fragment : segment.fragments())
totalLength += fragment.length();
Vector<uint8_t, 0, SystemAllocPolicy> bytes; Vector<uint8_t, 0, SystemAllocPolicy> bytes;
if (!bytes.reserve(text.length())) if (!bytes.reserve(totalLength))
return false; return false;
const char16_t* cur = text.begin(); for (const AstName& fragment : segment.fragments()) {
const char16_t* end = text.end(); const char16_t* cur = fragment.begin();
while (cur != end) { const char16_t* end = fragment.end();
uint8_t byte; while (cur != end) {
MOZ_ALWAYS_TRUE(ConsumeTextByte(&cur, end, &byte)); uint8_t byte;
bytes.infallibleAppend(byte); MOZ_ALWAYS_TRUE(ConsumeTextByte(&cur, end, &byte));
bytes.infallibleAppend(byte);
}
} }
if (!e.writeBytes(bytes.begin(), bytes.length())) if (!e.writeBytes(bytes.begin(), bytes.length()))

View File

@ -45,12 +45,13 @@ wasmFullPass(`(module
// Memory. // Memory.
wasmFullPass(`(module wasmFullPass(`(module
(memory (export "memory") 1 2) (memory (export "memory") 1 2)
(data (i32.const 0) "\\00\\01\\02\\03\\04\\05") (data (i32.const 0) "\\00\\01\\02" "\\03\\04\\05")
(data (i32.const 6) "\\06")
(func (export "run") (result i32) (func (export "run") (result i32)
i32.const 1 i32.const 1
i32.load offset=2 i32.load offset=2
) )
)`, 0x050403); )`, 0x06050403);
let memory = new WebAssembly.Memory({ initial: 1, maximum: 2 }); let memory = new WebAssembly.Memory({ initial: 1, maximum: 2 });

View File

@ -1,4 +1,2 @@
// |jit-test| test-also-wasm-baseline // |jit-test| test-also-wasm-baseline
// TODO parse error (memory data on several lines)
quit();
var importedArgs = ['float_exprs.wast']; load(scriptdir + '../spec.js'); var importedArgs = ['float_exprs.wast']; load(scriptdir + '../spec.js');