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 |