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

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

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

Powered by Google App Engine
This is Rietveld 408576698