Index: src/wasm/wasm-module-builder.cc |
diff --git a/src/wasm/wasm-module-builder.cc b/src/wasm/wasm-module-builder.cc |
index 3efcb090aa62796aafb82473775f4a4aa4e08b74..ab76efe5f8b8837811558657c1dab64556497f78 100644 |
--- a/src/wasm/wasm-module-builder.cc |
+++ b/src/wasm/wasm-module-builder.cc |
@@ -59,7 +59,8 @@ WasmFunctionBuilder::WasmFunctionBuilder(WasmModuleBuilder* builder) |
i64_temps_(builder->zone()), |
f32_temps_(builder->zone()), |
f64_temps_(builder->zone()), |
- direct_calls_(builder->zone()) {} |
+ direct_calls_(builder->zone()), |
+ asm_offsets_(builder->zone(), 8) {} |
void WasmFunctionBuilder::EmitVarInt(uint32_t val) { |
byte buffer[8]; |
@@ -153,6 +154,20 @@ void WasmFunctionBuilder::SetName(Vector<const char> name) { |
memcpy(name_.data(), name.start(), name.length()); |
} |
+void WasmFunctionBuilder::AddAsmWasmOffset(int asm_position) { |
+ // We only want to emit one mapping per byte offset: |
+ DCHECK(asm_offsets_.size() == 0 || body_.size() > last_asm_byte_offset_); |
+ |
+ DCHECK_LE(body_.size(), kMaxUInt32); |
+ uint32_t byte_offset = static_cast<uint32_t>(body_.size()); |
+ asm_offsets_.write_u32v(byte_offset - last_asm_byte_offset_); |
+ last_asm_byte_offset_ = byte_offset; |
+ |
+ DCHECK_GE(asm_position, 0); |
+ asm_offsets_.write_i32v(asm_position - last_asm_source_position_); |
+ last_asm_source_position_ = asm_position; |
+} |
+ |
void WasmFunctionBuilder::WriteSignature(ZoneBuffer& buffer) const { |
buffer.write_u32v(signature_index_); |
} |
@@ -188,6 +203,18 @@ void WasmFunctionBuilder::WriteBody(ZoneBuffer& buffer) const { |
} |
} |
+void WasmFunctionBuilder::WriteAsmWasmOffsetTable(ZoneBuffer& buffer) const { |
+ if (asm_offsets_.size() == 0) { |
+ buffer.write_size(0); |
+ return; |
+ } |
+ buffer.write_size(asm_offsets_.size() + kInt32Size); |
+ // Offset of the recorded byte offsets. |
+ DCHECK_GE(kMaxUInt32, locals_.Size()); |
+ buffer.write_u32(static_cast<uint32_t>(locals_.Size())); |
+ buffer.write(asm_offsets_.begin(), asm_offsets_.size()); |
+} |
+ |
WasmModuleBuilder::WasmModuleBuilder(Zone* zone) |
: zone_(zone), |
signatures_(zone), |
@@ -309,6 +336,7 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const { |
// == Emit function signatures =============================================== |
bool has_names = false; |
+ bool has_asm_offsets = false; |
if (functions_.size() > 0) { |
size_t start = EmitSection(kFunctionSectionCode, buffer); |
buffer.write_size(functions_.size()); |
@@ -316,6 +344,7 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const { |
function->WriteSignature(buffer); |
if (function->exported()) exports++; |
if (function->name_.size() > 0) has_names = true; |
+ if (function->asm_offsets_.size() > 0) has_asm_offsets = true; |
} |
FixupSection(buffer, start); |
} |
@@ -493,6 +522,25 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const { |
} |
FixupSection(buffer, start); |
} |
+ |
+ // == Emit asm.js offset table =============================================== |
+ if (has_asm_offsets) { |
+ // Emit the section code. |
+ buffer.write_u8(kUnknownSectionCode); |
+ // Emit a placeholder for the length. |
+ size_t start = buffer.reserve_u32v(); |
+ // Emit the section string. |
+ const char* asm_offsets_name = "asm_offsets"; |
+ buffer.write_size(strlen(asm_offsets_name)); |
+ buffer.write(reinterpret_cast<const byte*>(asm_offsets_name), |
+ strlen(asm_offsets_name)); |
+ buffer.write_size(functions_.size()); |
+ // Emit the offset table per function. |
+ for (auto function : functions_) { |
+ function->WriteAsmWasmOffsetTable(buffer); |
+ } |
+ FixupSection(buffer, start); |
+ } |
} |
} // namespace wasm |
} // namespace internal |