Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(303)

Side by Side Diff: src/wasm/wasm-module-builder.cc

Issue 2757693003: [wasm][asm.js] Asm.js -> wasm custom parser. (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/objects-inl.h" 8 #include "src/objects-inl.h"
9 #include "src/v8.h" 9 #include "src/v8.h"
10 #include "src/zone/zone-containers.h" 10 #include "src/zone/zone-containers.h"
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 178
179 void WasmFunctionBuilder::SetAsmFunctionStartPosition(int position) { 179 void WasmFunctionBuilder::SetAsmFunctionStartPosition(int position) {
180 DCHECK_EQ(0, asm_func_start_source_position_); 180 DCHECK_EQ(0, asm_func_start_source_position_);
181 DCHECK_LE(0, position); 181 DCHECK_LE(0, position);
182 // Must be called before emitting any asm.js source position. 182 // Must be called before emitting any asm.js source position.
183 DCHECK_EQ(0, asm_offsets_.size()); 183 DCHECK_EQ(0, asm_offsets_.size());
184 asm_func_start_source_position_ = position; 184 asm_func_start_source_position_ = position;
185 last_asm_source_position_ = position; 185 last_asm_source_position_ = position;
186 } 186 }
187 187
188 void WasmFunctionBuilder::StashCode(std::vector<byte>* dst, size_t position) {
vogelheim 2017/03/17 17:27:07 This method would probably benefit from hosting th
bradn 2017/03/24 03:58:19 Done.
189 size_t len = body_.size() - position;
190 if (dst != nullptr) {
191 dst->resize(body_.size() - position);
vogelheim 2017/03/17 17:27:07 dst->resize(len) ?
bradn 2017/03/24 03:58:19 Done.
192 }
193 if (len == 0) {
194 return;
195 }
196 if (dst != nullptr) {
197 memcpy(dst->data(), &body_[position], len);
198 }
199 body_.resize(position);
200 }
201
188 void WasmFunctionBuilder::WriteSignature(ZoneBuffer& buffer) const { 202 void WasmFunctionBuilder::WriteSignature(ZoneBuffer& buffer) const {
189 buffer.write_u32v(signature_index_); 203 buffer.write_u32v(signature_index_);
190 } 204 }
191 205
192 void WasmFunctionBuilder::WriteExports(ZoneBuffer& buffer) const { 206 void WasmFunctionBuilder::WriteExports(ZoneBuffer& buffer) const {
193 for (auto name : exported_names_) { 207 for (auto name : exported_names_) {
194 buffer.write_size(name.size()); 208 buffer.write_size(name.size());
195 buffer.write(reinterpret_cast<const byte*>(name.data()), name.size()); 209 buffer.write(reinterpret_cast<const byte*>(name.data()), name.size());
196 buffer.write_u8(kExternalFunction); 210 buffer.write_u8(kExternalFunction);
197 buffer.write_u32v(func_index_ + 211 buffer.write_u32v(func_index_ + static_cast<uint32_t>(
198 static_cast<uint32_t>(builder_->imports_.size())); 212 builder_->function_imports_.size()));
199 } 213 }
200 } 214 }
201 215
202 void WasmFunctionBuilder::WriteBody(ZoneBuffer& buffer) const { 216 void WasmFunctionBuilder::WriteBody(ZoneBuffer& buffer) const {
203 size_t locals_size = locals_.Size(); 217 size_t locals_size = locals_.Size();
204 buffer.write_size(locals_size + body_.size()); 218 buffer.write_size(locals_size + body_.size());
205 buffer.EnsureSpace(locals_size); 219 buffer.EnsureSpace(locals_size);
206 byte** ptr = buffer.pos_ptr(); 220 byte** ptr = buffer.pos_ptr();
207 locals_.Emit(*ptr); 221 locals_.Emit(*ptr);
208 (*ptr) += locals_size; // UGLY: manual bump of position pointer 222 (*ptr) += locals_size; // UGLY: manual bump of position pointer
209 if (body_.size() > 0) { 223 if (body_.size() > 0) {
210 size_t base = buffer.offset(); 224 size_t base = buffer.offset();
211 buffer.write(&body_[0], body_.size()); 225 buffer.write(&body_[0], body_.size());
212 for (DirectCallIndex call : direct_calls_) { 226 for (DirectCallIndex call : direct_calls_) {
213 buffer.patch_u32v( 227 buffer.patch_u32v(
214 base + call.offset, 228 base + call.offset,
215 call.direct_index + static_cast<uint32_t>(builder_->imports_.size())); 229 call.direct_index +
230 static_cast<uint32_t>(builder_->function_imports_.size()));
216 } 231 }
217 } 232 }
218 } 233 }
219 234
220 void WasmFunctionBuilder::WriteAsmWasmOffsetTable(ZoneBuffer& buffer) const { 235 void WasmFunctionBuilder::WriteAsmWasmOffsetTable(ZoneBuffer& buffer) const {
221 if (asm_func_start_source_position_ == 0 && asm_offsets_.size() == 0) { 236 if (asm_func_start_source_position_ == 0 && asm_offsets_.size() == 0) {
222 buffer.write_size(0); 237 buffer.write_size(0);
223 return; 238 return;
224 } 239 }
225 size_t locals_enc_size = LEBHelper::sizeof_u32v(locals_.Size()); 240 size_t locals_enc_size = LEBHelper::sizeof_u32v(locals_.Size());
226 size_t func_start_size = 241 size_t func_start_size =
227 LEBHelper::sizeof_u32v(asm_func_start_source_position_); 242 LEBHelper::sizeof_u32v(asm_func_start_source_position_);
228 buffer.write_size(asm_offsets_.size() + locals_enc_size + func_start_size); 243 buffer.write_size(asm_offsets_.size() + locals_enc_size + func_start_size);
229 // Offset of the recorded byte offsets. 244 // Offset of the recorded byte offsets.
230 DCHECK_GE(kMaxUInt32, locals_.Size()); 245 DCHECK_GE(kMaxUInt32, locals_.Size());
231 buffer.write_u32v(static_cast<uint32_t>(locals_.Size())); 246 buffer.write_u32v(static_cast<uint32_t>(locals_.Size()));
232 // Start position of the function. 247 // Start position of the function.
233 buffer.write_u32v(asm_func_start_source_position_); 248 buffer.write_u32v(asm_func_start_source_position_);
234 buffer.write(asm_offsets_.begin(), asm_offsets_.size()); 249 buffer.write(asm_offsets_.begin(), asm_offsets_.size());
235 } 250 }
236 251
237 WasmModuleBuilder::WasmModuleBuilder(Zone* zone) 252 WasmModuleBuilder::WasmModuleBuilder(Zone* zone)
238 : zone_(zone), 253 : zone_(zone),
239 signatures_(zone), 254 signatures_(zone),
240 imports_(zone), 255 function_imports_(zone),
256 global_imports_(zone),
241 functions_(zone), 257 functions_(zone),
242 data_segments_(zone), 258 data_segments_(zone),
243 indirect_functions_(zone), 259 indirect_functions_(zone),
244 globals_(zone), 260 globals_(zone),
245 signature_map_(zone), 261 signature_map_(zone),
246 start_function_index_(-1) {} 262 start_function_index_(-1) {}
247 263
248 WasmFunctionBuilder* WasmModuleBuilder::AddFunction(FunctionSig* sig) { 264 WasmFunctionBuilder* WasmModuleBuilder::AddFunction(FunctionSig* sig) {
249 functions_.push_back(new (zone_) WasmFunctionBuilder(this)); 265 functions_.push_back(new (zone_) WasmFunctionBuilder(this));
250 // Add the signature if one was provided here. 266 // Add the signature if one was provided here.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 return ret; 312 return ret;
297 } 313 }
298 314
299 void WasmModuleBuilder::SetIndirectFunction(uint32_t indirect, 315 void WasmModuleBuilder::SetIndirectFunction(uint32_t indirect,
300 uint32_t direct) { 316 uint32_t direct) {
301 indirect_functions_[indirect] = direct; 317 indirect_functions_[indirect] = direct;
302 } 318 }
303 319
304 uint32_t WasmModuleBuilder::AddImport(const char* name, int name_length, 320 uint32_t WasmModuleBuilder::AddImport(const char* name, int name_length,
305 FunctionSig* sig) { 321 FunctionSig* sig) {
306 imports_.push_back({AddSignature(sig), name, name_length}); 322 function_imports_.push_back({AddSignature(sig), name, name_length});
307 return static_cast<uint32_t>(imports_.size() - 1); 323 return static_cast<uint32_t>(function_imports_.size() - 1);
324 }
325
326 uint32_t WasmModuleBuilder::AddGlobalImport(const char* name, int name_length,
327 ValueType type) {
328 global_imports_.push_back(
329 {WasmOpcodes::ValueTypeCodeFor(type), name, name_length});
330 return static_cast<uint32_t>(global_imports_.size() - 1);
308 } 331 }
309 332
310 void WasmModuleBuilder::MarkStartFunction(WasmFunctionBuilder* function) { 333 void WasmModuleBuilder::MarkStartFunction(WasmFunctionBuilder* function) {
311 start_function_index_ = function->func_index(); 334 start_function_index_ = function->func_index();
312 } 335 }
313 336
314 uint32_t WasmModuleBuilder::AddGlobal(ValueType type, bool exported, 337 uint32_t WasmModuleBuilder::AddGlobal(ValueType type, bool exported,
315 bool mutability, 338 bool mutability,
316 const WasmInitExpr& init) { 339 const WasmInitExpr& init) {
317 globals_.push_back({type, exported, mutability, init}); 340 globals_.push_back({type, exported, mutability, init});
(...skipping 21 matching lines...) Expand all
339 } 362 }
340 buffer.write_size(sig->return_count()); 363 buffer.write_size(sig->return_count());
341 for (auto ret : sig->returns()) { 364 for (auto ret : sig->returns()) {
342 buffer.write_u8(WasmOpcodes::ValueTypeCodeFor(ret)); 365 buffer.write_u8(WasmOpcodes::ValueTypeCodeFor(ret));
343 } 366 }
344 } 367 }
345 FixupSection(buffer, start); 368 FixupSection(buffer, start);
346 } 369 }
347 370
348 // == Emit imports =========================================================== 371 // == Emit imports ===========================================================
349 if (imports_.size() > 0) { 372 if (global_imports_.size() + function_imports_.size() > 0) {
350 size_t start = EmitSection(kImportSectionCode, buffer); 373 size_t start = EmitSection(kImportSectionCode, buffer);
351 buffer.write_size(imports_.size()); 374 buffer.write_size(global_imports_.size() + function_imports_.size());
352 for (auto import : imports_) { 375 for (auto import : global_imports_) {
353 buffer.write_u32v(0); // module name length 376 buffer.write_u32v(0); // module name length
354 buffer.write_u32v(import.name_length); // field name length 377 buffer.write_u32v(import.name_length); // field name length
355 buffer.write(reinterpret_cast<const byte*>(import.name), // field name 378 buffer.write(reinterpret_cast<const byte*>(import.name), // field name
379 import.name_length);
380 buffer.write_u8(kExternalGlobal);
381 buffer.write_u8(import.type_code);
382 buffer.write_u8(0); // immutable
383 }
384 for (auto import : function_imports_) {
385 buffer.write_u32v(0); // module name length
386 buffer.write_u32v(import.name_length); // field name length
387 buffer.write(reinterpret_cast<const byte*>(import.name), // field name
356 import.name_length); 388 import.name_length);
357 buffer.write_u8(kExternalFunction); 389 buffer.write_u8(kExternalFunction);
358 buffer.write_u32v(import.sig_index); 390 buffer.write_u32v(import.sig_index);
359 } 391 }
360 FixupSection(buffer, start); 392 FixupSection(buffer, start);
361 } 393 }
362 394
363 // == Emit function signatures =============================================== 395 // == Emit function signatures ===============================================
364 bool has_names = false; 396 bool has_names = false;
365 if (functions_.size() > 0) { 397 if (functions_.size() > 0) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 size_t start = EmitSection(kExportSectionCode, buffer); 503 size_t start = EmitSection(kExportSectionCode, buffer);
472 buffer.write_u32v(exports); 504 buffer.write_u32v(exports);
473 for (auto function : functions_) function->WriteExports(buffer); 505 for (auto function : functions_) function->WriteExports(buffer);
474 FixupSection(buffer, start); 506 FixupSection(buffer, start);
475 } 507 }
476 508
477 // == emit start function index ============================================== 509 // == emit start function index ==============================================
478 if (start_function_index_ >= 0) { 510 if (start_function_index_ >= 0) {
479 size_t start = EmitSection(kStartSectionCode, buffer); 511 size_t start = EmitSection(kStartSectionCode, buffer);
480 buffer.write_u32v(start_function_index_ + 512 buffer.write_u32v(start_function_index_ +
481 static_cast<uint32_t>(imports_.size())); 513 static_cast<uint32_t>(function_imports_.size()));
482 FixupSection(buffer, start); 514 FixupSection(buffer, start);
483 } 515 }
484 516
485 // == emit function table elements =========================================== 517 // == emit function table elements ===========================================
486 if (indirect_functions_.size() > 0) { 518 if (indirect_functions_.size() > 0) {
487 size_t start = EmitSection(kElementSectionCode, buffer); 519 size_t start = EmitSection(kElementSectionCode, buffer);
488 buffer.write_u8(1); // count of entries 520 buffer.write_u8(1); // count of entries
489 buffer.write_u8(0); // table index 521 buffer.write_u8(0); // table index
490 buffer.write_u8(kExprI32Const); // offset 522 buffer.write_u8(kExprI32Const); // offset
491 buffer.write_u32v(0); 523 buffer.write_u32v(0);
492 buffer.write_u8(kExprEnd); 524 buffer.write_u8(kExprEnd);
493 buffer.write_size(indirect_functions_.size()); // element count 525 buffer.write_size(indirect_functions_.size()); // element count
494 526
495 for (auto index : indirect_functions_) { 527 for (auto index : indirect_functions_) {
496 buffer.write_u32v(index + static_cast<uint32_t>(imports_.size())); 528 buffer.write_u32v(index +
529 static_cast<uint32_t>(function_imports_.size()));
497 } 530 }
498 531
499 FixupSection(buffer, start); 532 FixupSection(buffer, start);
500 } 533 }
501 534
502 // == emit code ============================================================== 535 // == emit code ==============================================================
503 if (functions_.size() > 0) { 536 if (functions_.size() > 0) {
504 size_t start = EmitSection(kCodeSectionCode, buffer); 537 size_t start = EmitSection(kCodeSectionCode, buffer);
505 buffer.write_size(functions_.size()); 538 buffer.write_size(functions_.size());
506 for (auto function : functions_) { 539 for (auto function : functions_) {
(...skipping 21 matching lines...) Expand all
528 // == Emit names ============================================================= 561 // == Emit names =============================================================
529 if (has_names) { 562 if (has_names) {
530 // Emit the section code. 563 // Emit the section code.
531 buffer.write_u8(kUnknownSectionCode); 564 buffer.write_u8(kUnknownSectionCode);
532 // Emit a placeholder for the length. 565 // Emit a placeholder for the length.
533 size_t start = buffer.reserve_u32v(); 566 size_t start = buffer.reserve_u32v();
534 // Emit the section string. 567 // Emit the section string.
535 buffer.write_size(4); 568 buffer.write_size(4);
536 buffer.write(reinterpret_cast<const byte*>("name"), 4); 569 buffer.write(reinterpret_cast<const byte*>("name"), 4);
537 // Emit the names. 570 // Emit the names.
538 size_t count = functions_.size() + imports_.size(); 571 size_t count = functions_.size() + function_imports_.size();
539 buffer.write_size(count); 572 buffer.write_size(count);
540 for (size_t i = 0; i < imports_.size(); i++) { 573 for (size_t i = 0; i < function_imports_.size(); i++) {
541 buffer.write_u8(0); // empty name for import 574 buffer.write_u8(0); // empty name for import
542 buffer.write_u8(0); // no local variables 575 buffer.write_u8(0); // no local variables
543 } 576 }
544 for (auto function : functions_) { 577 for (auto function : functions_) {
545 buffer.write_size(function->name_.size()); 578 buffer.write_size(function->name_.size());
546 buffer.write(reinterpret_cast<const byte*>(function->name_.data()), 579 buffer.write(reinterpret_cast<const byte*>(function->name_.data()),
547 function->name_.size()); 580 function->name_.size());
548 buffer.write_u8(0); 581 buffer.write_u8(0);
549 } 582 }
550 FixupSection(buffer, start); 583 FixupSection(buffer, start);
551 } 584 }
552 } 585 }
553 586
554 void WasmModuleBuilder::WriteAsmJsOffsetTable(ZoneBuffer& buffer) const { 587 void WasmModuleBuilder::WriteAsmJsOffsetTable(ZoneBuffer& buffer) const {
555 // == Emit asm.js offset table =============================================== 588 // == Emit asm.js offset table ===============================================
556 buffer.write_size(functions_.size()); 589 buffer.write_size(functions_.size());
557 // Emit the offset table per function. 590 // Emit the offset table per function.
558 for (auto function : functions_) { 591 for (auto function : functions_) {
559 function->WriteAsmWasmOffsetTable(buffer); 592 function->WriteAsmWasmOffsetTable(buffer);
560 } 593 }
561 // Append a 0 to indicate that this is an encoded table. 594 // Append a 0 to indicate that this is an encoded table.
562 buffer.write_u8(0); 595 buffer.write_u8(0);
563 } 596 }
564 } // namespace wasm 597 } // namespace wasm
565 } // namespace internal 598 } // namespace internal
566 } // namespace v8 599 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698