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

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

Issue 1648503003: [wasm] Fix CallIndirect with the case of no indirect function table. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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 | « no previous file | src/wasm/wasm-module.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/platform.h" 9 #include "src/base/platform/platform.h"
10 10
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 explicit WasmTrapHelper(WasmGraphBuilder* builder) 98 explicit WasmTrapHelper(WasmGraphBuilder* builder)
99 : builder_(builder), 99 : builder_(builder),
100 jsgraph_(builder->jsgraph()), 100 jsgraph_(builder->jsgraph()),
101 graph_(builder->jsgraph() ? builder->jsgraph()->graph() : nullptr) { 101 graph_(builder->jsgraph() ? builder->jsgraph()->graph() : nullptr) {
102 for (int i = 0; i < kTrapCount; i++) traps_[i] = nullptr; 102 for (int i = 0; i < kTrapCount; i++) traps_[i] = nullptr;
103 } 103 }
104 104
105 // Make the current control path trap to unreachable. 105 // Make the current control path trap to unreachable.
106 void Unreachable() { ConnectTrap(kTrapUnreachable); } 106 void Unreachable() { ConnectTrap(kTrapUnreachable); }
107 107
108 // Always trap with the given reason.
109 void TrapAlways(TrapReason reason) { ConnectTrap(reason); }
110
108 // Add a check that traps if {node} is equal to {val}. 111 // Add a check that traps if {node} is equal to {val}.
109 Node* TrapIfEq32(TrapReason reason, Node* node, int32_t val) { 112 Node* TrapIfEq32(TrapReason reason, Node* node, int32_t val) {
110 Int32Matcher m(node); 113 Int32Matcher m(node);
111 if (m.HasValue() && !m.Is(val)) return graph()->start(); 114 if (m.HasValue() && !m.Is(val)) return graph()->start();
112 if (val == 0) { 115 if (val == 0) {
113 AddTrapIfFalse(reason, node); 116 AddTrapIfFalse(reason, node);
114 } else { 117 } else {
115 AddTrapIfTrue(reason, 118 AddTrapIfTrue(reason,
116 graph()->NewNode(jsgraph()->machine()->Word32Equal(), node, 119 graph()->NewNode(jsgraph()->machine()->Word32Equal(), node,
117 jsgraph()->Int32Constant(val))); 120 jsgraph()->Int32Constant(val)));
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 Node* branch = graph()->NewNode(common()->Branch(hint), cond, *control_ptr); 161 Node* branch = graph()->NewNode(common()->Branch(hint), cond, *control_ptr);
159 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 162 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
160 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 163 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
161 164
162 *control_ptr = iftrue ? if_true : if_false; 165 *control_ptr = iftrue ? if_true : if_false;
163 ConnectTrap(reason); 166 ConnectTrap(reason);
164 *control_ptr = iftrue ? if_false : if_true; 167 *control_ptr = iftrue ? if_false : if_true;
165 *effect_ptr = before; 168 *effect_ptr = before;
166 } 169 }
167 170
171 Node* GetTrapValue(wasm::FunctionSig* sig) {
172 if (sig->return_count() > 0) {
173 switch (sig->GetReturn()) {
174 case wasm::kAstI32:
175 return jsgraph()->Int32Constant(0xdeadbeef);
176 case wasm::kAstI64:
177 return jsgraph()->Int64Constant(0xdeadbeefdeadbeef);
178 case wasm::kAstF32:
179 return jsgraph()->Float32Constant(bit_cast<float>(0xdeadbeef));
180 case wasm::kAstF64:
181 return jsgraph()->Float64Constant(
182 bit_cast<double>(0xdeadbeefdeadbeef));
183 break;
184 default:
185 UNREACHABLE();
186 return nullptr;
187 }
188 } else {
189 return jsgraph()->Int32Constant(0xdeadbeef);
190 }
191 }
192
168 private: 193 private:
169 WasmGraphBuilder* builder_; 194 WasmGraphBuilder* builder_;
170 JSGraph* jsgraph_; 195 JSGraph* jsgraph_;
171 Graph* graph_; 196 Graph* graph_;
172 Node* traps_[kTrapCount]; 197 Node* traps_[kTrapCount];
173 Node* effects_[kTrapCount]; 198 Node* effects_[kTrapCount];
174 199
175 JSGraph* jsgraph() { return jsgraph_; } 200 JSGraph* jsgraph() { return jsgraph_; }
176 Graph* graph() { return jsgraph_->graph(); } 201 Graph* graph() { return jsgraph_->graph(); }
177 CommonOperatorBuilder* common() { return jsgraph()->common(); } 202 CommonOperatorBuilder* common() { return jsgraph()->common(); }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 *effect_ptr = node; 245 *effect_ptr = node;
221 } 246 }
222 if (false) { 247 if (false) {
223 // End the control flow with a throw 248 // End the control flow with a throw
224 Node* thrw = 249 Node* thrw =
225 graph()->NewNode(common()->Throw(), jsgraph()->ZeroConstant(), 250 graph()->NewNode(common()->Throw(), jsgraph()->ZeroConstant(),
226 *effect_ptr, *control_ptr); 251 *effect_ptr, *control_ptr);
227 end = thrw; 252 end = thrw;
228 } else { 253 } else {
229 // End the control flow with returning 0xdeadbeef 254 // End the control flow with returning 0xdeadbeef
230 Node* ret_value; 255 Node* ret_value = GetTrapValue(builder_->GetFunctionSignature());
231 if (builder_->GetFunctionSignature()->return_count() > 0) {
232 switch (builder_->GetFunctionSignature()->GetReturn()) {
233 case wasm::kAstI32:
234 ret_value = jsgraph()->Int32Constant(0xdeadbeef);
235 break;
236 case wasm::kAstI64:
237 ret_value = jsgraph()->Int64Constant(0xdeadbeefdeadbeef);
238 break;
239 case wasm::kAstF32:
240 ret_value = jsgraph()->Float32Constant(bit_cast<float>(0xdeadbeef));
241 break;
242 case wasm::kAstF64:
243 ret_value = jsgraph()->Float64Constant(
244 bit_cast<double>(0xdeadbeefdeadbeef));
245 break;
246 default:
247 UNREACHABLE();
248 ret_value = nullptr;
249 }
250 } else {
251 ret_value = jsgraph()->Int32Constant(0xdeadbeef);
252 }
253 end = graph()->NewNode(jsgraph()->common()->Return(), ret_value, 256 end = graph()->NewNode(jsgraph()->common()->Return(), ret_value,
254 *effect_ptr, *control_ptr); 257 *effect_ptr, *control_ptr);
255 } 258 }
256 259
257 MergeControlToEnd(jsgraph(), end); 260 MergeControlToEnd(jsgraph(), end);
258 } 261 }
259 }; 262 };
260 263
261 264
262 WasmGraphBuilder::WasmGraphBuilder(Zone* zone, JSGraph* jsgraph, 265 WasmGraphBuilder::WasmGraphBuilder(Zone* zone, JSGraph* jsgraph,
(...skipping 1195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1458 // Add code object as constant. 1461 // Add code object as constant.
1459 args[0] = Constant(module_->GetFunctionCode(index)); 1462 args[0] = Constant(module_->GetFunctionCode(index));
1460 wasm::FunctionSig* sig = module_->GetFunctionSignature(index); 1463 wasm::FunctionSig* sig = module_->GetFunctionSignature(index);
1461 1464
1462 return BuildWasmCall(sig, args); 1465 return BuildWasmCall(sig, args);
1463 } 1466 }
1464 1467
1465 1468
1466 Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args) { 1469 Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args) {
1467 DCHECK_NOT_NULL(args[0]); 1470 DCHECK_NOT_NULL(args[0]);
1471 DCHECK(module_ && module_->instance);
1468 1472
1469 MachineOperatorBuilder* machine = jsgraph()->machine(); 1473 MachineOperatorBuilder* machine = jsgraph()->machine();
1470 1474
1471 // Compute the code object by loading it from the function table. 1475 // Compute the code object by loading it from the function table.
1472 Node* key = args[0]; 1476 Node* key = args[0];
1473 Node* table = FunctionTable();
1474 1477
1475 // Bounds check the index. 1478 // Bounds check the index.
1476 int table_size = static_cast<int>(module_->FunctionTableSize()); 1479 int table_size = static_cast<int>(module_->FunctionTableSize());
1477 { 1480 if (table_size > 0) {
1481 // Bounds check against the table size.
1478 Node* size = Int32Constant(static_cast<int>(table_size)); 1482 Node* size = Int32Constant(static_cast<int>(table_size));
1479 Node* in_bounds = graph()->NewNode(machine->Uint32LessThan(), key, size); 1483 Node* in_bounds = graph()->NewNode(machine->Uint32LessThan(), key, size);
1480 trap_->AddTrapIfFalse(kTrapFuncInvalid, in_bounds); 1484 trap_->AddTrapIfFalse(kTrapFuncInvalid, in_bounds);
1485 } else {
1486 // No function table. Generate a trap and return a constant.
1487 trap_->AddTrapIfFalse(kTrapFuncInvalid, Int32Constant(0));
1488 return trap_->GetTrapValue(module_->GetSignature(index));
1481 } 1489 }
1490 Node* table = FunctionTable();
1482 1491
1483 // Load signature from the table and check. 1492 // Load signature from the table and check.
1484 // The table is a FixedArray; signatures are encoded as SMIs. 1493 // The table is a FixedArray; signatures are encoded as SMIs.
1485 // [sig1, sig2, sig3, ...., code1, code2, code3 ...] 1494 // [sig1, sig2, sig3, ...., code1, code2, code3 ...]
1486 ElementAccess access = AccessBuilder::ForFixedArrayElement(); 1495 ElementAccess access = AccessBuilder::ForFixedArrayElement();
1487 const int fixed_offset = access.header_size - access.tag(); 1496 const int fixed_offset = access.header_size - access.tag();
1488 { 1497 {
1489 Node* load_sig = graph()->NewNode( 1498 Node* load_sig = graph()->NewNode(
1490 machine->Load(MachineType::AnyTagged()), table, 1499 machine->Load(MachineType::AnyTagged()), table,
1491 graph()->NewNode(machine->Int32Add(), 1500 graph()->NewNode(machine->Int32Add(),
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after
2101 code->Disassemble(buffer.start(), os); 2110 code->Disassemble(buffer.start(), os);
2102 } 2111 }
2103 #endif 2112 #endif
2104 return code; 2113 return code;
2105 } 2114 }
2106 2115
2107 2116
2108 } // namespace compiler 2117 } // namespace compiler
2109 } // namespace internal 2118 } // namespace internal
2110 } // namespace v8 2119 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/wasm/wasm-module.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698