Commit 29cd25be authored by binji's avatar binji Committed by Commit bot

[Wasm] Move data segment data inline to the data segment section

BUG=
R=titzer@chromium.org

Review URL: https://codereview.chromium.org/1776923005

Cr-Commit-Position: refs/heads/master@{#34639}
parent 48f9c161
......@@ -376,14 +376,11 @@ uint32_t WasmDataSegmentEncoder::BodySize() const {
void WasmDataSegmentEncoder::Serialize(byte* buffer, byte** header,
byte** body) const {
uint32_t body_offset = static_cast<uint32_t>(*body - buffer);
EmitUint32(header, dest_);
EmitUint32(header, body_offset);
EmitUint32(header, static_cast<uint32_t>(data_.size()));
EmitUint8(header, 1); // init
std::memcpy(*body, &data_[0], data_.size());
(*body) += data_.size();
EmitVarInt(header, dest_);
EmitVarInt(header, static_cast<uint32_t>(data_.size()));
std::memcpy(*header, &data_[0], data_.size());
(*header) += data_.size();
}
WasmModuleBuilder::WasmModuleBuilder(Zone* zone)
......
......@@ -445,16 +445,18 @@ class ModuleDecoder : public Decoder {
// Decodes a single data segment entry inside a module starting at {pc_}.
void DecodeDataSegmentInModule(WasmModule* module, WasmDataSegment* segment) {
segment->dest_addr = consume_u32("destination");
segment->source_offset = consume_offset("source offset");
segment->source_size = consume_u32("source size");
segment->init = consume_u8("init");
const byte* start = pc_;
int length;
segment->dest_addr = consume_u32v(&length, "destination");
segment->source_size = consume_u32v(&length, "source size");
segment->source_offset = static_cast<uint32_t>(pc_ - start_);
segment->init = true;
// Validate the data is in the module.
uint32_t module_limit = static_cast<uint32_t>(limit_ - start_);
if (!IsWithinLimit(module_limit, segment->source_offset,
segment->source_size)) {
error(pc_ - sizeof(uint32_t), "segment out of bounds of module");
error(start, "segment out of bounds of module");
}
// Validate that the segment will fit into the (minimum) memory.
......@@ -463,8 +465,10 @@ class ModuleDecoder : public Decoder {
: WasmModule::kMaxMemPages);
if (!IsWithinLimit(memory_limit, segment->dest_addr,
segment->source_size)) {
error(pc_ - sizeof(uint32_t), "segment out of bounds of memory");
error(start, "segment out of bounds of memory");
}
consume_bytes(segment->source_size);
}
// Verifies the body (code) of a given function.
......
......@@ -2,11 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function DataRef(data) {
this.pos = -1;
this.data = data;
}
function WasmFunctionBuilder(name, sig_index) {
this.name = name;
this.sig_index = sig_index;
......@@ -118,13 +113,6 @@ function emit_string(bytes, string) {
}
}
function emit_data_ref(bytes, string) {
bytes.push(new DataRef(string));
bytes.push(0);
bytes.push(0);
bytes.push(0);
}
function emit_varint(bytes, val) {
while (true) {
var v = val & 0xff;
......@@ -269,10 +257,11 @@ WasmModuleBuilder.prototype.toArray = function(debug) {
emit_u8(bytes, kDeclDataSegments);
emit_varint(bytes, this.data_segments.length);
for (seg of this.data_segments) {
emit_u32(bytes, seg.addr);
emit_data_ref(bytes, seg.data);
emit_u32(bytes, seg.data.length);
emit_u8(bytes, seg.init ? 1 : 0);
emit_varint(bytes, seg.addr);
emit_varint(bytes, seg.data.length);
for (var i = 0; i < seg.data.length; i++) {
emit_u8(bytes, seg.data[i]);
}
}
}
......@@ -288,39 +277,6 @@ WasmModuleBuilder.prototype.toArray = function(debug) {
if (debug) print("emitting end @ " + bytes.length);
emit_u8(bytes, kDeclEnd);
// Collect references.
var strings = new Object();
var data_segments = [];
var count = 0;
for (var i = 0; i < bytes.length; i++) {
var b = bytes[i];
if (b instanceof DataRef) {
data_segments.push(b);
count++;
}
}
if (count > 0) {
// Emit data.
if (debug) print("emitting data @ " + bytes.length);
for (ref of data_segments) {
ref.pos = bytes.length;
for (var i = 0; i < ref.data.length; i++) {
emit_u8(bytes, ref.data[i]);
}
}
// Update references to strings and data.
for (var i = 0; i < bytes.length; i++) {
var b = bytes[i];
if (b instanceof DataRef) {
bytes[i] = b.pos & 0xFF;
bytes[i + 1] = (b.pos >> 8) & 0xFF;
bytes[i + 2] = (b.pos >> 16) & 0xFF;
bytes[i + 3] = (b.pos >> 24) & 0xFF;
}
}
}
return bytes;
}
......
......@@ -456,6 +456,7 @@ TEST_F(WasmModuleVerifyTest, OneFunctionWithNopBody_WithLocals) {
TEST_F(WasmModuleVerifyTest, OneGlobalOneFunctionWithNopBodyOneDataSegment) {
static const byte kCodeStartOffset = 8 + 4 + 5 + 4 + 18;
static const byte kCodeEndOffset = kCodeStartOffset + 3;
static const byte kDataSegmentSourceOffset = kCodeEndOffset + 6;
static const byte data[] = {
kDeclMemory, 28, 28, 1,
......@@ -478,10 +479,9 @@ TEST_F(WasmModuleVerifyTest, OneGlobalOneFunctionWithNopBodyOneDataSegment) {
kExprNop, // func#0 body
kExprNop, // func#0 body
// segment#0 -------------------------------------------------
kDeclDataSegments, 1, 0xae, 0xb3, 0x08, 0, // dest addr
15, 0, 0, 0, // source offset
5, 0, 0, 0, // source size
1, // init
kDeclDataSegments, 1, U32V_3(0x8b3ae), // dest addr
U32V_1(5), // source size
0, 1, 2, 3, 4, // data bytes
// rest ------------------------------------------------------
kDeclEnd,
};
......@@ -513,7 +513,7 @@ TEST_F(WasmModuleVerifyTest, OneGlobalOneFunctionWithNopBodyOneDataSegment) {
WasmDataSegment* segment = &result.val->data_segments.back();
EXPECT_EQ(0x8b3ae, segment->dest_addr);
EXPECT_EQ(15, segment->source_offset);
EXPECT_EQ(kDataSegmentSourceOffset, segment->source_offset);
EXPECT_EQ(5, segment->source_size);
EXPECT_TRUE(segment->init);
......@@ -523,14 +523,13 @@ TEST_F(WasmModuleVerifyTest, OneGlobalOneFunctionWithNopBodyOneDataSegment) {
TEST_F(WasmModuleVerifyTest, OneDataSegment) {
const byte kDataSegmentSourceOffset = 8 + 10;
const byte data[] = {
kDeclMemory, 28, 28, 1, kDeclDataSegments, 1, 0xaa, 0xbb, 0x09,
0, // dest addr
11, 0, 0,
0, // source offset
3, 0, 0,
0, // source size
1, // init
kDeclMemory, 28, 28, 1,
kDeclDataSegments, 1,
U32V_3(0x9bbaa), // dest addr
U32V_1(3), // source size
'a', 'b', 'c' // data bytes
};
{
......@@ -544,7 +543,7 @@ TEST_F(WasmModuleVerifyTest, OneDataSegment) {
WasmDataSegment* segment = &result.val->data_segments.back();
EXPECT_EQ(0x9bbaa, segment->dest_addr);
EXPECT_EQ(11, segment->source_offset);
EXPECT_EQ(kDataSegmentSourceOffset, segment->source_offset);
EXPECT_EQ(3, segment->source_size);
EXPECT_TRUE(segment->init);
......@@ -556,21 +555,18 @@ TEST_F(WasmModuleVerifyTest, OneDataSegment) {
TEST_F(WasmModuleVerifyTest, TwoDataSegments) {
const byte kDataSegment0SourceOffset = 8 + 10;
const byte kDataSegment1SourceOffset = 8 + 10 + 8;
const byte data[] = {
kDeclMemory, 28, 28, 1, kDeclDataSegments, 2, 0xee, 0xff, 0x07,
0, // dest addr
9, 0, 0,
0, // #0: source offset
4, 0, 0,
0, // source size
0, // init
0xcc, 0xdd, 0x06,
0, // #1: dest addr
6, 0, 0,
0, // source offset
10, 0, 0,
0, // source size
1, // init
kDeclMemory, 28, 28, 1,
kDeclDataSegments, 2,
U32V_3(0x7ffee), // #0: dest addr
U32V_1(4), // source size
1, 2, 3, 4, // data bytes
U32V_3(0x6ddcc), // #1: dest addr
U32V_1(10), // source size
1, 2, 3, 4, 5, 6, 7, 8, 9, 10 // data bytes
};
{
......@@ -584,12 +580,12 @@ TEST_F(WasmModuleVerifyTest, TwoDataSegments) {
WasmDataSegment* s1 = &result.val->data_segments[1];
EXPECT_EQ(0x7ffee, s0->dest_addr);
EXPECT_EQ(9, s0->source_offset);
EXPECT_EQ(kDataSegment0SourceOffset, s0->source_offset);
EXPECT_EQ(4, s0->source_size);
EXPECT_FALSE(s0->init);
EXPECT_TRUE(s0->init);
EXPECT_EQ(0x6ddcc, s1->dest_addr);
EXPECT_EQ(6, s1->source_offset);
EXPECT_EQ(kDataSegment1SourceOffset, s1->source_offset);
EXPECT_EQ(10, s1->source_size);
EXPECT_TRUE(s1->init);
......@@ -600,44 +596,8 @@ TEST_F(WasmModuleVerifyTest, TwoDataSegments) {
}
TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidSource) {
const int dest_addr = 0x100;
const byte mem_pages = 1;
const int kHeaderSize = 8;
const int kDataSize = 19;
const int kTotalSize = kHeaderSize + kDataSize;
for (int source_offset = 0; source_offset < 5 + kDataSize; source_offset++) {
for (int source_size = -1; source_size < 5 + kDataSize; source_size += 3) {
byte data[] = {
kDeclMemory,
mem_pages,
mem_pages,
1,
kDeclDataSegments,
1,
U32_LE(dest_addr),
U32_LE(source_offset),
U32_LE(source_size),
1, // init
};
STATIC_ASSERT(kDataSize == arraysize(data));
if (source_offset < kTotalSize && source_size >= 0 &&
(source_offset + source_size) <= kTotalSize) {
EXPECT_VERIFIES(data);
} else {
EXPECT_FAILURE(data);
}
}
}
}
TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidDest) {
const int source_size = 3;
const int source_offset = 11;
for (byte mem_pages = 1; mem_pages < 16; mem_pages++) {
int mem_size = mem_pages * 0x10000; // 64k pages.
......@@ -651,10 +611,9 @@ TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidDest) {
1,
kDeclDataSegments,
1,
U32_LE(dest_addr),
U32_LE(source_offset),
U32_LE(source_size),
1, // init
U32V_3(dest_addr),
U32V_1(source_size),
'a', 'b', 'c'
};
if (dest_addr <= (mem_size - source_size)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment