Index: src/wasm/wasm-module.cc |
diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc |
index 76287ac6a2e607cf98966dd5a7589f28a7fa6717..4d5dc7e7ddcd5c1e5c0531da0ca5d71324dfd0f5 100644 |
--- a/src/wasm/wasm-module.cc |
+++ b/src/wasm/wasm-module.cc |
@@ -90,7 +90,7 @@ enum WasmGlobalInitData { |
}; |
enum WasmSegmentInfo { |
- kDestInitKind, // 0 = constant, 1 = global index |
+ kDestAddrKind, // 0 = constant, 1 = global index |
kDestAddrValue, // Smi. an uint32_t |
kSourceSize, // Smi. an uint32_t |
kWasmSegmentInfoSize // Sentinel value. |
@@ -127,9 +127,18 @@ void SaveDataSegmentInfo(Factory* factory, const WasmModule* module, |
if (segment.source_size == 0) continue; |
Handle<ByteArray> js_segment = |
factory->NewByteArray(kWasmSegmentInfoSize * sizeof(uint32_t), TENURED); |
- // TODO(titzer): add support for global offsets for dest_addr |
- CHECK_EQ(WasmInitExpr::kI32Const, segment.dest_addr.kind); |
- js_segment->set_int(kDestAddrValue, segment.dest_addr.val.i32_const); |
+ if (segment.dest_addr.kind == WasmInitExpr::kGlobalIndex) { |
+ // The destination address is the value of a global variable. |
+ js_segment->set_int(kDestAddrKind, 1); |
+ uint32_t offset = |
+ module->globals[segment.dest_addr.val.global_index].offset; |
+ js_segment->set_int(kDestAddrValue, static_cast<int>(offset)); |
+ } else { |
+ // The destination address is a constant. |
+ CHECK_EQ(WasmInitExpr::kI32Const, segment.dest_addr.kind); |
+ js_segment->set_int(kDestAddrKind, 0); |
+ js_segment->set_int(kDestAddrValue, segment.dest_addr.val.i32_const); |
+ } |
js_segment->set_int(kSourceSize, segment.source_size); |
segments->set(i, *js_segment); |
data->copy_in(last_insertion_pos, |
@@ -1276,6 +1285,11 @@ class WasmInstanceBuilder { |
if (num_imported_functions < 0) return nothing; |
//-------------------------------------------------------------------------- |
+ // Process the initialization for the module's globals. |
+ //-------------------------------------------------------------------------- |
+ ProcessInits(globals); |
+ |
+ //-------------------------------------------------------------------------- |
// Set up the memory for the new instance. |
//-------------------------------------------------------------------------- |
MaybeHandle<JSArrayBuffer> old_memory; |
@@ -1295,7 +1309,7 @@ class WasmInstanceBuilder { |
Address mem_start = static_cast<Address>(memory_->backing_store()); |
uint32_t mem_size = |
static_cast<uint32_t>(memory_->byte_length()->Number()); |
- LoadDataSegments(mem_start, mem_size); |
+ LoadDataSegments(globals, mem_start, mem_size); |
uint32_t old_mem_size = compiled_module_->has_heap() |
? compiled_module_->mem_size() |
@@ -1310,11 +1324,6 @@ class WasmInstanceBuilder { |
} |
//-------------------------------------------------------------------------- |
- // Process the initialization for the module's globals. |
- //-------------------------------------------------------------------------- |
- ProcessInits(globals); |
- |
- //-------------------------------------------------------------------------- |
// Set up the runtime support for the new instance. |
//-------------------------------------------------------------------------- |
Handle<WeakCell> weak_link = factory->NewWeakCell(instance); |
@@ -1502,7 +1511,8 @@ class WasmInstanceBuilder { |
} |
// Load data segments into the memory. |
- void LoadDataSegments(Address mem_addr, size_t mem_size) { |
+ void LoadDataSegments(MaybeHandle<JSArrayBuffer> globals, Address mem_addr, |
+ size_t mem_size) { |
CHECK(compiled_module_->has_data_segments() == |
compiled_module_->has_data_segments_info()); |
@@ -1518,6 +1528,12 @@ class WasmInstanceBuilder { |
Handle<ByteArray>(ByteArray::cast(segments->get(i))); |
uint32_t dest_addr = |
static_cast<uint32_t>(segment->get_int(kDestAddrValue)); |
+ if (segment->get_int(kDestAddrKind) == 1) { |
+ // The destination address is the value of a global variable. |
+ dest_addr = |
+ *reinterpret_cast<uint32_t*>(raw_buffer_ptr(globals, dest_addr)); |
+ } |
+ |
uint32_t source_size = |
static_cast<uint32_t>(segment->get_int(kSourceSize)); |
CHECK_LT(dest_addr, mem_size); |