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
{
AstExpr* offset_;
AstName text_;
AstNameVector fragments_;
public:
AstDataSegment(AstExpr* offset, AstName text)
: offset_(offset), text_(text)
AstDataSegment(AstExpr* offset, AstNameVector&& fragments)
: offset_(offset), fragments_(Move(fragments))
{}
AstExpr* offset() const { return offset_; }
AstName text() const { return text_; }
const AstNameVector& fragments() const { return fragments_; }
};
typedef AstVector<AstDataSegment*> AstDataSegmentVector;

View File

@ -2027,6 +2027,9 @@ AstDecodeCodeSection(AstDecodeContext &c)
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
AstDecodeDataSection(AstDecodeContext &c)
{
@ -2049,8 +2052,14 @@ AstDecodeDataSection(AstDecodeContext &c)
if (!offset)
return false;
AstName name(buffer, s.length);
AstDataSegment* segment = new(c.lifo) AstDataSegment(offset, name);
AstNameVector fragments(c.lifo);
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))
return false;
}

View File

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

View File

@ -1630,11 +1630,25 @@ RenderDataSection(WasmRenderContext& c, const AstModule& module)
return false;
if (!RenderInlineExpr(c, *seg->offset()))
return false;
if (!c.buffer.append(" \""))
if (!c.buffer.append("\n"))
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;
if (!c.buffer.append("\")\n"))
if (!c.buffer.append(")\n"))
return false;
}

View File

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

View File

@ -45,12 +45,13 @@ wasmFullPass(`(module
// Memory.
wasmFullPass(`(module
(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)
i32.const 1
i32.load offset=2
)
)`, 0x050403);
)`, 0x06050403);
let memory = new WebAssembly.Memory({ initial: 1, maximum: 2 });

View File

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