| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/signature.h" | 5 #include "src/signature.h" |
| 6 | 6 |
| 7 #include "src/handles.h" | 7 #include "src/handles.h" |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 #include "src/zone/zone-containers.h" | 9 #include "src/zone/zone-containers.h" |
| 10 | 10 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 // Patch the size of a section after it's finished. | 43 // Patch the size of a section after it's finished. |
| 44 void FixupSection(ZoneBuffer& buffer, size_t start) { | 44 void FixupSection(ZoneBuffer& buffer, size_t start) { |
| 45 buffer.patch_u32v(start, static_cast<uint32_t>(buffer.offset() - start - | 45 buffer.patch_u32v(start, static_cast<uint32_t>(buffer.offset() - start - |
| 46 kPaddedVarInt32Size)); | 46 kPaddedVarInt32Size)); |
| 47 } | 47 } |
| 48 | 48 |
| 49 WasmFunctionBuilder::WasmFunctionBuilder(WasmModuleBuilder* builder) | 49 WasmFunctionBuilder::WasmFunctionBuilder(WasmModuleBuilder* builder) |
| 50 : builder_(builder), | 50 : builder_(builder), |
| 51 locals_(builder->zone()), | 51 locals_(builder->zone()), |
| 52 signature_index_(0), | 52 signature_index_(0), |
| 53 exported_(0), | |
| 54 func_index_(static_cast<uint32_t>(builder->functions_.size())), | 53 func_index_(static_cast<uint32_t>(builder->functions_.size())), |
| 55 body_(builder->zone()), | 54 body_(builder->zone()), |
| 56 name_(builder->zone()), | 55 name_(builder->zone()), |
| 57 exported_name_(builder->zone()), | 56 exported_names_(builder->zone()), |
| 58 i32_temps_(builder->zone()), | 57 i32_temps_(builder->zone()), |
| 59 i64_temps_(builder->zone()), | 58 i64_temps_(builder->zone()), |
| 60 f32_temps_(builder->zone()), | 59 f32_temps_(builder->zone()), |
| 61 f64_temps_(builder->zone()), | 60 f64_temps_(builder->zone()), |
| 62 direct_calls_(builder->zone()), | 61 direct_calls_(builder->zone()), |
| 63 asm_offsets_(builder->zone(), 8) {} | 62 asm_offsets_(builder->zone(), 8) {} |
| 64 | 63 |
| 65 void WasmFunctionBuilder::EmitVarInt(uint32_t val) { | 64 void WasmFunctionBuilder::EmitVarInt(uint32_t val) { |
| 66 byte buffer[8]; | 65 byte buffer[8]; |
| 67 byte* ptr = buffer; | 66 byte* ptr = buffer; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 | 133 |
| 135 void WasmFunctionBuilder::EmitDirectCallIndex(uint32_t index) { | 134 void WasmFunctionBuilder::EmitDirectCallIndex(uint32_t index) { |
| 136 DirectCallIndex call; | 135 DirectCallIndex call; |
| 137 call.offset = body_.size(); | 136 call.offset = body_.size(); |
| 138 call.direct_index = index; | 137 call.direct_index = index; |
| 139 direct_calls_.push_back(call); | 138 direct_calls_.push_back(call); |
| 140 byte code[] = {U32V_5(0)}; | 139 byte code[] = {U32V_5(0)}; |
| 141 EmitCode(code, sizeof(code)); | 140 EmitCode(code, sizeof(code)); |
| 142 } | 141 } |
| 143 | 142 |
| 144 void WasmFunctionBuilder::Export() { exported_ = true; } | |
| 145 | |
| 146 void WasmFunctionBuilder::ExportAs(Vector<const char> name) { | 143 void WasmFunctionBuilder::ExportAs(Vector<const char> name) { |
| 147 exported_ = true; | 144 exported_names_.push_back(ZoneVector<char>( |
| 148 exported_name_.resize(name.length()); | 145 name.start(), name.start() + name.length(), builder_->zone())); |
| 149 memcpy(exported_name_.data(), name.start(), name.length()); | |
| 150 } | 146 } |
| 151 | 147 |
| 152 void WasmFunctionBuilder::SetName(Vector<const char> name) { | 148 void WasmFunctionBuilder::SetName(Vector<const char> name) { |
| 153 name_.resize(name.length()); | 149 name_.resize(name.length()); |
| 154 memcpy(name_.data(), name.start(), name.length()); | 150 memcpy(name_.data(), name.start(), name.length()); |
| 155 } | 151 } |
| 156 | 152 |
| 157 void WasmFunctionBuilder::AddAsmWasmOffset(int asm_position) { | 153 void WasmFunctionBuilder::AddAsmWasmOffset(int asm_position) { |
| 158 // We only want to emit one mapping per byte offset: | 154 // We only want to emit one mapping per byte offset: |
| 159 DCHECK(asm_offsets_.size() == 0 || body_.size() > last_asm_byte_offset_); | 155 DCHECK(asm_offsets_.size() == 0 || body_.size() > last_asm_byte_offset_); |
| 160 | 156 |
| 161 DCHECK_LE(body_.size(), kMaxUInt32); | 157 DCHECK_LE(body_.size(), kMaxUInt32); |
| 162 uint32_t byte_offset = static_cast<uint32_t>(body_.size()); | 158 uint32_t byte_offset = static_cast<uint32_t>(body_.size()); |
| 163 asm_offsets_.write_u32v(byte_offset - last_asm_byte_offset_); | 159 asm_offsets_.write_u32v(byte_offset - last_asm_byte_offset_); |
| 164 last_asm_byte_offset_ = byte_offset; | 160 last_asm_byte_offset_ = byte_offset; |
| 165 | 161 |
| 166 DCHECK_GE(asm_position, 0); | 162 DCHECK_GE(asm_position, 0); |
| 167 asm_offsets_.write_i32v(asm_position - last_asm_source_position_); | 163 asm_offsets_.write_i32v(asm_position - last_asm_source_position_); |
| 168 last_asm_source_position_ = asm_position; | 164 last_asm_source_position_ = asm_position; |
| 169 } | 165 } |
| 170 | 166 |
| 171 void WasmFunctionBuilder::WriteSignature(ZoneBuffer& buffer) const { | 167 void WasmFunctionBuilder::WriteSignature(ZoneBuffer& buffer) const { |
| 172 buffer.write_u32v(signature_index_); | 168 buffer.write_u32v(signature_index_); |
| 173 } | 169 } |
| 174 | 170 |
| 175 void WasmFunctionBuilder::WriteExport(ZoneBuffer& buffer) const { | 171 void WasmFunctionBuilder::WriteExports(ZoneBuffer& buffer) const { |
| 176 if (exported_) { | 172 for (auto name : exported_names_) { |
| 177 const ZoneVector<char>* exported_name = | 173 buffer.write_size(name.size()); |
| 178 exported_name_.size() == 0 ? &name_ : &exported_name_; | 174 buffer.write(reinterpret_cast<const byte*>(name.data()), name.size()); |
| 179 buffer.write_size(exported_name->size()); | |
| 180 buffer.write(reinterpret_cast<const byte*>(exported_name->data()), | |
| 181 exported_name->size()); | |
| 182 buffer.write_u8(kExternalFunction); | 175 buffer.write_u8(kExternalFunction); |
| 183 buffer.write_u32v(func_index_ + | 176 buffer.write_u32v(func_index_ + |
| 184 static_cast<uint32_t>(builder_->imports_.size())); | 177 static_cast<uint32_t>(builder_->imports_.size())); |
| 185 } | 178 } |
| 186 } | 179 } |
| 187 | 180 |
| 188 void WasmFunctionBuilder::WriteBody(ZoneBuffer& buffer) const { | 181 void WasmFunctionBuilder::WriteBody(ZoneBuffer& buffer) const { |
| 189 size_t locals_size = locals_.Size(); | 182 size_t locals_size = locals_.Size(); |
| 190 buffer.write_size(locals_size + body_.size()); | 183 buffer.write_size(locals_size + body_.size()); |
| 191 buffer.EnsureSpace(locals_size); | 184 buffer.EnsureSpace(locals_size); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 FixupSection(buffer, start); | 334 FixupSection(buffer, start); |
| 342 } | 335 } |
| 343 | 336 |
| 344 // == Emit function signatures =============================================== | 337 // == Emit function signatures =============================================== |
| 345 bool has_names = false; | 338 bool has_names = false; |
| 346 if (functions_.size() > 0) { | 339 if (functions_.size() > 0) { |
| 347 size_t start = EmitSection(kFunctionSectionCode, buffer); | 340 size_t start = EmitSection(kFunctionSectionCode, buffer); |
| 348 buffer.write_size(functions_.size()); | 341 buffer.write_size(functions_.size()); |
| 349 for (auto function : functions_) { | 342 for (auto function : functions_) { |
| 350 function->WriteSignature(buffer); | 343 function->WriteSignature(buffer); |
| 351 if (function->exported()) exports++; | 344 exports += function->exported_names_.size(); |
| 352 if (function->name_.size() > 0) has_names = true; | 345 if (function->name_.size() > 0) has_names = true; |
| 353 } | 346 } |
| 354 FixupSection(buffer, start); | 347 FixupSection(buffer, start); |
| 355 } | 348 } |
| 356 | 349 |
| 357 // == emit function table ==================================================== | 350 // == emit function table ==================================================== |
| 358 if (indirect_functions_.size() > 0) { | 351 if (indirect_functions_.size() > 0) { |
| 359 size_t start = EmitSection(kTableSectionCode, buffer); | 352 size_t start = EmitSection(kTableSectionCode, buffer); |
| 360 buffer.write_u8(1); // table count | 353 buffer.write_u8(1); // table count |
| 361 buffer.write_u8(kWasmAnyFunctionTypeForm); | 354 buffer.write_u8(kWasmAnyFunctionTypeForm); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 } | 437 } |
| 445 buffer.write_u8(kExprEnd); | 438 buffer.write_u8(kExprEnd); |
| 446 } | 439 } |
| 447 FixupSection(buffer, start); | 440 FixupSection(buffer, start); |
| 448 } | 441 } |
| 449 | 442 |
| 450 // == emit exports =========================================================== | 443 // == emit exports =========================================================== |
| 451 if (exports > 0) { | 444 if (exports > 0) { |
| 452 size_t start = EmitSection(kExportSectionCode, buffer); | 445 size_t start = EmitSection(kExportSectionCode, buffer); |
| 453 buffer.write_u32v(exports); | 446 buffer.write_u32v(exports); |
| 454 for (auto function : functions_) function->WriteExport(buffer); | 447 for (auto function : functions_) function->WriteExports(buffer); |
| 455 FixupSection(buffer, start); | 448 FixupSection(buffer, start); |
| 456 } | 449 } |
| 457 | 450 |
| 458 // == emit start function index ============================================== | 451 // == emit start function index ============================================== |
| 459 if (start_function_index_ >= 0) { | 452 if (start_function_index_ >= 0) { |
| 460 size_t start = EmitSection(kStartSectionCode, buffer); | 453 size_t start = EmitSection(kStartSectionCode, buffer); |
| 461 buffer.write_u32v(start_function_index_ + | 454 buffer.write_u32v(start_function_index_ + |
| 462 static_cast<uint32_t>(imports_.size())); | 455 static_cast<uint32_t>(imports_.size())); |
| 463 FixupSection(buffer, start); | 456 FixupSection(buffer, start); |
| 464 } | 457 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 buffer.write(reinterpret_cast<const byte*>("name"), 4); | 510 buffer.write(reinterpret_cast<const byte*>("name"), 4); |
| 518 // Emit the names. | 511 // Emit the names. |
| 519 size_t count = functions_.size() + imports_.size(); | 512 size_t count = functions_.size() + imports_.size(); |
| 520 buffer.write_size(count); | 513 buffer.write_size(count); |
| 521 for (size_t i = 0; i < imports_.size(); i++) { | 514 for (size_t i = 0; i < imports_.size(); i++) { |
| 522 buffer.write_u8(0); // empty name for import | 515 buffer.write_u8(0); // empty name for import |
| 523 buffer.write_u8(0); // no local variables | 516 buffer.write_u8(0); // no local variables |
| 524 } | 517 } |
| 525 for (auto function : functions_) { | 518 for (auto function : functions_) { |
| 526 buffer.write_size(function->name_.size()); | 519 buffer.write_size(function->name_.size()); |
| 527 if (function->name_.size() > 0) { | 520 buffer.write(reinterpret_cast<const byte*>(function->name_.data()), |
| 528 buffer.write(reinterpret_cast<const byte*>(&function->name_[0]), | 521 function->name_.size()); |
| 529 function->name_.size()); | |
| 530 } | |
| 531 buffer.write_u8(0); | 522 buffer.write_u8(0); |
| 532 } | 523 } |
| 533 FixupSection(buffer, start); | 524 FixupSection(buffer, start); |
| 534 } | 525 } |
| 535 } | 526 } |
| 536 | 527 |
| 537 void WasmModuleBuilder::WriteAsmJsOffsetTable(ZoneBuffer& buffer) const { | 528 void WasmModuleBuilder::WriteAsmJsOffsetTable(ZoneBuffer& buffer) const { |
| 538 // == Emit asm.js offset table =============================================== | 529 // == Emit asm.js offset table =============================================== |
| 539 buffer.write_size(functions_.size()); | 530 buffer.write_size(functions_.size()); |
| 540 // Emit the offset table per function. | 531 // Emit the offset table per function. |
| 541 for (auto function : functions_) { | 532 for (auto function : functions_) { |
| 542 function->WriteAsmWasmOffsetTable(buffer); | 533 function->WriteAsmWasmOffsetTable(buffer); |
| 543 } | 534 } |
| 544 // Append a 0 to indicate that this is an encoded table. | 535 // Append a 0 to indicate that this is an encoded table. |
| 545 buffer.write_u8(0); | 536 buffer.write_u8(0); |
| 546 } | 537 } |
| 547 } // namespace wasm | 538 } // namespace wasm |
| 548 } // namespace internal | 539 } // namespace internal |
| 549 } // namespace v8 | 540 } // namespace v8 |
| OLD | NEW |