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

Side by Side Diff: src/compiler/wasm-compiler.cc

Issue 1915123006: [wasm] Pass byte position for trapping instructions (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase Created 4 years, 7 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/compiler/wasm-compiler.h ('k') | src/runtime/runtime.h » ('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/compiler/wasm-compiler.h" 5 #include "src/compiler/wasm-compiler.h"
6 6
7 #include "src/isolate-inl.h" 7 #include "src/isolate-inl.h"
8 8
9 #include "src/base/platform/elapsed-timer.h" 9 #include "src/base/platform/elapsed-timer.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 73
74 // A helper that handles building graph fragments for trapping. 74 // A helper that handles building graph fragments for trapping.
75 // To avoid generating a ton of redundant code that just calls the runtime 75 // To avoid generating a ton of redundant code that just calls the runtime
76 // to trap, we generate a per-trap-reason block of code that all trap sites 76 // to trap, we generate a per-trap-reason block of code that all trap sites
77 // in this function will branch to. 77 // in this function will branch to.
78 class WasmTrapHelper : public ZoneObject { 78 class WasmTrapHelper : public ZoneObject {
79 public: 79 public:
80 explicit WasmTrapHelper(WasmGraphBuilder* builder) 80 explicit WasmTrapHelper(WasmGraphBuilder* builder)
81 : builder_(builder), 81 : builder_(builder),
82 jsgraph_(builder->jsgraph()), 82 jsgraph_(builder->jsgraph()),
83 graph_(builder->jsgraph() ? builder->jsgraph()->graph() : nullptr) { 83 graph_(builder->jsgraph() ? builder->jsgraph()->graph() : nullptr) {}
84 for (int i = 0; i < wasm::kTrapCount; i++) traps_[i] = nullptr; 84
85 // Make the current control path trap to unreachable.
86 void Unreachable(wasm::WasmCodePosition position) {
87 ConnectTrap(wasm::kTrapUnreachable, position);
85 } 88 }
86 89
87 // Make the current control path trap to unreachable.
88 void Unreachable() { ConnectTrap(wasm::kTrapUnreachable); }
89
90 // Always trap with the given reason. 90 // Always trap with the given reason.
91 void TrapAlways(wasm::TrapReason reason) { ConnectTrap(reason); } 91 void TrapAlways(wasm::TrapReason reason, wasm::WasmCodePosition position) {
92 ConnectTrap(reason, position);
93 }
92 94
93 // Add a check that traps if {node} is equal to {val}. 95 // Add a check that traps if {node} is equal to {val}.
94 Node* TrapIfEq32(wasm::TrapReason reason, Node* node, int32_t val) { 96 Node* TrapIfEq32(wasm::TrapReason reason, Node* node, int32_t val,
97 wasm::WasmCodePosition position) {
95 Int32Matcher m(node); 98 Int32Matcher m(node);
96 if (m.HasValue() && !m.Is(val)) return graph()->start(); 99 if (m.HasValue() && !m.Is(val)) return graph()->start();
97 if (val == 0) { 100 if (val == 0) {
98 AddTrapIfFalse(reason, node); 101 AddTrapIfFalse(reason, node, position);
99 } else { 102 } else {
100 AddTrapIfTrue(reason, 103 AddTrapIfTrue(reason,
101 graph()->NewNode(jsgraph()->machine()->Word32Equal(), node, 104 graph()->NewNode(jsgraph()->machine()->Word32Equal(), node,
102 jsgraph()->Int32Constant(val))); 105 jsgraph()->Int32Constant(val)),
106 position);
103 } 107 }
104 return builder_->Control(); 108 return builder_->Control();
105 } 109 }
106 110
107 // Add a check that traps if {node} is zero. 111 // Add a check that traps if {node} is zero.
108 Node* ZeroCheck32(wasm::TrapReason reason, Node* node) { 112 Node* ZeroCheck32(wasm::TrapReason reason, Node* node,
109 return TrapIfEq32(reason, node, 0); 113 wasm::WasmCodePosition position) {
114 return TrapIfEq32(reason, node, 0, position);
110 } 115 }
111 116
112 // Add a check that traps if {node} is equal to {val}. 117 // Add a check that traps if {node} is equal to {val}.
113 Node* TrapIfEq64(wasm::TrapReason reason, Node* node, int64_t val) { 118 Node* TrapIfEq64(wasm::TrapReason reason, Node* node, int64_t val,
119 wasm::WasmCodePosition position) {
114 Int64Matcher m(node); 120 Int64Matcher m(node);
115 if (m.HasValue() && !m.Is(val)) return graph()->start(); 121 if (m.HasValue() && !m.Is(val)) return graph()->start();
116 AddTrapIfTrue(reason, 122 AddTrapIfTrue(reason, graph()->NewNode(jsgraph()->machine()->Word64Equal(),
117 graph()->NewNode(jsgraph()->machine()->Word64Equal(), node, 123 node, jsgraph()->Int64Constant(val)),
118 jsgraph()->Int64Constant(val))); 124 position);
119 return builder_->Control(); 125 return builder_->Control();
120 } 126 }
121 127
122 // Add a check that traps if {node} is zero. 128 // Add a check that traps if {node} is zero.
123 Node* ZeroCheck64(wasm::TrapReason reason, Node* node) { 129 Node* ZeroCheck64(wasm::TrapReason reason, Node* node,
124 return TrapIfEq64(reason, node, 0); 130 wasm::WasmCodePosition position) {
131 return TrapIfEq64(reason, node, 0, position);
125 } 132 }
126 133
127 // Add a trap if {cond} is true. 134 // Add a trap if {cond} is true.
128 void AddTrapIfTrue(wasm::TrapReason reason, Node* cond) { 135 void AddTrapIfTrue(wasm::TrapReason reason, Node* cond,
129 AddTrapIf(reason, cond, true); 136 wasm::WasmCodePosition position) {
137 AddTrapIf(reason, cond, true, position);
130 } 138 }
131 139
132 // Add a trap if {cond} is false. 140 // Add a trap if {cond} is false.
133 void AddTrapIfFalse(wasm::TrapReason reason, Node* cond) { 141 void AddTrapIfFalse(wasm::TrapReason reason, Node* cond,
134 AddTrapIf(reason, cond, false); 142 wasm::WasmCodePosition position) {
143 AddTrapIf(reason, cond, false, position);
135 } 144 }
136 145
137 // Add a trap if {cond} is true or false according to {iftrue}. 146 // Add a trap if {cond} is true or false according to {iftrue}.
138 void AddTrapIf(wasm::TrapReason reason, Node* cond, bool iftrue) { 147 void AddTrapIf(wasm::TrapReason reason, Node* cond, bool iftrue,
148 wasm::WasmCodePosition position) {
139 Node** effect_ptr = builder_->effect_; 149 Node** effect_ptr = builder_->effect_;
140 Node** control_ptr = builder_->control_; 150 Node** control_ptr = builder_->control_;
141 Node* before = *effect_ptr; 151 Node* before = *effect_ptr;
142 BranchHint hint = iftrue ? BranchHint::kFalse : BranchHint::kTrue; 152 BranchHint hint = iftrue ? BranchHint::kFalse : BranchHint::kTrue;
143 Node* branch = graph()->NewNode(common()->Branch(hint), cond, *control_ptr); 153 Node* branch = graph()->NewNode(common()->Branch(hint), cond, *control_ptr);
144 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 154 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
145 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 155 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
146 156
147 *control_ptr = iftrue ? if_true : if_false; 157 *control_ptr = iftrue ? if_true : if_false;
148 ConnectTrap(reason); 158 ConnectTrap(reason, position);
149 *control_ptr = iftrue ? if_false : if_true; 159 *control_ptr = iftrue ? if_false : if_true;
150 *effect_ptr = before; 160 *effect_ptr = before;
151 } 161 }
152 162
153 Node* GetTrapValue(wasm::FunctionSig* sig) { 163 Node* GetTrapValue(wasm::FunctionSig* sig) {
154 if (sig->return_count() > 0) { 164 if (sig->return_count() > 0) {
155 switch (sig->GetReturn()) { 165 switch (sig->GetReturn()) {
156 case wasm::kAstI32: 166 case wasm::kAstI32:
157 return jsgraph()->Int32Constant(0xdeadbeef); 167 return jsgraph()->Int32Constant(0xdeadbeef);
158 case wasm::kAstI64: 168 case wasm::kAstI64:
(...skipping 10 matching lines...) Expand all
169 } 179 }
170 } else { 180 } else {
171 return jsgraph()->Int32Constant(0xdeadbeef); 181 return jsgraph()->Int32Constant(0xdeadbeef);
172 } 182 }
173 } 183 }
174 184
175 private: 185 private:
176 WasmGraphBuilder* builder_; 186 WasmGraphBuilder* builder_;
177 JSGraph* jsgraph_; 187 JSGraph* jsgraph_;
178 Graph* graph_; 188 Graph* graph_;
179 Node* traps_[wasm::kTrapCount]; 189 Node* trap_merge_ = nullptr;
180 Node* effects_[wasm::kTrapCount]; 190 Node* trap_effect_;
191 Node* trap_reason_;
192 Node* trap_position_;
181 193
182 JSGraph* jsgraph() { return jsgraph_; } 194 JSGraph* jsgraph() { return jsgraph_; }
183 Graph* graph() { return jsgraph_->graph(); } 195 Graph* graph() { return jsgraph_->graph(); }
184 CommonOperatorBuilder* common() { return jsgraph()->common(); } 196 CommonOperatorBuilder* common() { return jsgraph()->common(); }
185 197
186 void ConnectTrap(wasm::TrapReason reason) { 198 void ConnectTrap(wasm::TrapReason reason, wasm::WasmCodePosition position) {
187 if (traps_[reason] == nullptr) { 199 DCHECK(position != wasm::kNoCodePosition);
188 // Create trap code for the first time this trap is used. 200 Node* reason_node = builder_->Int32Constant(
189 return BuildTrapCode(reason); 201 wasm::WasmOpcodes::TrapReasonToMessageId(reason));
202 Node* position_node = builder_->Int32Constant(position);
203 if (trap_merge_ == nullptr) {
204 // Create trap code for the first time.
205 return BuildTrapCode(reason_node, position_node);
190 } 206 }
191 // Connect the current control and effect to the existing trap code. 207 // Connect the current control and effect to the existing trap code.
192 builder_->AppendToMerge(traps_[reason], builder_->Control()); 208 builder_->AppendToMerge(trap_merge_, builder_->Control());
193 builder_->AppendToPhi(traps_[reason], effects_[reason], builder_->Effect()); 209 builder_->AppendToPhi(trap_effect_, builder_->Effect());
210 builder_->AppendToPhi(trap_reason_, reason_node);
211 builder_->AppendToPhi(trap_position_, position_node);
194 } 212 }
195 213
196 void BuildTrapCode(wasm::TrapReason reason) { 214 void BuildTrapCode(Node* reason_node, Node* position_node) {
197 Node* message_id = builder_->NumberConstant(
198 wasm::WasmOpcodes::TrapReasonToMessageId(reason));
199 Node* end; 215 Node* end;
200 Node** control_ptr = builder_->control_; 216 Node** control_ptr = builder_->control_;
201 Node** effect_ptr = builder_->effect_; 217 Node** effect_ptr = builder_->effect_;
202 wasm::ModuleEnv* module = builder_->module_; 218 wasm::ModuleEnv* module = builder_->module_;
203 DCHECK(traps_[reason] == NULL); 219 DCHECK(trap_merge_ == NULL);
204 *control_ptr = traps_[reason] = 220 *control_ptr = trap_merge_ =
205 graph()->NewNode(common()->Merge(1), *control_ptr); 221 graph()->NewNode(common()->Merge(1), *control_ptr);
206 *effect_ptr = effects_[reason] = 222 *effect_ptr = trap_effect_ =
207 graph()->NewNode(common()->EffectPhi(1), *effect_ptr, *control_ptr); 223 graph()->NewNode(common()->EffectPhi(1), *effect_ptr, *control_ptr);
224 trap_reason_ =
225 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 1),
226 reason_node, *control_ptr);
227 trap_position_ =
228 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 1),
229 position_node, *control_ptr);
230
231 Node* trap_reason_smi = builder_->BuildChangeInt32ToSmi(trap_reason_);
232 Node* trap_position_smi = builder_->BuildChangeInt32ToSmi(trap_position_);
208 233
209 if (module && !module->instance->context.is_null()) { 234 if (module && !module->instance->context.is_null()) {
210 // Use the module context to call the runtime to throw an exception. 235 // Use the module context to call the runtime to throw an exception.
211 Runtime::FunctionId f = Runtime::kThrowWasmError; 236 Runtime::FunctionId f = Runtime::kThrowWasmError;
212 const Runtime::Function* fun = Runtime::FunctionForId(f); 237 const Runtime::Function* fun = Runtime::FunctionForId(f);
213 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor( 238 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
214 jsgraph()->zone(), f, fun->nargs, Operator::kNoProperties, 239 jsgraph()->zone(), f, fun->nargs, Operator::kNoProperties,
215 CallDescriptor::kNoFlags); 240 CallDescriptor::kNoFlags);
216 Node* inputs[] = { 241 Node* inputs[] = {
217 jsgraph()->CEntryStubConstant(fun->result_size), // C entry 242 jsgraph()->CEntryStubConstant(fun->result_size), // C entry
218 message_id, // message id 243 trap_reason_smi, // message id
244 trap_position_smi, // byte position
219 jsgraph()->ExternalConstant( 245 jsgraph()->ExternalConstant(
220 ExternalReference(f, jsgraph()->isolate())), // ref 246 ExternalReference(f, jsgraph()->isolate())), // ref
221 jsgraph()->Int32Constant(fun->nargs), // arity 247 jsgraph()->Int32Constant(fun->nargs), // arity
222 jsgraph()->Constant(module->instance->context), // context 248 jsgraph()->Constant(module->instance->context), // context
223 *effect_ptr, 249 *effect_ptr,
224 *control_ptr}; 250 *control_ptr};
225 251
226 Node* node = graph()->NewNode( 252 Node* node = graph()->NewNode(
227 common()->Call(desc), static_cast<int>(arraysize(inputs)), inputs); 253 common()->Call(desc), static_cast<int>(arraysize(inputs)), inputs);
228 *control_ptr = node; 254 *control_ptr = node;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 332
307 333
308 void WasmGraphBuilder::AppendToMerge(Node* merge, Node* from) { 334 void WasmGraphBuilder::AppendToMerge(Node* merge, Node* from) {
309 DCHECK(IrOpcode::IsMergeOpcode(merge->opcode())); 335 DCHECK(IrOpcode::IsMergeOpcode(merge->opcode()));
310 merge->AppendInput(jsgraph()->zone(), from); 336 merge->AppendInput(jsgraph()->zone(), from);
311 int new_size = merge->InputCount(); 337 int new_size = merge->InputCount();
312 NodeProperties::ChangeOp( 338 NodeProperties::ChangeOp(
313 merge, jsgraph()->common()->ResizeMergeOrPhi(merge->op(), new_size)); 339 merge, jsgraph()->common()->ResizeMergeOrPhi(merge->op(), new_size));
314 } 340 }
315 341
316 342 void WasmGraphBuilder::AppendToPhi(Node* phi, Node* from) {
317 void WasmGraphBuilder::AppendToPhi(Node* merge, Node* phi, Node* from) {
318 DCHECK(IrOpcode::IsPhiOpcode(phi->opcode())); 343 DCHECK(IrOpcode::IsPhiOpcode(phi->opcode()));
319 DCHECK(IrOpcode::IsMergeOpcode(merge->opcode()));
320 int new_size = phi->InputCount(); 344 int new_size = phi->InputCount();
321 phi->InsertInput(jsgraph()->zone(), phi->InputCount() - 1, from); 345 phi->InsertInput(jsgraph()->zone(), phi->InputCount() - 1, from);
322 NodeProperties::ChangeOp( 346 NodeProperties::ChangeOp(
323 phi, jsgraph()->common()->ResizeMergeOrPhi(phi->op(), new_size)); 347 phi, jsgraph()->common()->ResizeMergeOrPhi(phi->op(), new_size));
324 } 348 }
325 349
326 350
327 Node* WasmGraphBuilder::Merge(unsigned count, Node** controls) { 351 Node* WasmGraphBuilder::Merge(unsigned count, Node** controls) {
328 return graph()->NewNode(jsgraph()->common()->Merge(count), count, controls); 352 return graph()->NewNode(jsgraph()->common()->Merge(count), count, controls);
329 } 353 }
(...skipping 24 matching lines...) Expand all
354 378
355 Node* WasmGraphBuilder::Int32Constant(int32_t value) { 379 Node* WasmGraphBuilder::Int32Constant(int32_t value) {
356 return jsgraph()->Int32Constant(value); 380 return jsgraph()->Int32Constant(value);
357 } 381 }
358 382
359 383
360 Node* WasmGraphBuilder::Int64Constant(int64_t value) { 384 Node* WasmGraphBuilder::Int64Constant(int64_t value) {
361 return jsgraph()->Int64Constant(value); 385 return jsgraph()->Int64Constant(value);
362 } 386 }
363 387
364 388 Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left, Node* right,
365 Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left, 389 wasm::WasmCodePosition position) {
366 Node* right) {
367 const Operator* op; 390 const Operator* op;
368 MachineOperatorBuilder* m = jsgraph()->machine(); 391 MachineOperatorBuilder* m = jsgraph()->machine();
369 switch (opcode) { 392 switch (opcode) {
370 case wasm::kExprI32Add: 393 case wasm::kExprI32Add:
371 op = m->Int32Add(); 394 op = m->Int32Add();
372 break; 395 break;
373 case wasm::kExprI32Sub: 396 case wasm::kExprI32Sub:
374 op = m->Int32Sub(); 397 op = m->Int32Sub();
375 break; 398 break;
376 case wasm::kExprI32Mul: 399 case wasm::kExprI32Mul:
377 op = m->Int32Mul(); 400 op = m->Int32Mul();
378 break; 401 break;
379 case wasm::kExprI32DivS: 402 case wasm::kExprI32DivS:
380 return BuildI32DivS(left, right); 403 return BuildI32DivS(left, right, position);
381 case wasm::kExprI32DivU: 404 case wasm::kExprI32DivU:
382 return BuildI32DivU(left, right); 405 return BuildI32DivU(left, right, position);
383 case wasm::kExprI32RemS: 406 case wasm::kExprI32RemS:
384 return BuildI32RemS(left, right); 407 return BuildI32RemS(left, right, position);
385 case wasm::kExprI32RemU: 408 case wasm::kExprI32RemU:
386 return BuildI32RemU(left, right); 409 return BuildI32RemU(left, right, position);
387 case wasm::kExprI32And: 410 case wasm::kExprI32And:
388 op = m->Word32And(); 411 op = m->Word32And();
389 break; 412 break;
390 case wasm::kExprI32Ior: 413 case wasm::kExprI32Ior:
391 op = m->Word32Or(); 414 op = m->Word32Or();
392 break; 415 break;
393 case wasm::kExprI32Xor: 416 case wasm::kExprI32Xor:
394 op = m->Word32Xor(); 417 op = m->Word32Xor();
395 break; 418 break;
396 case wasm::kExprI32Shl: 419 case wasm::kExprI32Shl:
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 // kExprI64Sub: 480 // kExprI64Sub:
458 case wasm::kExprI64Sub: 481 case wasm::kExprI64Sub:
459 op = m->Int64Sub(); 482 op = m->Int64Sub();
460 break; 483 break;
461 // kExprI64Mul: 484 // kExprI64Mul:
462 case wasm::kExprI64Mul: 485 case wasm::kExprI64Mul:
463 op = m->Int64Mul(); 486 op = m->Int64Mul();
464 break; 487 break;
465 // kExprI64DivS: 488 // kExprI64DivS:
466 case wasm::kExprI64DivS: 489 case wasm::kExprI64DivS:
467 return BuildI64DivS(left, right); 490 return BuildI64DivS(left, right, position);
468 // kExprI64DivU: 491 // kExprI64DivU:
469 case wasm::kExprI64DivU: 492 case wasm::kExprI64DivU:
470 return BuildI64DivU(left, right); 493 return BuildI64DivU(left, right, position);
471 // kExprI64RemS: 494 // kExprI64RemS:
472 case wasm::kExprI64RemS: 495 case wasm::kExprI64RemS:
473 return BuildI64RemS(left, right); 496 return BuildI64RemS(left, right, position);
474 // kExprI64RemU: 497 // kExprI64RemU:
475 case wasm::kExprI64RemU: 498 case wasm::kExprI64RemU:
476 return BuildI64RemU(left, right); 499 return BuildI64RemU(left, right, position);
477 case wasm::kExprI64Ior: 500 case wasm::kExprI64Ior:
478 op = m->Word64Or(); 501 op = m->Word64Or();
479 break; 502 break;
480 // kExprI64Xor: 503 // kExprI64Xor:
481 case wasm::kExprI64Xor: 504 case wasm::kExprI64Xor:
482 op = m->Word64Xor(); 505 op = m->Word64Xor();
483 break; 506 break;
484 // kExprI64Shl: 507 // kExprI64Shl:
485 case wasm::kExprI64Shl: 508 case wasm::kExprI64Shl:
486 op = m->Word64Shl(); 509 op = m->Word64Shl();
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 } 643 }
621 case wasm::kExprF64Mod: { 644 case wasm::kExprF64Mod: {
622 return BuildF64Mod(left, right); 645 return BuildF64Mod(left, right);
623 } 646 }
624 default: 647 default:
625 op = UnsupportedOpcode(opcode); 648 op = UnsupportedOpcode(opcode);
626 } 649 }
627 return graph()->NewNode(op, left, right); 650 return graph()->NewNode(op, left, right);
628 } 651 }
629 652
630 653 Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input,
631 Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) { 654 wasm::WasmCodePosition position) {
632 const Operator* op; 655 const Operator* op;
633 MachineOperatorBuilder* m = jsgraph()->machine(); 656 MachineOperatorBuilder* m = jsgraph()->machine();
634 switch (opcode) { 657 switch (opcode) {
635 case wasm::kExprI32Eqz: 658 case wasm::kExprI32Eqz:
636 op = m->Word32Equal(); 659 op = m->Word32Equal();
637 return graph()->NewNode(op, input, jsgraph()->Int32Constant(0)); 660 return graph()->NewNode(op, input, jsgraph()->Int32Constant(0));
638 case wasm::kExprF32Abs: 661 case wasm::kExprF32Abs:
639 op = m->Float32Abs(); 662 op = m->Float32Abs();
640 break; 663 break;
641 case wasm::kExprF32Neg: 664 case wasm::kExprF32Neg:
642 return BuildF32Neg(input); 665 return BuildF32Neg(input);
643 case wasm::kExprF32Sqrt: 666 case wasm::kExprF32Sqrt:
644 op = m->Float32Sqrt(); 667 op = m->Float32Sqrt();
645 break; 668 break;
646 case wasm::kExprF64Abs: 669 case wasm::kExprF64Abs:
647 op = m->Float64Abs(); 670 op = m->Float64Abs();
648 break; 671 break;
649 case wasm::kExprF64Neg: 672 case wasm::kExprF64Neg:
650 return BuildF64Neg(input); 673 return BuildF64Neg(input);
651 case wasm::kExprF64Sqrt: 674 case wasm::kExprF64Sqrt:
652 op = m->Float64Sqrt(); 675 op = m->Float64Sqrt();
653 break; 676 break;
654 case wasm::kExprI32SConvertF64: 677 case wasm::kExprI32SConvertF64:
655 return BuildI32SConvertF64(input); 678 return BuildI32SConvertF64(input, position);
656 case wasm::kExprI32UConvertF64: 679 case wasm::kExprI32UConvertF64:
657 return BuildI32UConvertF64(input); 680 return BuildI32UConvertF64(input, position);
658 case wasm::kExprF32ConvertF64: 681 case wasm::kExprF32ConvertF64:
659 op = m->TruncateFloat64ToFloat32(); 682 op = m->TruncateFloat64ToFloat32();
660 break; 683 break;
661 case wasm::kExprF64SConvertI32: 684 case wasm::kExprF64SConvertI32:
662 op = m->ChangeInt32ToFloat64(); 685 op = m->ChangeInt32ToFloat64();
663 break; 686 break;
664 case wasm::kExprF64UConvertI32: 687 case wasm::kExprF64UConvertI32:
665 op = m->ChangeUint32ToFloat64(); 688 op = m->ChangeUint32ToFloat64();
666 break; 689 break;
667 case wasm::kExprF32SConvertI32: 690 case wasm::kExprF32SConvertI32:
668 op = m->RoundInt32ToFloat32(); 691 op = m->RoundInt32ToFloat32();
669 break; 692 break;
670 case wasm::kExprF32UConvertI32: 693 case wasm::kExprF32UConvertI32:
671 op = m->RoundUint32ToFloat32(); 694 op = m->RoundUint32ToFloat32();
672 break; 695 break;
673 case wasm::kExprI32SConvertF32: 696 case wasm::kExprI32SConvertF32:
674 return BuildI32SConvertF32(input); 697 return BuildI32SConvertF32(input, position);
675 case wasm::kExprI32UConvertF32: 698 case wasm::kExprI32UConvertF32:
676 return BuildI32UConvertF32(input); 699 return BuildI32UConvertF32(input, position);
677 case wasm::kExprF64ConvertF32: 700 case wasm::kExprF64ConvertF32:
678 op = m->ChangeFloat32ToFloat64(); 701 op = m->ChangeFloat32ToFloat64();
679 break; 702 break;
680 case wasm::kExprF32ReinterpretI32: 703 case wasm::kExprF32ReinterpretI32:
681 op = m->BitcastInt32ToFloat32(); 704 op = m->BitcastInt32ToFloat32();
682 break; 705 break;
683 case wasm::kExprI32ReinterpretF32: 706 case wasm::kExprI32ReinterpretF32:
684 op = m->BitcastFloat32ToInt32(); 707 op = m->BitcastFloat32ToInt32();
685 break; 708 break;
686 case wasm::kExprI32Clz: 709 case wasm::kExprI32Clz:
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 break; 872 break;
850 // kExprF64UConvertI64: 873 // kExprF64UConvertI64:
851 case wasm::kExprF64UConvertI64: 874 case wasm::kExprF64UConvertI64:
852 if (m->Is32()) { 875 if (m->Is32()) {
853 return BuildF64UConvertI64(input); 876 return BuildF64UConvertI64(input);
854 } 877 }
855 op = m->RoundUint64ToFloat64(); 878 op = m->RoundUint64ToFloat64();
856 break; 879 break;
857 // kExprI64SConvertF32: 880 // kExprI64SConvertF32:
858 case wasm::kExprI64SConvertF32: { 881 case wasm::kExprI64SConvertF32: {
859 return BuildI64SConvertF32(input); 882 return BuildI64SConvertF32(input, position);
860 } 883 }
861 // kExprI64SConvertF64: 884 // kExprI64SConvertF64:
862 case wasm::kExprI64SConvertF64: { 885 case wasm::kExprI64SConvertF64: {
863 return BuildI64SConvertF64(input); 886 return BuildI64SConvertF64(input, position);
864 } 887 }
865 // kExprI64UConvertF32: 888 // kExprI64UConvertF32:
866 case wasm::kExprI64UConvertF32: { 889 case wasm::kExprI64UConvertF32: {
867 return BuildI64UConvertF32(input); 890 return BuildI64UConvertF32(input, position);
868 } 891 }
869 // kExprI64UConvertF64: 892 // kExprI64UConvertF64:
870 case wasm::kExprI64UConvertF64: { 893 case wasm::kExprI64UConvertF64: {
871 return BuildI64UConvertF64(input); 894 return BuildI64UConvertF64(input, position);
872 } 895 }
873 default: 896 default:
874 op = UnsupportedOpcode(opcode); 897 op = UnsupportedOpcode(opcode);
875 } 898 }
876 return graph()->NewNode(op, input); 899 return graph()->NewNode(op, input);
877 } 900 }
878 901
879 902
880 Node* WasmGraphBuilder::Float32Constant(float value) { 903 Node* WasmGraphBuilder::Float32Constant(float value) {
881 return jsgraph()->Float32Constant(value); 904 return jsgraph()->Float32Constant(value);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 buf[count + 1] = *control_; 959 buf[count + 1] = *control_;
937 Node* ret = graph()->NewNode(jsgraph()->common()->Return(), count + 2, vals); 960 Node* ret = graph()->NewNode(jsgraph()->common()->Return(), count + 2, vals);
938 961
939 MergeControlToEnd(jsgraph(), ret); 962 MergeControlToEnd(jsgraph(), ret);
940 return ret; 963 return ret;
941 } 964 }
942 965
943 966
944 Node* WasmGraphBuilder::ReturnVoid() { return Return(0, Buffer(0)); } 967 Node* WasmGraphBuilder::ReturnVoid() { return Return(0, Buffer(0)); }
945 968
946 969 Node* WasmGraphBuilder::Unreachable(wasm::WasmCodePosition position) {
947 Node* WasmGraphBuilder::Unreachable() { 970 trap_->Unreachable(position);
948 trap_->Unreachable();
949 return nullptr; 971 return nullptr;
950 } 972 }
951 973
952 Node* WasmGraphBuilder::MaskShiftCount32(Node* node) { 974 Node* WasmGraphBuilder::MaskShiftCount32(Node* node) {
953 static const int32_t kMask32 = 0x1f; 975 static const int32_t kMask32 = 0x1f;
954 if (!jsgraph()->machine()->Word32ShiftIsSafe()) { 976 if (!jsgraph()->machine()->Word32ShiftIsSafe()) {
955 // Shifts by constants are so common we pattern-match them here. 977 // Shifts by constants are so common we pattern-match them here.
956 Int32Matcher match(node); 978 Int32Matcher match(node);
957 if (match.HasValue()) { 979 if (match.HasValue()) {
958 int32_t masked = (match.Value() & kMask32); 980 int32_t masked = (match.Value() & kMask32);
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 return left_ge_right.Phi( 1151 return left_ge_right.Phi(
1130 wasm::kAstF64, left, 1152 wasm::kAstF64, left,
1131 right_gt_left.Phi( 1153 right_gt_left.Phi(
1132 wasm::kAstF64, right, 1154 wasm::kAstF64, right,
1133 left_is_not_nan.Phi( 1155 left_is_not_nan.Phi(
1134 wasm::kAstF64, 1156 wasm::kAstF64,
1135 Binop(wasm::kExprF64Mul, right, Float64Constant(1.0)), 1157 Binop(wasm::kExprF64Mul, right, Float64Constant(1.0)),
1136 Binop(wasm::kExprF64Mul, left, Float64Constant(1.0))))); 1158 Binop(wasm::kExprF64Mul, left, Float64Constant(1.0)))));
1137 } 1159 }
1138 1160
1139 1161 Node* WasmGraphBuilder::BuildI32SConvertF32(Node* input,
1140 Node* WasmGraphBuilder::BuildI32SConvertF32(Node* input) { 1162 wasm::WasmCodePosition position) {
1141 MachineOperatorBuilder* m = jsgraph()->machine(); 1163 MachineOperatorBuilder* m = jsgraph()->machine();
1142 if (module_ && module_->asm_js()) { 1164 if (module_ && module_->asm_js()) {
1143 // asm.js must use the wacky JS semantics. 1165 // asm.js must use the wacky JS semantics.
1144 input = graph()->NewNode(m->ChangeFloat32ToFloat64(), input); 1166 input = graph()->NewNode(m->ChangeFloat32ToFloat64(), input);
1145 return graph()->NewNode(m->TruncateFloat64ToWord32(), input); 1167 return graph()->NewNode(m->TruncateFloat64ToWord32(), input);
1146 } 1168 }
1147 1169
1148 // Truncation of the input value is needed for the overflow check later. 1170 // Truncation of the input value is needed for the overflow check later.
1149 Node* trunc = Unop(wasm::kExprF32Trunc, input); 1171 Node* trunc = Unop(wasm::kExprF32Trunc, input);
1150 Node* result = graph()->NewNode(m->TruncateFloat32ToInt32(), trunc); 1172 Node* result = graph()->NewNode(m->TruncateFloat32ToInt32(), trunc);
1151 1173
1152 // Convert the result back to f64. If we end up at a different value than the 1174 // Convert the result back to f64. If we end up at a different value than the
1153 // truncated input value, then there has been an overflow and we trap. 1175 // truncated input value, then there has been an overflow and we trap.
1154 Node* check = Unop(wasm::kExprF32SConvertI32, result); 1176 Node* check = Unop(wasm::kExprF32SConvertI32, result);
1155 Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); 1177 Node* overflow = Binop(wasm::kExprF32Ne, trunc, check);
1156 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow); 1178 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow, position);
1157 1179
1158 return result; 1180 return result;
1159 } 1181 }
1160 1182
1161 1183 Node* WasmGraphBuilder::BuildI32SConvertF64(Node* input,
1162 Node* WasmGraphBuilder::BuildI32SConvertF64(Node* input) { 1184 wasm::WasmCodePosition position) {
1163 MachineOperatorBuilder* m = jsgraph()->machine(); 1185 MachineOperatorBuilder* m = jsgraph()->machine();
1164 if (module_ && module_->asm_js()) { 1186 if (module_ && module_->asm_js()) {
1165 // asm.js must use the wacky JS semantics. 1187 // asm.js must use the wacky JS semantics.
1166 return graph()->NewNode(m->TruncateFloat64ToWord32(), input); 1188 return graph()->NewNode(m->TruncateFloat64ToWord32(), input);
1167 } 1189 }
1168 // Truncation of the input value is needed for the overflow check later. 1190 // Truncation of the input value is needed for the overflow check later.
1169 Node* trunc = Unop(wasm::kExprF64Trunc, input); 1191 Node* trunc = Unop(wasm::kExprF64Trunc, input);
1170 Node* result = graph()->NewNode(m->ChangeFloat64ToInt32(), trunc); 1192 Node* result = graph()->NewNode(m->ChangeFloat64ToInt32(), trunc);
1171 1193
1172 // Convert the result back to f64. If we end up at a different value than the 1194 // Convert the result back to f64. If we end up at a different value than the
1173 // truncated input value, then there has been an overflow and we trap. 1195 // truncated input value, then there has been an overflow and we trap.
1174 Node* check = Unop(wasm::kExprF64SConvertI32, result); 1196 Node* check = Unop(wasm::kExprF64SConvertI32, result);
1175 Node* overflow = Binop(wasm::kExprF64Ne, trunc, check); 1197 Node* overflow = Binop(wasm::kExprF64Ne, trunc, check);
1176 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow); 1198 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow, position);
1177 1199
1178 return result; 1200 return result;
1179 } 1201 }
1180 1202
1181 1203 Node* WasmGraphBuilder::BuildI32UConvertF32(Node* input,
1182 Node* WasmGraphBuilder::BuildI32UConvertF32(Node* input) { 1204 wasm::WasmCodePosition position) {
1183 MachineOperatorBuilder* m = jsgraph()->machine(); 1205 MachineOperatorBuilder* m = jsgraph()->machine();
1184 if (module_ && module_->asm_js()) { 1206 if (module_ && module_->asm_js()) {
1185 // asm.js must use the wacky JS semantics. 1207 // asm.js must use the wacky JS semantics.
1186 input = graph()->NewNode(m->ChangeFloat32ToFloat64(), input); 1208 input = graph()->NewNode(m->ChangeFloat32ToFloat64(), input);
1187 return graph()->NewNode(m->TruncateFloat64ToWord32(), input); 1209 return graph()->NewNode(m->TruncateFloat64ToWord32(), input);
1188 } 1210 }
1189 1211
1190 // Truncation of the input value is needed for the overflow check later. 1212 // Truncation of the input value is needed for the overflow check later.
1191 Node* trunc = Unop(wasm::kExprF32Trunc, input); 1213 Node* trunc = Unop(wasm::kExprF32Trunc, input);
1192 Node* result = graph()->NewNode(m->TruncateFloat32ToUint32(), trunc); 1214 Node* result = graph()->NewNode(m->TruncateFloat32ToUint32(), trunc);
1193 1215
1194 // Convert the result back to f32. If we end up at a different value than the 1216 // Convert the result back to f32. If we end up at a different value than the
1195 // truncated input value, then there has been an overflow and we trap. 1217 // truncated input value, then there has been an overflow and we trap.
1196 Node* check = Unop(wasm::kExprF32UConvertI32, result); 1218 Node* check = Unop(wasm::kExprF32UConvertI32, result);
1197 Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); 1219 Node* overflow = Binop(wasm::kExprF32Ne, trunc, check);
1198 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow); 1220 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow, position);
1199 1221
1200 return result; 1222 return result;
1201 } 1223 }
1202 1224
1203 1225 Node* WasmGraphBuilder::BuildI32UConvertF64(Node* input,
1204 Node* WasmGraphBuilder::BuildI32UConvertF64(Node* input) { 1226 wasm::WasmCodePosition position) {
1205 MachineOperatorBuilder* m = jsgraph()->machine(); 1227 MachineOperatorBuilder* m = jsgraph()->machine();
1206 if (module_ && module_->asm_js()) { 1228 if (module_ && module_->asm_js()) {
1207 // asm.js must use the wacky JS semantics. 1229 // asm.js must use the wacky JS semantics.
1208 return graph()->NewNode(m->TruncateFloat64ToWord32(), input); 1230 return graph()->NewNode(m->TruncateFloat64ToWord32(), input);
1209 } 1231 }
1210 // Truncation of the input value is needed for the overflow check later. 1232 // Truncation of the input value is needed for the overflow check later.
1211 Node* trunc = Unop(wasm::kExprF64Trunc, input); 1233 Node* trunc = Unop(wasm::kExprF64Trunc, input);
1212 Node* result = graph()->NewNode(m->TruncateFloat64ToUint32(), trunc); 1234 Node* result = graph()->NewNode(m->TruncateFloat64ToUint32(), trunc);
1213 1235
1214 // Convert the result back to f64. If we end up at a different value than the 1236 // Convert the result back to f64. If we end up at a different value than the
1215 // truncated input value, then there has been an overflow and we trap. 1237 // truncated input value, then there has been an overflow and we trap.
1216 Node* check = Unop(wasm::kExprF64UConvertI32, result); 1238 Node* check = Unop(wasm::kExprF64UConvertI32, result);
1217 Node* overflow = Binop(wasm::kExprF64Ne, trunc, check); 1239 Node* overflow = Binop(wasm::kExprF64Ne, trunc, check);
1218 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow); 1240 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow, position);
1219 1241
1220 return result; 1242 return result;
1221 } 1243 }
1222 1244
1223 Node* WasmGraphBuilder::BuildBitCountingCall(Node* input, ExternalReference ref, 1245 Node* WasmGraphBuilder::BuildBitCountingCall(Node* input, ExternalReference ref,
1224 MachineRepresentation input_type) { 1246 MachineRepresentation input_type) {
1225 Node* stack_slot_param = 1247 Node* stack_slot_param =
1226 graph()->NewNode(jsgraph()->machine()->StackSlot(input_type)); 1248 graph()->NewNode(jsgraph()->machine()->StackSlot(input_type));
1227 1249
1228 const Operator* store_op = jsgraph()->machine()->Store( 1250 const Operator* store_op = jsgraph()->machine()->Store(
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
1499 Node* args[] = {function, stack_slot_param, stack_slot_result}; 1521 Node* args[] = {function, stack_slot_param, stack_slot_result};
1500 BuildCCall(sig_builder.Build(), args); 1522 BuildCCall(sig_builder.Build(), args);
1501 const Operator* load_op = jsgraph()->machine()->Load(result_type); 1523 const Operator* load_op = jsgraph()->machine()->Load(result_type);
1502 Node* load = 1524 Node* load =
1503 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0), 1525 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0),
1504 *effect_, *control_); 1526 *effect_, *control_);
1505 *effect_ = load; 1527 *effect_ = load;
1506 return load; 1528 return load;
1507 } 1529 }
1508 1530
1509 Node* WasmGraphBuilder::BuildI64SConvertF32(Node* input) { 1531 Node* WasmGraphBuilder::BuildI64SConvertF32(Node* input,
1532 wasm::WasmCodePosition position) {
1510 if (jsgraph()->machine()->Is32()) { 1533 if (jsgraph()->machine()->Is32()) {
1511 return BuildFloatToIntConversionInstruction( 1534 return BuildFloatToIntConversionInstruction(
1512 input, ExternalReference::wasm_float32_to_int64(jsgraph()->isolate()), 1535 input, ExternalReference::wasm_float32_to_int64(jsgraph()->isolate()),
1513 MachineRepresentation::kFloat32, MachineType::Int64()); 1536 MachineRepresentation::kFloat32, MachineType::Int64(), position);
1514 } else { 1537 } else {
1515 Node* trunc = graph()->NewNode( 1538 Node* trunc = graph()->NewNode(
1516 jsgraph()->machine()->TryTruncateFloat32ToInt64(), input); 1539 jsgraph()->machine()->TryTruncateFloat32ToInt64(), input);
1517 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); 1540 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
1518 Node* overflow = 1541 Node* overflow =
1519 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); 1542 graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
1520 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow); 1543 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position);
1521 return result; 1544 return result;
1522 } 1545 }
1523 } 1546 }
1524 1547
1525 Node* WasmGraphBuilder::BuildI64UConvertF32(Node* input) { 1548 Node* WasmGraphBuilder::BuildI64UConvertF32(Node* input,
1549 wasm::WasmCodePosition position) {
1526 if (jsgraph()->machine()->Is32()) { 1550 if (jsgraph()->machine()->Is32()) {
1527 return BuildFloatToIntConversionInstruction( 1551 return BuildFloatToIntConversionInstruction(
1528 input, ExternalReference::wasm_float32_to_uint64(jsgraph()->isolate()), 1552 input, ExternalReference::wasm_float32_to_uint64(jsgraph()->isolate()),
1529 MachineRepresentation::kFloat32, MachineType::Int64()); 1553 MachineRepresentation::kFloat32, MachineType::Int64(), position);
1530 } else { 1554 } else {
1531 Node* trunc = graph()->NewNode( 1555 Node* trunc = graph()->NewNode(
1532 jsgraph()->machine()->TryTruncateFloat32ToUint64(), input); 1556 jsgraph()->machine()->TryTruncateFloat32ToUint64(), input);
1533 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); 1557 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
1534 Node* overflow = 1558 Node* overflow =
1535 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); 1559 graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
1536 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow); 1560 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position);
1537 return result; 1561 return result;
1538 } 1562 }
1539 } 1563 }
1540 1564
1541 Node* WasmGraphBuilder::BuildI64SConvertF64(Node* input) { 1565 Node* WasmGraphBuilder::BuildI64SConvertF64(Node* input,
1566 wasm::WasmCodePosition position) {
1542 if (jsgraph()->machine()->Is32()) { 1567 if (jsgraph()->machine()->Is32()) {
1543 return BuildFloatToIntConversionInstruction( 1568 return BuildFloatToIntConversionInstruction(
1544 input, ExternalReference::wasm_float64_to_int64(jsgraph()->isolate()), 1569 input, ExternalReference::wasm_float64_to_int64(jsgraph()->isolate()),
1545 MachineRepresentation::kFloat64, MachineType::Int64()); 1570 MachineRepresentation::kFloat64, MachineType::Int64(), position);
1546 } else { 1571 } else {
1547 Node* trunc = graph()->NewNode( 1572 Node* trunc = graph()->NewNode(
1548 jsgraph()->machine()->TryTruncateFloat64ToInt64(), input); 1573 jsgraph()->machine()->TryTruncateFloat64ToInt64(), input);
1549 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); 1574 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
1550 Node* overflow = 1575 Node* overflow =
1551 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); 1576 graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
1552 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow); 1577 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position);
1553 return result; 1578 return result;
1554 } 1579 }
1555 } 1580 }
1556 1581
1557 Node* WasmGraphBuilder::BuildI64UConvertF64(Node* input) { 1582 Node* WasmGraphBuilder::BuildI64UConvertF64(Node* input,
1583 wasm::WasmCodePosition position) {
1558 if (jsgraph()->machine()->Is32()) { 1584 if (jsgraph()->machine()->Is32()) {
1559 return BuildFloatToIntConversionInstruction( 1585 return BuildFloatToIntConversionInstruction(
1560 input, ExternalReference::wasm_float64_to_uint64(jsgraph()->isolate()), 1586 input, ExternalReference::wasm_float64_to_uint64(jsgraph()->isolate()),
1561 MachineRepresentation::kFloat64, MachineType::Int64()); 1587 MachineRepresentation::kFloat64, MachineType::Int64(), position);
1562 } else { 1588 } else {
1563 Node* trunc = graph()->NewNode( 1589 Node* trunc = graph()->NewNode(
1564 jsgraph()->machine()->TryTruncateFloat64ToUint64(), input); 1590 jsgraph()->machine()->TryTruncateFloat64ToUint64(), input);
1565 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); 1591 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
1566 Node* overflow = 1592 Node* overflow =
1567 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); 1593 graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
1568 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow); 1594 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position);
1569 return result; 1595 return result;
1570 } 1596 }
1571 } 1597 }
1572 1598
1573 Node* WasmGraphBuilder::BuildFloatToIntConversionInstruction( 1599 Node* WasmGraphBuilder::BuildFloatToIntConversionInstruction(
1574 Node* input, ExternalReference ref, 1600 Node* input, ExternalReference ref,
1575 MachineRepresentation parameter_representation, 1601 MachineRepresentation parameter_representation,
1576 const MachineType result_type) { 1602 const MachineType result_type, wasm::WasmCodePosition position) {
1577 Node* stack_slot_param = graph()->NewNode( 1603 Node* stack_slot_param = graph()->NewNode(
1578 jsgraph()->machine()->StackSlot(parameter_representation)); 1604 jsgraph()->machine()->StackSlot(parameter_representation));
1579 Node* stack_slot_result = graph()->NewNode( 1605 Node* stack_slot_result = graph()->NewNode(
1580 jsgraph()->machine()->StackSlot(result_type.representation())); 1606 jsgraph()->machine()->StackSlot(result_type.representation()));
1581 const Operator* store_op = jsgraph()->machine()->Store( 1607 const Operator* store_op = jsgraph()->machine()->Store(
1582 StoreRepresentation(parameter_representation, kNoWriteBarrier)); 1608 StoreRepresentation(parameter_representation, kNoWriteBarrier));
1583 *effect_ = 1609 *effect_ =
1584 graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0), 1610 graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0),
1585 input, *effect_, *control_); 1611 input, *effect_, *control_);
1586 MachineSignature::Builder sig_builder(jsgraph()->zone(), 1, 2); 1612 MachineSignature::Builder sig_builder(jsgraph()->zone(), 1, 2);
1587 sig_builder.AddReturn(MachineType::Int32()); 1613 sig_builder.AddReturn(MachineType::Int32());
1588 sig_builder.AddParam(MachineType::Pointer()); 1614 sig_builder.AddParam(MachineType::Pointer());
1589 sig_builder.AddParam(MachineType::Pointer()); 1615 sig_builder.AddParam(MachineType::Pointer());
1590 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref)); 1616 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref));
1591 Node* args[] = {function, stack_slot_param, stack_slot_result}; 1617 Node* args[] = {function, stack_slot_param, stack_slot_result};
1592 trap_->ZeroCheck32(wasm::kTrapFloatUnrepresentable, 1618 trap_->ZeroCheck32(wasm::kTrapFloatUnrepresentable,
1593 BuildCCall(sig_builder.Build(), args)); 1619 BuildCCall(sig_builder.Build(), args), position);
1594 const Operator* load_op = jsgraph()->machine()->Load(result_type); 1620 const Operator* load_op = jsgraph()->machine()->Load(result_type);
1595 Node* load = 1621 Node* load =
1596 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0), 1622 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0),
1597 *effect_, *control_); 1623 *effect_, *control_);
1598 *effect_ = load; 1624 *effect_ = load;
1599 return load; 1625 return load;
1600 } 1626 }
1601 1627
1602 Node* WasmGraphBuilder::BuildI32DivS(Node* left, Node* right) { 1628 Node* WasmGraphBuilder::BuildI32DivS(Node* left, Node* right,
1629 wasm::WasmCodePosition position) {
1603 MachineOperatorBuilder* m = jsgraph()->machine(); 1630 MachineOperatorBuilder* m = jsgraph()->machine();
1604 if (module_ && module_->asm_js()) { 1631 if (module_ && module_->asm_js()) {
1605 // asm.js semantics return 0 on divide or mod by zero. 1632 // asm.js semantics return 0 on divide or mod by zero.
1606 if (m->Int32DivIsSafe()) { 1633 if (m->Int32DivIsSafe()) {
1607 // The hardware instruction does the right thing (e.g. arm). 1634 // The hardware instruction does the right thing (e.g. arm).
1608 return graph()->NewNode(m->Int32Div(), left, right, graph()->start()); 1635 return graph()->NewNode(m->Int32Div(), left, right, graph()->start());
1609 } 1636 }
1610 1637
1611 // Check denominator for zero. 1638 // Check denominator for zero.
1612 Diamond z( 1639 Diamond z(
1613 graph(), jsgraph()->common(), 1640 graph(), jsgraph()->common(),
1614 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(0)), 1641 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(0)),
1615 BranchHint::kFalse); 1642 BranchHint::kFalse);
1616 1643
1617 // Check numerator for -1. (avoid minint / -1 case). 1644 // Check numerator for -1. (avoid minint / -1 case).
1618 Diamond n( 1645 Diamond n(
1619 graph(), jsgraph()->common(), 1646 graph(), jsgraph()->common(),
1620 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)), 1647 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)),
1621 BranchHint::kFalse); 1648 BranchHint::kFalse);
1622 1649
1623 Node* div = graph()->NewNode(m->Int32Div(), left, right, z.if_false); 1650 Node* div = graph()->NewNode(m->Int32Div(), left, right, z.if_false);
1624 Node* neg = 1651 Node* neg =
1625 graph()->NewNode(m->Int32Sub(), jsgraph()->Int32Constant(0), left); 1652 graph()->NewNode(m->Int32Sub(), jsgraph()->Int32Constant(0), left);
1626 1653
1627 return n.Phi(MachineRepresentation::kWord32, neg, 1654 return n.Phi(MachineRepresentation::kWord32, neg,
1628 z.Phi(MachineRepresentation::kWord32, 1655 z.Phi(MachineRepresentation::kWord32,
1629 jsgraph()->Int32Constant(0), div)); 1656 jsgraph()->Int32Constant(0), div));
1630 } 1657 }
1631 1658
1632 trap_->ZeroCheck32(wasm::kTrapDivByZero, right); 1659 trap_->ZeroCheck32(wasm::kTrapDivByZero, right, position);
1633 Node* before = *control_; 1660 Node* before = *control_;
1634 Node* denom_is_m1; 1661 Node* denom_is_m1;
1635 Node* denom_is_not_m1; 1662 Node* denom_is_not_m1;
1636 Branch( 1663 Branch(
1637 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)), 1664 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)),
1638 &denom_is_m1, &denom_is_not_m1); 1665 &denom_is_m1, &denom_is_not_m1);
1639 *control_ = denom_is_m1; 1666 *control_ = denom_is_m1;
1640 trap_->TrapIfEq32(wasm::kTrapDivUnrepresentable, left, kMinInt); 1667 trap_->TrapIfEq32(wasm::kTrapDivUnrepresentable, left, kMinInt, position);
1641 if (*control_ != denom_is_m1) { 1668 if (*control_ != denom_is_m1) {
1642 *control_ = graph()->NewNode(jsgraph()->common()->Merge(2), denom_is_not_m1, 1669 *control_ = graph()->NewNode(jsgraph()->common()->Merge(2), denom_is_not_m1,
1643 *control_); 1670 *control_);
1644 } else { 1671 } else {
1645 *control_ = before; 1672 *control_ = before;
1646 } 1673 }
1647 return graph()->NewNode(m->Int32Div(), left, right, *control_); 1674 return graph()->NewNode(m->Int32Div(), left, right, *control_);
1648 } 1675 }
1649 1676
1650 Node* WasmGraphBuilder::BuildI32RemS(Node* left, Node* right) { 1677 Node* WasmGraphBuilder::BuildI32RemS(Node* left, Node* right,
1678 wasm::WasmCodePosition position) {
1651 MachineOperatorBuilder* m = jsgraph()->machine(); 1679 MachineOperatorBuilder* m = jsgraph()->machine();
1652 if (module_ && module_->asm_js()) { 1680 if (module_ && module_->asm_js()) {
1653 // asm.js semantics return 0 on divide or mod by zero. 1681 // asm.js semantics return 0 on divide or mod by zero.
1654 // Explicit check for x % 0. 1682 // Explicit check for x % 0.
1655 Diamond z( 1683 Diamond z(
1656 graph(), jsgraph()->common(), 1684 graph(), jsgraph()->common(),
1657 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(0)), 1685 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(0)),
1658 BranchHint::kFalse); 1686 BranchHint::kFalse);
1659 1687
1660 // Explicit check for x % -1. 1688 // Explicit check for x % -1.
1661 Diamond d( 1689 Diamond d(
1662 graph(), jsgraph()->common(), 1690 graph(), jsgraph()->common(),
1663 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)), 1691 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)),
1664 BranchHint::kFalse); 1692 BranchHint::kFalse);
1665 d.Chain(z.if_false); 1693 d.Chain(z.if_false);
1666 1694
1667 return z.Phi( 1695 return z.Phi(
1668 MachineRepresentation::kWord32, jsgraph()->Int32Constant(0), 1696 MachineRepresentation::kWord32, jsgraph()->Int32Constant(0),
1669 d.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0), 1697 d.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0),
1670 graph()->NewNode(m->Int32Mod(), left, right, d.if_false))); 1698 graph()->NewNode(m->Int32Mod(), left, right, d.if_false)));
1671 } 1699 }
1672 1700
1673 trap_->ZeroCheck32(wasm::kTrapRemByZero, right); 1701 trap_->ZeroCheck32(wasm::kTrapRemByZero, right, position);
1674 1702
1675 Diamond d( 1703 Diamond d(
1676 graph(), jsgraph()->common(), 1704 graph(), jsgraph()->common(),
1677 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)), 1705 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)),
1678 BranchHint::kFalse); 1706 BranchHint::kFalse);
1679 d.Chain(*control_); 1707 d.Chain(*control_);
1680 1708
1681 return d.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0), 1709 return d.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0),
1682 graph()->NewNode(m->Int32Mod(), left, right, d.if_false)); 1710 graph()->NewNode(m->Int32Mod(), left, right, d.if_false));
1683 } 1711 }
1684 1712
1685 Node* WasmGraphBuilder::BuildI32DivU(Node* left, Node* right) { 1713 Node* WasmGraphBuilder::BuildI32DivU(Node* left, Node* right,
1714 wasm::WasmCodePosition position) {
1686 MachineOperatorBuilder* m = jsgraph()->machine(); 1715 MachineOperatorBuilder* m = jsgraph()->machine();
1687 if (module_ && module_->asm_js()) { 1716 if (module_ && module_->asm_js()) {
1688 // asm.js semantics return 0 on divide or mod by zero. 1717 // asm.js semantics return 0 on divide or mod by zero.
1689 if (m->Uint32DivIsSafe()) { 1718 if (m->Uint32DivIsSafe()) {
1690 // The hardware instruction does the right thing (e.g. arm). 1719 // The hardware instruction does the right thing (e.g. arm).
1691 return graph()->NewNode(m->Uint32Div(), left, right, graph()->start()); 1720 return graph()->NewNode(m->Uint32Div(), left, right, graph()->start());
1692 } 1721 }
1693 1722
1694 // Explicit check for x % 0. 1723 // Explicit check for x % 0.
1695 Diamond z( 1724 Diamond z(
1696 graph(), jsgraph()->common(), 1725 graph(), jsgraph()->common(),
1697 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(0)), 1726 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(0)),
1698 BranchHint::kFalse); 1727 BranchHint::kFalse);
1699 1728
1700 return z.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0), 1729 return z.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0),
1701 graph()->NewNode(jsgraph()->machine()->Uint32Div(), left, 1730 graph()->NewNode(jsgraph()->machine()->Uint32Div(), left,
1702 right, z.if_false)); 1731 right, z.if_false));
1703 } 1732 }
1704 return graph()->NewNode(m->Uint32Div(), left, right, 1733 return graph()->NewNode(
1705 trap_->ZeroCheck32(wasm::kTrapDivByZero, right)); 1734 m->Uint32Div(), left, right,
1735 trap_->ZeroCheck32(wasm::kTrapDivByZero, right, position));
1706 } 1736 }
1707 1737
1708 Node* WasmGraphBuilder::BuildI32RemU(Node* left, Node* right) { 1738 Node* WasmGraphBuilder::BuildI32RemU(Node* left, Node* right,
1739 wasm::WasmCodePosition position) {
1709 MachineOperatorBuilder* m = jsgraph()->machine(); 1740 MachineOperatorBuilder* m = jsgraph()->machine();
1710 if (module_ && module_->asm_js()) { 1741 if (module_ && module_->asm_js()) {
1711 // asm.js semantics return 0 on divide or mod by zero. 1742 // asm.js semantics return 0 on divide or mod by zero.
1712 // Explicit check for x % 0. 1743 // Explicit check for x % 0.
1713 Diamond z( 1744 Diamond z(
1714 graph(), jsgraph()->common(), 1745 graph(), jsgraph()->common(),
1715 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(0)), 1746 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(0)),
1716 BranchHint::kFalse); 1747 BranchHint::kFalse);
1717 1748
1718 Node* rem = graph()->NewNode(jsgraph()->machine()->Uint32Mod(), left, right, 1749 Node* rem = graph()->NewNode(jsgraph()->machine()->Uint32Mod(), left, right,
1719 z.if_false); 1750 z.if_false);
1720 return z.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0), 1751 return z.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0),
1721 rem); 1752 rem);
1722 } 1753 }
1723 1754
1724 return graph()->NewNode(m->Uint32Mod(), left, right, 1755 return graph()->NewNode(
1725 trap_->ZeroCheck32(wasm::kTrapRemByZero, right)); 1756 m->Uint32Mod(), left, right,
1757 trap_->ZeroCheck32(wasm::kTrapRemByZero, right, position));
1726 } 1758 }
1727 1759
1728 Node* WasmGraphBuilder::BuildI64DivS(Node* left, Node* right) { 1760 Node* WasmGraphBuilder::BuildI64DivS(Node* left, Node* right,
1761 wasm::WasmCodePosition position) {
1729 if (jsgraph()->machine()->Is32()) { 1762 if (jsgraph()->machine()->Is32()) {
1730 return BuildDiv64Call( 1763 return BuildDiv64Call(
1731 left, right, ExternalReference::wasm_int64_div(jsgraph()->isolate()), 1764 left, right, ExternalReference::wasm_int64_div(jsgraph()->isolate()),
1732 MachineType::Int64(), wasm::kTrapDivByZero); 1765 MachineType::Int64(), wasm::kTrapDivByZero, position);
1733 } 1766 }
1734 trap_->ZeroCheck64(wasm::kTrapDivByZero, right); 1767 trap_->ZeroCheck64(wasm::kTrapDivByZero, right, position);
1735 Node* before = *control_; 1768 Node* before = *control_;
1736 Node* denom_is_m1; 1769 Node* denom_is_m1;
1737 Node* denom_is_not_m1; 1770 Node* denom_is_not_m1;
1738 Branch(graph()->NewNode(jsgraph()->machine()->Word64Equal(), right, 1771 Branch(graph()->NewNode(jsgraph()->machine()->Word64Equal(), right,
1739 jsgraph()->Int64Constant(-1)), 1772 jsgraph()->Int64Constant(-1)),
1740 &denom_is_m1, &denom_is_not_m1); 1773 &denom_is_m1, &denom_is_not_m1);
1741 *control_ = denom_is_m1; 1774 *control_ = denom_is_m1;
1742 trap_->TrapIfEq64(wasm::kTrapDivUnrepresentable, left, 1775 trap_->TrapIfEq64(wasm::kTrapDivUnrepresentable, left,
1743 std::numeric_limits<int64_t>::min()); 1776 std::numeric_limits<int64_t>::min(), position);
1744 if (*control_ != denom_is_m1) { 1777 if (*control_ != denom_is_m1) {
1745 *control_ = graph()->NewNode(jsgraph()->common()->Merge(2), denom_is_not_m1, 1778 *control_ = graph()->NewNode(jsgraph()->common()->Merge(2), denom_is_not_m1,
1746 *control_); 1779 *control_);
1747 } else { 1780 } else {
1748 *control_ = before; 1781 *control_ = before;
1749 } 1782 }
1750 return graph()->NewNode(jsgraph()->machine()->Int64Div(), left, right, 1783 return graph()->NewNode(jsgraph()->machine()->Int64Div(), left, right,
1751 *control_); 1784 *control_);
1752 } 1785 }
1753 1786
1754 Node* WasmGraphBuilder::BuildI64RemS(Node* left, Node* right) { 1787 Node* WasmGraphBuilder::BuildI64RemS(Node* left, Node* right,
1788 wasm::WasmCodePosition position) {
1755 if (jsgraph()->machine()->Is32()) { 1789 if (jsgraph()->machine()->Is32()) {
1756 return BuildDiv64Call( 1790 return BuildDiv64Call(
1757 left, right, ExternalReference::wasm_int64_mod(jsgraph()->isolate()), 1791 left, right, ExternalReference::wasm_int64_mod(jsgraph()->isolate()),
1758 MachineType::Int64(), wasm::kTrapRemByZero); 1792 MachineType::Int64(), wasm::kTrapRemByZero, position);
1759 } 1793 }
1760 trap_->ZeroCheck64(wasm::kTrapRemByZero, right); 1794 trap_->ZeroCheck64(wasm::kTrapRemByZero, right, position);
1761 Diamond d(jsgraph()->graph(), jsgraph()->common(), 1795 Diamond d(jsgraph()->graph(), jsgraph()->common(),
1762 graph()->NewNode(jsgraph()->machine()->Word64Equal(), right, 1796 graph()->NewNode(jsgraph()->machine()->Word64Equal(), right,
1763 jsgraph()->Int64Constant(-1))); 1797 jsgraph()->Int64Constant(-1)));
1764 1798
1765 Node* rem = graph()->NewNode(jsgraph()->machine()->Int64Mod(), left, right, 1799 Node* rem = graph()->NewNode(jsgraph()->machine()->Int64Mod(), left, right,
1766 d.if_false); 1800 d.if_false);
1767 1801
1768 return d.Phi(MachineRepresentation::kWord64, jsgraph()->Int64Constant(0), 1802 return d.Phi(MachineRepresentation::kWord64, jsgraph()->Int64Constant(0),
1769 rem); 1803 rem);
1770 } 1804 }
1771 1805
1772 Node* WasmGraphBuilder::BuildI64DivU(Node* left, Node* right) { 1806 Node* WasmGraphBuilder::BuildI64DivU(Node* left, Node* right,
1807 wasm::WasmCodePosition position) {
1773 if (jsgraph()->machine()->Is32()) { 1808 if (jsgraph()->machine()->Is32()) {
1774 return BuildDiv64Call( 1809 return BuildDiv64Call(
1775 left, right, ExternalReference::wasm_uint64_div(jsgraph()->isolate()), 1810 left, right, ExternalReference::wasm_uint64_div(jsgraph()->isolate()),
1776 MachineType::Int64(), wasm::kTrapDivByZero); 1811 MachineType::Int64(), wasm::kTrapDivByZero, position);
1777 } 1812 }
1778 return graph()->NewNode(jsgraph()->machine()->Uint64Div(), left, right, 1813 return graph()->NewNode(
1779 trap_->ZeroCheck64(wasm::kTrapDivByZero, right)); 1814 jsgraph()->machine()->Uint64Div(), left, right,
1815 trap_->ZeroCheck64(wasm::kTrapDivByZero, right, position));
1780 } 1816 }
1781 Node* WasmGraphBuilder::BuildI64RemU(Node* left, Node* right) { 1817 Node* WasmGraphBuilder::BuildI64RemU(Node* left, Node* right,
1818 wasm::WasmCodePosition position) {
1782 if (jsgraph()->machine()->Is32()) { 1819 if (jsgraph()->machine()->Is32()) {
1783 return BuildDiv64Call( 1820 return BuildDiv64Call(
1784 left, right, ExternalReference::wasm_uint64_mod(jsgraph()->isolate()), 1821 left, right, ExternalReference::wasm_uint64_mod(jsgraph()->isolate()),
1785 MachineType::Int64(), wasm::kTrapRemByZero); 1822 MachineType::Int64(), wasm::kTrapRemByZero, position);
1786 } 1823 }
1787 return graph()->NewNode(jsgraph()->machine()->Uint64Mod(), left, right, 1824 return graph()->NewNode(
1788 trap_->ZeroCheck64(wasm::kTrapRemByZero, right)); 1825 jsgraph()->machine()->Uint64Mod(), left, right,
1826 trap_->ZeroCheck64(wasm::kTrapRemByZero, right, position));
1789 } 1827 }
1790 1828
1791 Node* WasmGraphBuilder::BuildDiv64Call(Node* left, Node* right, 1829 Node* WasmGraphBuilder::BuildDiv64Call(Node* left, Node* right,
1792 ExternalReference ref, 1830 ExternalReference ref,
1793 MachineType result_type, int trap_zero) { 1831 MachineType result_type, int trap_zero,
1832 wasm::WasmCodePosition position) {
1794 Node* stack_slot_dst = graph()->NewNode( 1833 Node* stack_slot_dst = graph()->NewNode(
1795 jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64)); 1834 jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64));
1796 Node* stack_slot_src = graph()->NewNode( 1835 Node* stack_slot_src = graph()->NewNode(
1797 jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64)); 1836 jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64));
1798 1837
1799 const Operator* store_op = jsgraph()->machine()->Store( 1838 const Operator* store_op = jsgraph()->machine()->Store(
1800 StoreRepresentation(MachineRepresentation::kWord64, kNoWriteBarrier)); 1839 StoreRepresentation(MachineRepresentation::kWord64, kNoWriteBarrier));
1801 *effect_ = 1840 *effect_ =
1802 graph()->NewNode(store_op, stack_slot_dst, jsgraph()->Int32Constant(0), 1841 graph()->NewNode(store_op, stack_slot_dst, jsgraph()->Int32Constant(0),
1803 left, *effect_, *control_); 1842 left, *effect_, *control_);
1804 *effect_ = 1843 *effect_ =
1805 graph()->NewNode(store_op, stack_slot_src, jsgraph()->Int32Constant(0), 1844 graph()->NewNode(store_op, stack_slot_src, jsgraph()->Int32Constant(0),
1806 right, *effect_, *control_); 1845 right, *effect_, *control_);
1807 1846
1808 MachineSignature::Builder sig_builder(jsgraph()->zone(), 1, 2); 1847 MachineSignature::Builder sig_builder(jsgraph()->zone(), 1, 2);
1809 sig_builder.AddReturn(MachineType::Int32()); 1848 sig_builder.AddReturn(MachineType::Int32());
1810 sig_builder.AddParam(MachineType::Pointer()); 1849 sig_builder.AddParam(MachineType::Pointer());
1811 sig_builder.AddParam(MachineType::Pointer()); 1850 sig_builder.AddParam(MachineType::Pointer());
1812 1851
1813 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref)); 1852 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref));
1814 Node* args[] = {function, stack_slot_dst, stack_slot_src}; 1853 Node* args[] = {function, stack_slot_dst, stack_slot_src};
1815 1854
1816 Node* call = BuildCCall(sig_builder.Build(), args); 1855 Node* call = BuildCCall(sig_builder.Build(), args);
1817 1856
1818 // TODO(wasm): This can get simpler if we have a specialized runtime call to 1857 // TODO(wasm): This can get simpler if we have a specialized runtime call to
1819 // throw WASM exceptions by trap code instead of by string. 1858 // throw WASM exceptions by trap code instead of by string.
1820 trap_->ZeroCheck32(static_cast<wasm::TrapReason>(trap_zero), call); 1859 trap_->ZeroCheck32(static_cast<wasm::TrapReason>(trap_zero), call, position);
1821 trap_->TrapIfEq32(wasm::kTrapDivUnrepresentable, call, -1); 1860 trap_->TrapIfEq32(wasm::kTrapDivUnrepresentable, call, -1, position);
1822 const Operator* load_op = jsgraph()->machine()->Load(result_type); 1861 const Operator* load_op = jsgraph()->machine()->Load(result_type);
1823 Node* load = 1862 Node* load =
1824 graph()->NewNode(load_op, stack_slot_dst, jsgraph()->Int32Constant(0), 1863 graph()->NewNode(load_op, stack_slot_dst, jsgraph()->Int32Constant(0),
1825 *effect_, *control_); 1864 *effect_, *control_);
1826 *effect_ = load; 1865 *effect_ = load;
1827 return load; 1866 return load;
1828 } 1867 }
1829 1868
1830 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) { 1869 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) {
1831 const size_t params = sig->parameter_count(); 1870 const size_t params = sig->parameter_count();
1832 const size_t extra = 2; // effect and control inputs. 1871 const size_t extra = 2; // effect and control inputs.
1833 const size_t count = 1 + params + extra; 1872 const size_t count = 1 + params + extra;
1834 1873
1835 // Reallocate the buffer to make space for extra inputs. 1874 // Reallocate the buffer to make space for extra inputs.
1836 args = Realloc(args, 1 + params, count); 1875 args = Realloc(args, 1 + params, count);
1837 1876
1838 // Add effect and control inputs. 1877 // Add effect and control inputs.
1839 args[params + 1] = *effect_; 1878 args[params + 1] = *effect_;
1840 args[params + 2] = *control_; 1879 args[params + 2] = *control_;
1841 1880
1842 CallDescriptor* desc = 1881 CallDescriptor* desc =
1843 Linkage::GetSimplifiedCDescriptor(jsgraph()->zone(), sig); 1882 Linkage::GetSimplifiedCDescriptor(jsgraph()->zone(), sig);
1844 1883
1845 const Operator* op = jsgraph()->common()->Call(desc); 1884 const Operator* op = jsgraph()->common()->Call(desc);
1846 Node* call = graph()->NewNode(op, static_cast<int>(count), args); 1885 Node* call = graph()->NewNode(op, static_cast<int>(count), args);
1847 *effect_ = call; 1886 *effect_ = call;
1848 return call; 1887 return call;
1849 } 1888 }
1850 1889
1851 Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args) { 1890 Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args,
1891 wasm::WasmCodePosition position) {
1852 const size_t params = sig->parameter_count(); 1892 const size_t params = sig->parameter_count();
1853 const size_t extra = 2; // effect and control inputs. 1893 const size_t extra = 2; // effect and control inputs.
1854 const size_t count = 1 + params + extra; 1894 const size_t count = 1 + params + extra;
1855 1895
1856 // Reallocate the buffer to make space for extra inputs. 1896 // Reallocate the buffer to make space for extra inputs.
1857 args = Realloc(args, 1 + params, count); 1897 args = Realloc(args, 1 + params, count);
1858 1898
1859 // Add effect and control inputs. 1899 // Add effect and control inputs.
1860 args[params + 1] = *effect_; 1900 args[params + 1] = *effect_;
1861 args[params + 2] = *control_; 1901 args[params + 2] = *control_;
1862 1902
1863 CallDescriptor* descriptor = 1903 CallDescriptor* descriptor =
1864 wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig); 1904 wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig);
1865 const Operator* op = jsgraph()->common()->Call(descriptor); 1905 const Operator* op = jsgraph()->common()->Call(descriptor);
1866 Node* call = graph()->NewNode(op, static_cast<int>(count), args); 1906 Node* call = graph()->NewNode(op, static_cast<int>(count), args);
1907 SetSourcePosition(call, position);
1867 1908
1868 *effect_ = call; 1909 *effect_ = call;
1869 return call; 1910 return call;
1870 } 1911 }
1871 1912
1872 Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args) { 1913 Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args,
1914 wasm::WasmCodePosition position) {
1873 DCHECK_NULL(args[0]); 1915 DCHECK_NULL(args[0]);
1874 1916
1875 // Add code object as constant. 1917 // Add code object as constant.
1876 args[0] = Constant(module_->GetFunctionCode(index)); 1918 args[0] = Constant(module_->GetFunctionCode(index));
1877 wasm::FunctionSig* sig = module_->GetFunctionSignature(index); 1919 wasm::FunctionSig* sig = module_->GetFunctionSignature(index);
1878 1920
1879 return BuildWasmCall(sig, args); 1921 return BuildWasmCall(sig, args, position);
1880 } 1922 }
1881 1923
1882 Node* WasmGraphBuilder::CallImport(uint32_t index, Node** args) { 1924 Node* WasmGraphBuilder::CallImport(uint32_t index, Node** args,
1925 wasm::WasmCodePosition position) {
1883 DCHECK_NULL(args[0]); 1926 DCHECK_NULL(args[0]);
1884 1927
1885 // Add code object as constant. 1928 // Add code object as constant.
1886 args[0] = Constant(module_->GetImportCode(index)); 1929 args[0] = Constant(module_->GetImportCode(index));
1887 wasm::FunctionSig* sig = module_->GetImportSignature(index); 1930 wasm::FunctionSig* sig = module_->GetImportSignature(index);
1888 1931
1889 return BuildWasmCall(sig, args); 1932 return BuildWasmCall(sig, args, position);
1890 } 1933 }
1891 1934
1892 Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args) { 1935 Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args,
1936 wasm::WasmCodePosition position) {
1893 DCHECK_NOT_NULL(args[0]); 1937 DCHECK_NOT_NULL(args[0]);
1894 DCHECK(module_ && module_->instance); 1938 DCHECK(module_ && module_->instance);
1895 1939
1896 MachineOperatorBuilder* machine = jsgraph()->machine(); 1940 MachineOperatorBuilder* machine = jsgraph()->machine();
1897 1941
1898 // Compute the code object by loading it from the function table. 1942 // Compute the code object by loading it from the function table.
1899 Node* key = args[0]; 1943 Node* key = args[0];
1900 1944
1901 // Bounds check the index. 1945 // Bounds check the index.
1902 int table_size = static_cast<int>(module_->FunctionTableSize()); 1946 int table_size = static_cast<int>(module_->FunctionTableSize());
1903 if (table_size > 0) { 1947 if (table_size > 0) {
1904 // Bounds check against the table size. 1948 // Bounds check against the table size.
1905 Node* size = Int32Constant(static_cast<int>(table_size)); 1949 Node* size = Int32Constant(static_cast<int>(table_size));
1906 Node* in_bounds = graph()->NewNode(machine->Uint32LessThan(), key, size); 1950 Node* in_bounds = graph()->NewNode(machine->Uint32LessThan(), key, size);
1907 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, in_bounds); 1951 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, in_bounds, position);
1908 } else { 1952 } else {
1909 // No function table. Generate a trap and return a constant. 1953 // No function table. Generate a trap and return a constant.
1910 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0)); 1954 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0), position);
1911 return trap_->GetTrapValue(module_->GetSignature(index)); 1955 return trap_->GetTrapValue(module_->GetSignature(index));
1912 } 1956 }
1913 Node* table = FunctionTable(); 1957 Node* table = FunctionTable();
1914 1958
1915 // Load signature from the table and check. 1959 // Load signature from the table and check.
1916 // The table is a FixedArray; signatures are encoded as SMIs. 1960 // The table is a FixedArray; signatures are encoded as SMIs.
1917 // [sig1, sig2, sig3, ...., code1, code2, code3 ...] 1961 // [sig1, sig2, sig3, ...., code1, code2, code3 ...]
1918 ElementAccess access = AccessBuilder::ForFixedArrayElement(); 1962 ElementAccess access = AccessBuilder::ForFixedArrayElement();
1919 const int fixed_offset = access.header_size - access.tag(); 1963 const int fixed_offset = access.header_size - access.tag();
1920 { 1964 {
1921 Node* load_sig = graph()->NewNode( 1965 Node* load_sig = graph()->NewNode(
1922 machine->Load(MachineType::AnyTagged()), table, 1966 machine->Load(MachineType::AnyTagged()), table,
1923 graph()->NewNode(machine->Int32Add(), 1967 graph()->NewNode(machine->Int32Add(),
1924 graph()->NewNode(machine->Word32Shl(), key, 1968 graph()->NewNode(machine->Word32Shl(), key,
1925 Int32Constant(kPointerSizeLog2)), 1969 Int32Constant(kPointerSizeLog2)),
1926 Int32Constant(fixed_offset)), 1970 Int32Constant(fixed_offset)),
1927 *effect_, *control_); 1971 *effect_, *control_);
1928 Node* sig_match = graph()->NewNode(machine->WordEqual(), load_sig, 1972 Node* sig_match = graph()->NewNode(machine->WordEqual(), load_sig,
1929 jsgraph()->SmiConstant(index)); 1973 jsgraph()->SmiConstant(index));
1930 trap_->AddTrapIfFalse(wasm::kTrapFuncSigMismatch, sig_match); 1974 trap_->AddTrapIfFalse(wasm::kTrapFuncSigMismatch, sig_match, position);
1931 } 1975 }
1932 1976
1933 // Load code object from the table. 1977 // Load code object from the table.
1934 int offset = fixed_offset + kPointerSize * table_size; 1978 int offset = fixed_offset + kPointerSize * table_size;
1935 Node* load_code = graph()->NewNode( 1979 Node* load_code = graph()->NewNode(
1936 machine->Load(MachineType::AnyTagged()), table, 1980 machine->Load(MachineType::AnyTagged()), table,
1937 graph()->NewNode(machine->Int32Add(), 1981 graph()->NewNode(machine->Int32Add(),
1938 graph()->NewNode(machine->Word32Shl(), key, 1982 graph()->NewNode(machine->Word32Shl(), key,
1939 Int32Constant(kPointerSizeLog2)), 1983 Int32Constant(kPointerSizeLog2)),
1940 Int32Constant(offset)), 1984 Int32Constant(offset)),
1941 *effect_, *control_); 1985 *effect_, *control_);
1942 1986
1943 args[0] = load_code; 1987 args[0] = load_code;
1944 wasm::FunctionSig* sig = module_->GetSignature(index); 1988 wasm::FunctionSig* sig = module_->GetSignature(index);
1945 return BuildWasmCall(sig, args); 1989 return BuildWasmCall(sig, args, position);
1946 } 1990 }
1947 1991
1948 Node* WasmGraphBuilder::BuildI32Rol(Node* left, Node* right) { 1992 Node* WasmGraphBuilder::BuildI32Rol(Node* left, Node* right) {
1949 // Implement Rol by Ror since TurboFan does not have Rol opcode. 1993 // Implement Rol by Ror since TurboFan does not have Rol opcode.
1950 // TODO(weiliang): support Word32Rol opcode in TurboFan. 1994 // TODO(weiliang): support Word32Rol opcode in TurboFan.
1951 Int32Matcher m(right); 1995 Int32Matcher m(right);
1952 if (m.HasValue()) { 1996 if (m.HasValue()) {
1953 return Binop(wasm::kExprI32Ror, left, 1997 return Binop(wasm::kExprI32Ror, left,
1954 jsgraph()->Int32Constant(32 - m.Value())); 1998 jsgraph()->Int32Constant(32 - m.Value()));
1955 } else { 1999 } else {
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after
2554 reinterpret_cast<uintptr_t>(module_->instance->globals_start + 2598 reinterpret_cast<uintptr_t>(module_->instance->globals_start +
2555 module_->module->globals[index].offset)); 2599 module_->module->globals[index].offset));
2556 const Operator* op = jsgraph()->machine()->Store( 2600 const Operator* op = jsgraph()->machine()->Store(
2557 StoreRepresentation(mem_type.representation(), kNoWriteBarrier)); 2601 StoreRepresentation(mem_type.representation(), kNoWriteBarrier));
2558 Node* node = graph()->NewNode(op, addr, jsgraph()->Int32Constant(0), val, 2602 Node* node = graph()->NewNode(op, addr, jsgraph()->Int32Constant(0), val,
2559 *effect_, *control_); 2603 *effect_, *control_);
2560 *effect_ = node; 2604 *effect_ = node;
2561 return node; 2605 return node;
2562 } 2606 }
2563 2607
2564
2565 void WasmGraphBuilder::BoundsCheckMem(MachineType memtype, Node* index, 2608 void WasmGraphBuilder::BoundsCheckMem(MachineType memtype, Node* index,
2566 uint32_t offset) { 2609 uint32_t offset,
2610 wasm::WasmCodePosition position) {
2567 // TODO(turbofan): fold bounds checks for constant indexes. 2611 // TODO(turbofan): fold bounds checks for constant indexes.
2568 DCHECK(module_ && module_->instance); 2612 DCHECK(module_ && module_->instance);
2569 size_t size = module_->instance->mem_size; 2613 size_t size = module_->instance->mem_size;
2570 byte memsize = wasm::WasmOpcodes::MemSize(memtype); 2614 byte memsize = wasm::WasmOpcodes::MemSize(memtype);
2571 Node* cond; 2615 Node* cond;
2572 if (offset >= size || (static_cast<uint64_t>(offset) + memsize) > size) { 2616 if (offset >= size || (static_cast<uint64_t>(offset) + memsize) > size) {
2573 // The access will always throw. 2617 // The access will always throw.
2574 cond = jsgraph()->Int32Constant(0); 2618 cond = jsgraph()->Int32Constant(0);
2575 } else { 2619 } else {
2576 // Check against the limit. 2620 // Check against the limit.
2577 size_t limit = size - offset - memsize; 2621 size_t limit = size - offset - memsize;
2578 CHECK(limit <= kMaxUInt32); 2622 CHECK(limit <= kMaxUInt32);
2579 cond = graph()->NewNode( 2623 cond = graph()->NewNode(
2580 jsgraph()->machine()->Uint32LessThanOrEqual(), index, 2624 jsgraph()->machine()->Uint32LessThanOrEqual(), index,
2581 jsgraph()->Int32Constant(static_cast<uint32_t>(limit))); 2625 jsgraph()->Int32Constant(static_cast<uint32_t>(limit)));
2582 } 2626 }
2583 2627
2584 trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, cond); 2628 trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, cond, position);
2585 } 2629 }
2586 2630
2587
2588 Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype, 2631 Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype,
2589 Node* index, uint32_t offset) { 2632 Node* index, uint32_t offset,
2633 wasm::WasmCodePosition position) {
2590 Node* load; 2634 Node* load;
2591 2635
2592 if (module_ && module_->asm_js()) { 2636 if (module_ && module_->asm_js()) {
2593 // asm.js semantics use CheckedLoad (i.e. OOB reads return 0ish). 2637 // asm.js semantics use CheckedLoad (i.e. OOB reads return 0ish).
2594 DCHECK_EQ(0, offset); 2638 DCHECK_EQ(0, offset);
2595 const Operator* op = jsgraph()->machine()->CheckedLoad(memtype); 2639 const Operator* op = jsgraph()->machine()->CheckedLoad(memtype);
2596 load = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), *effect_, 2640 load = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), *effect_,
2597 *control_); 2641 *control_);
2598 } else { 2642 } else {
2599 // WASM semantics throw on OOB. Introduce explicit bounds check. 2643 // WASM semantics throw on OOB. Introduce explicit bounds check.
2600 BoundsCheckMem(memtype, index, offset); 2644 BoundsCheckMem(memtype, index, offset, position);
2601 load = graph()->NewNode(jsgraph()->machine()->Load(memtype), 2645 load = graph()->NewNode(jsgraph()->machine()->Load(memtype),
2602 MemBuffer(offset), index, *effect_, *control_); 2646 MemBuffer(offset), index, *effect_, *control_);
2603 } 2647 }
2604 2648
2605 *effect_ = load; 2649 *effect_ = load;
2606 2650
2607 if (type == wasm::kAstI64 && 2651 if (type == wasm::kAstI64 &&
2608 ElementSizeLog2Of(memtype.representation()) < 3) { 2652 ElementSizeLog2Of(memtype.representation()) < 3) {
2609 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes. 2653 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes.
2610 if (memtype.IsSigned()) { 2654 if (memtype.IsSigned()) {
2611 // sign extend 2655 // sign extend
2612 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load); 2656 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load);
2613 } else { 2657 } else {
2614 // zero extend 2658 // zero extend
2615 load = 2659 load =
2616 graph()->NewNode(jsgraph()->machine()->ChangeUint32ToUint64(), load); 2660 graph()->NewNode(jsgraph()->machine()->ChangeUint32ToUint64(), load);
2617 } 2661 }
2618 } 2662 }
2619 2663
2620 return load; 2664 return load;
2621 } 2665 }
2622 2666
2623
2624 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index, 2667 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index,
2625 uint32_t offset, Node* val) { 2668 uint32_t offset, Node* val,
2669 wasm::WasmCodePosition position) {
2626 Node* store; 2670 Node* store;
2627 if (module_ && module_->asm_js()) { 2671 if (module_ && module_->asm_js()) {
2628 // asm.js semantics use CheckedStore (i.e. ignore OOB writes). 2672 // asm.js semantics use CheckedStore (i.e. ignore OOB writes).
2629 DCHECK_EQ(0, offset); 2673 DCHECK_EQ(0, offset);
2630 const Operator* op = 2674 const Operator* op =
2631 jsgraph()->machine()->CheckedStore(memtype.representation()); 2675 jsgraph()->machine()->CheckedStore(memtype.representation());
2632 store = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), val, *effect_, 2676 store = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), val, *effect_,
2633 *control_); 2677 *control_);
2634 } else { 2678 } else {
2635 // WASM semantics throw on OOB. Introduce explicit bounds check. 2679 // WASM semantics throw on OOB. Introduce explicit bounds check.
2636 BoundsCheckMem(memtype, index, offset); 2680 BoundsCheckMem(memtype, index, offset, position);
2637 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); 2681 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier);
2638 store = 2682 store =
2639 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset), 2683 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset),
2640 index, val, *effect_, *control_); 2684 index, val, *effect_, *control_);
2641 } 2685 }
2642 *effect_ = store; 2686 *effect_ = store;
2643 return store; 2687 return store;
2644 } 2688 }
2645 2689
2646 2690
(...skipping 12 matching lines...) Expand all
2659 2703
2660 void WasmGraphBuilder::Int64LoweringForTesting() { 2704 void WasmGraphBuilder::Int64LoweringForTesting() {
2661 if (jsgraph()->machine()->Is32()) { 2705 if (jsgraph()->machine()->Is32()) {
2662 Int64Lowering r(jsgraph()->graph(), jsgraph()->machine(), 2706 Int64Lowering r(jsgraph()->graph(), jsgraph()->machine(),
2663 jsgraph()->common(), jsgraph()->zone(), 2707 jsgraph()->common(), jsgraph()->zone(),
2664 function_signature_); 2708 function_signature_);
2665 r.LowerGraph(); 2709 r.LowerGraph();
2666 } 2710 }
2667 } 2711 }
2668 2712
2669 void WasmGraphBuilder::SetSourcePosition(Node* node, int position) { 2713 void WasmGraphBuilder::SetSourcePosition(Node* node,
2714 wasm::WasmCodePosition position) {
2715 DCHECK_NE(position, wasm::kNoCodePosition);
2670 compiler::SourcePosition pos(position); 2716 compiler::SourcePosition pos(position);
2671 if (source_position_table_) 2717 if (source_position_table_)
2672 source_position_table_->SetSourcePosition(node, pos); 2718 source_position_table_->SetSourcePosition(node, pos);
2673 } 2719 }
2674 2720
2675 static void RecordFunctionCompilation(Logger::LogEventsAndTags tag, 2721 static void RecordFunctionCompilation(Logger::LogEventsAndTags tag,
2676 CompilationInfo* info, 2722 CompilationInfo* info,
2677 const char* message, uint32_t index, 2723 const char* message, uint32_t index,
2678 wasm::WasmName func_name) { 2724 wasm::WasmName func_name) {
2679 Isolate* isolate = info->isolate(); 2725 Isolate* isolate = info->isolate();
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
3057 3103
3058 Handle<Code> FinishCompilation(WasmCompilationUnit* unit) { 3104 Handle<Code> FinishCompilation(WasmCompilationUnit* unit) {
3059 Handle<Code> result = unit->FinishCompilation(); 3105 Handle<Code> result = unit->FinishCompilation();
3060 delete unit; 3106 delete unit;
3061 return result; 3107 return result;
3062 } 3108 }
3063 3109
3064 } // namespace compiler 3110 } // namespace compiler
3065 } // namespace internal 3111 } // namespace internal
3066 } // namespace v8 3112 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/runtime/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698