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

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

Issue 1862633002: [wasm] Factor trap codes out of wasm-compiler.cc (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 8 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-opcodes.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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 65
66 void MergeControlToEnd(JSGraph* jsgraph, Node* node) { 66 void MergeControlToEnd(JSGraph* jsgraph, Node* node) {
67 Graph* g = jsgraph->graph(); 67 Graph* g = jsgraph->graph();
68 if (g->end()) { 68 if (g->end()) {
69 NodeProperties::MergeControlToEnd(g, jsgraph->common(), node); 69 NodeProperties::MergeControlToEnd(g, jsgraph->common(), node);
70 } else { 70 } else {
71 g->SetEnd(g->NewNode(jsgraph->common()->End(1), node)); 71 g->SetEnd(g->NewNode(jsgraph->common()->End(1), node));
72 } 72 }
73 } 73 }
74 74
75
76 enum TrapReason {
77 kTrapUnreachable,
78 kTrapMemOutOfBounds,
79 kTrapDivByZero,
80 kTrapDivUnrepresentable,
81 kTrapRemByZero,
82 kTrapFloatUnrepresentable,
83 kTrapFuncInvalid,
84 kTrapFuncSigMismatch,
85 kTrapCount
86 };
87
88
89 static const char* kTrapMessages[] = {
90 "unreachable", "memory access out of bounds",
91 "divide by zero", "divide result unrepresentable",
92 "remainder by zero", "integer result unrepresentable",
93 "invalid function", "function signature mismatch"};
94 } // namespace 75 } // namespace
95 76
96
97 // A helper that handles building graph fragments for trapping. 77 // A helper that handles building graph fragments for trapping.
98 // To avoid generating a ton of redundant code that just calls the runtime 78 // To avoid generating a ton of redundant code that just calls the runtime
99 // to trap, we generate a per-trap-reason block of code that all trap sites 79 // to trap, we generate a per-trap-reason block of code that all trap sites
100 // in this function will branch to. 80 // in this function will branch to.
101 class WasmTrapHelper : public ZoneObject { 81 class WasmTrapHelper : public ZoneObject {
102 public: 82 public:
103 explicit WasmTrapHelper(WasmGraphBuilder* builder) 83 explicit WasmTrapHelper(WasmGraphBuilder* builder)
104 : builder_(builder), 84 : builder_(builder),
105 jsgraph_(builder->jsgraph()), 85 jsgraph_(builder->jsgraph()),
106 graph_(builder->jsgraph() ? builder->jsgraph()->graph() : nullptr) { 86 graph_(builder->jsgraph() ? builder->jsgraph()->graph() : nullptr) {
107 for (int i = 0; i < kTrapCount; i++) traps_[i] = nullptr; 87 for (int i = 0; i < wasm::kTrapCount; i++) traps_[i] = nullptr;
108 } 88 }
109 89
110 // Make the current control path trap to unreachable. 90 // Make the current control path trap to unreachable.
111 void Unreachable() { ConnectTrap(kTrapUnreachable); } 91 void Unreachable() { ConnectTrap(wasm::kTrapUnreachable); }
112 92
113 // Always trap with the given reason. 93 // Always trap with the given reason.
114 void TrapAlways(TrapReason reason) { ConnectTrap(reason); } 94 void TrapAlways(wasm::TrapReason reason) { ConnectTrap(reason); }
115 95
116 // Add a check that traps if {node} is equal to {val}. 96 // Add a check that traps if {node} is equal to {val}.
117 Node* TrapIfEq32(TrapReason reason, Node* node, int32_t val) { 97 Node* TrapIfEq32(wasm::TrapReason reason, Node* node, int32_t val) {
118 Int32Matcher m(node); 98 Int32Matcher m(node);
119 if (m.HasValue() && !m.Is(val)) return graph()->start(); 99 if (m.HasValue() && !m.Is(val)) return graph()->start();
120 if (val == 0) { 100 if (val == 0) {
121 AddTrapIfFalse(reason, node); 101 AddTrapIfFalse(reason, node);
122 } else { 102 } else {
123 AddTrapIfTrue(reason, 103 AddTrapIfTrue(reason,
124 graph()->NewNode(jsgraph()->machine()->Word32Equal(), node, 104 graph()->NewNode(jsgraph()->machine()->Word32Equal(), node,
125 jsgraph()->Int32Constant(val))); 105 jsgraph()->Int32Constant(val)));
126 } 106 }
127 return builder_->Control(); 107 return builder_->Control();
128 } 108 }
129 109
130 // Add a check that traps if {node} is zero. 110 // Add a check that traps if {node} is zero.
131 Node* ZeroCheck32(TrapReason reason, Node* node) { 111 Node* ZeroCheck32(wasm::TrapReason reason, Node* node) {
132 return TrapIfEq32(reason, node, 0); 112 return TrapIfEq32(reason, node, 0);
133 } 113 }
134 114
135 // Add a check that traps if {node} is equal to {val}. 115 // Add a check that traps if {node} is equal to {val}.
136 Node* TrapIfEq64(TrapReason reason, Node* node, int64_t val) { 116 Node* TrapIfEq64(wasm::TrapReason reason, Node* node, int64_t val) {
137 Int64Matcher m(node); 117 Int64Matcher m(node);
138 if (m.HasValue() && !m.Is(val)) return graph()->start(); 118 if (m.HasValue() && !m.Is(val)) return graph()->start();
139 AddTrapIfTrue(reason, 119 AddTrapIfTrue(reason,
140 graph()->NewNode(jsgraph()->machine()->Word64Equal(), node, 120 graph()->NewNode(jsgraph()->machine()->Word64Equal(), node,
141 jsgraph()->Int64Constant(val))); 121 jsgraph()->Int64Constant(val)));
142 return builder_->Control(); 122 return builder_->Control();
143 } 123 }
144 124
145 // Add a check that traps if {node} is zero. 125 // Add a check that traps if {node} is zero.
146 Node* ZeroCheck64(TrapReason reason, Node* node) { 126 Node* ZeroCheck64(wasm::TrapReason reason, Node* node) {
147 return TrapIfEq64(reason, node, 0); 127 return TrapIfEq64(reason, node, 0);
148 } 128 }
149 129
150 // Add a trap if {cond} is true. 130 // Add a trap if {cond} is true.
151 void AddTrapIfTrue(TrapReason reason, Node* cond) { 131 void AddTrapIfTrue(wasm::TrapReason reason, Node* cond) {
152 AddTrapIf(reason, cond, true); 132 AddTrapIf(reason, cond, true);
153 } 133 }
154 134
155 // Add a trap if {cond} is false. 135 // Add a trap if {cond} is false.
156 void AddTrapIfFalse(TrapReason reason, Node* cond) { 136 void AddTrapIfFalse(wasm::TrapReason reason, Node* cond) {
157 AddTrapIf(reason, cond, false); 137 AddTrapIf(reason, cond, false);
158 } 138 }
159 139
160 // Add a trap if {cond} is true or false according to {iftrue}. 140 // Add a trap if {cond} is true or false according to {iftrue}.
161 void AddTrapIf(TrapReason reason, Node* cond, bool iftrue) { 141 void AddTrapIf(wasm::TrapReason reason, Node* cond, bool iftrue) {
162 Node** effect_ptr = builder_->effect_; 142 Node** effect_ptr = builder_->effect_;
163 Node** control_ptr = builder_->control_; 143 Node** control_ptr = builder_->control_;
164 Node* before = *effect_ptr; 144 Node* before = *effect_ptr;
165 BranchHint hint = iftrue ? BranchHint::kFalse : BranchHint::kTrue; 145 BranchHint hint = iftrue ? BranchHint::kFalse : BranchHint::kTrue;
166 Node* branch = graph()->NewNode(common()->Branch(hint), cond, *control_ptr); 146 Node* branch = graph()->NewNode(common()->Branch(hint), cond, *control_ptr);
167 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 147 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
168 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 148 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
169 149
170 *control_ptr = iftrue ? if_true : if_false; 150 *control_ptr = iftrue ? if_true : if_false;
171 ConnectTrap(reason); 151 ConnectTrap(reason);
(...skipping 20 matching lines...) Expand all
192 } 172 }
193 } else { 173 } else {
194 return jsgraph()->Int32Constant(0xdeadbeef); 174 return jsgraph()->Int32Constant(0xdeadbeef);
195 } 175 }
196 } 176 }
197 177
198 private: 178 private:
199 WasmGraphBuilder* builder_; 179 WasmGraphBuilder* builder_;
200 JSGraph* jsgraph_; 180 JSGraph* jsgraph_;
201 Graph* graph_; 181 Graph* graph_;
202 Node* traps_[kTrapCount]; 182 Node* traps_[wasm::kTrapCount];
203 Node* effects_[kTrapCount]; 183 Node* effects_[wasm::kTrapCount];
204 184
205 JSGraph* jsgraph() { return jsgraph_; } 185 JSGraph* jsgraph() { return jsgraph_; }
206 Graph* graph() { return jsgraph_->graph(); } 186 Graph* graph() { return jsgraph_->graph(); }
207 CommonOperatorBuilder* common() { return jsgraph()->common(); } 187 CommonOperatorBuilder* common() { return jsgraph()->common(); }
208 188
209 void ConnectTrap(TrapReason reason) { 189 void ConnectTrap(wasm::TrapReason reason) {
210 if (traps_[reason] == nullptr) { 190 if (traps_[reason] == nullptr) {
211 // Create trap code for the first time this trap is used. 191 // Create trap code for the first time this trap is used.
212 return BuildTrapCode(reason); 192 return BuildTrapCode(reason);
213 } 193 }
214 // Connect the current control and effect to the existing trap code. 194 // Connect the current control and effect to the existing trap code.
215 builder_->AppendToMerge(traps_[reason], builder_->Control()); 195 builder_->AppendToMerge(traps_[reason], builder_->Control());
216 builder_->AppendToPhi(traps_[reason], effects_[reason], builder_->Effect()); 196 builder_->AppendToPhi(traps_[reason], effects_[reason], builder_->Effect());
217 } 197 }
218 198
219 void BuildTrapCode(TrapReason reason) { 199 void BuildTrapCode(wasm::TrapReason reason) {
220 Node* exception = builder_->String(kTrapMessages[reason]); 200 Node* exception =
201 builder_->String(wasm::WasmOpcodes::TrapReasonName(reason));
221 Node* end; 202 Node* end;
222 Node** control_ptr = builder_->control_; 203 Node** control_ptr = builder_->control_;
223 Node** effect_ptr = builder_->effect_; 204 Node** effect_ptr = builder_->effect_;
224 wasm::ModuleEnv* module = builder_->module_; 205 wasm::ModuleEnv* module = builder_->module_;
225 *control_ptr = traps_[reason] = 206 *control_ptr = traps_[reason] =
226 graph()->NewNode(common()->Merge(1), *control_ptr); 207 graph()->NewNode(common()->Merge(1), *control_ptr);
227 *effect_ptr = effects_[reason] = 208 *effect_ptr = effects_[reason] =
228 graph()->NewNode(common()->EffectPhi(1), *effect_ptr, *control_ptr); 209 graph()->NewNode(common()->EffectPhi(1), *effect_ptr, *control_ptr);
229 210
230 if (module && !module->instance->context.is_null()) { 211 if (module && !module->instance->context.is_null()) {
(...skipping 28 matching lines...) Expand all
259 // End the control flow with returning 0xdeadbeef 240 // End the control flow with returning 0xdeadbeef
260 Node* ret_value = GetTrapValue(builder_->GetFunctionSignature()); 241 Node* ret_value = GetTrapValue(builder_->GetFunctionSignature());
261 end = graph()->NewNode(jsgraph()->common()->Return(), ret_value, 242 end = graph()->NewNode(jsgraph()->common()->Return(), ret_value,
262 *effect_ptr, *control_ptr); 243 *effect_ptr, *control_ptr);
263 } 244 }
264 245
265 MergeControlToEnd(jsgraph(), end); 246 MergeControlToEnd(jsgraph(), end);
266 } 247 }
267 }; 248 };
268 249
269
270 WasmGraphBuilder::WasmGraphBuilder(Zone* zone, JSGraph* jsgraph, 250 WasmGraphBuilder::WasmGraphBuilder(Zone* zone, JSGraph* jsgraph,
271 wasm::FunctionSig* function_signature) 251 wasm::FunctionSig* function_signature)
272 : zone_(zone), 252 : zone_(zone),
273 jsgraph_(jsgraph), 253 jsgraph_(jsgraph),
274 module_(nullptr), 254 module_(nullptr),
275 mem_buffer_(nullptr), 255 mem_buffer_(nullptr),
276 mem_size_(nullptr), 256 mem_size_(nullptr),
277 function_table_(nullptr), 257 function_table_(nullptr),
278 control_(nullptr), 258 control_(nullptr),
279 effect_(nullptr), 259 effect_(nullptr),
(...skipping 884 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 } 1144 }
1165 1145
1166 // Truncation of the input value is needed for the overflow check later. 1146 // Truncation of the input value is needed for the overflow check later.
1167 Node* trunc = Unop(wasm::kExprF32Trunc, input); 1147 Node* trunc = Unop(wasm::kExprF32Trunc, input);
1168 Node* result = graph()->NewNode(m->TruncateFloat32ToInt32(), trunc); 1148 Node* result = graph()->NewNode(m->TruncateFloat32ToInt32(), trunc);
1169 1149
1170 // Convert the result back to f64. If we end up at a different value than the 1150 // Convert the result back to f64. If we end up at a different value than the
1171 // truncated input value, then there has been an overflow and we trap. 1151 // truncated input value, then there has been an overflow and we trap.
1172 Node* check = Unop(wasm::kExprF32SConvertI32, result); 1152 Node* check = Unop(wasm::kExprF32SConvertI32, result);
1173 Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); 1153 Node* overflow = Binop(wasm::kExprF32Ne, trunc, check);
1174 trap_->AddTrapIfTrue(kTrapFloatUnrepresentable, overflow); 1154 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow);
1175 1155
1176 return result; 1156 return result;
1177 } 1157 }
1178 1158
1179 1159
1180 Node* WasmGraphBuilder::BuildI32SConvertF64(Node* input) { 1160 Node* WasmGraphBuilder::BuildI32SConvertF64(Node* input) {
1181 MachineOperatorBuilder* m = jsgraph()->machine(); 1161 MachineOperatorBuilder* m = jsgraph()->machine();
1182 if (module_ && module_->asm_js()) { 1162 if (module_ && module_->asm_js()) {
1183 // asm.js must use the wacky JS semantics. 1163 // asm.js must use the wacky JS semantics.
1184 return graph()->NewNode( 1164 return graph()->NewNode(
1185 m->TruncateFloat64ToInt32(TruncationMode::kJavaScript), input); 1165 m->TruncateFloat64ToInt32(TruncationMode::kJavaScript), input);
1186 } 1166 }
1187 // Truncation of the input value is needed for the overflow check later. 1167 // Truncation of the input value is needed for the overflow check later.
1188 Node* trunc = Unop(wasm::kExprF64Trunc, input); 1168 Node* trunc = Unop(wasm::kExprF64Trunc, input);
1189 Node* result = graph()->NewNode(m->ChangeFloat64ToInt32(), trunc); 1169 Node* result = graph()->NewNode(m->ChangeFloat64ToInt32(), trunc);
1190 1170
1191 // Convert the result back to f64. If we end up at a different value than the 1171 // Convert the result back to f64. If we end up at a different value than the
1192 // truncated input value, then there has been an overflow and we trap. 1172 // truncated input value, then there has been an overflow and we trap.
1193 Node* check = Unop(wasm::kExprF64SConvertI32, result); 1173 Node* check = Unop(wasm::kExprF64SConvertI32, result);
1194 Node* overflow = Binop(wasm::kExprF64Ne, trunc, check); 1174 Node* overflow = Binop(wasm::kExprF64Ne, trunc, check);
1195 trap_->AddTrapIfTrue(kTrapFloatUnrepresentable, overflow); 1175 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow);
1196 1176
1197 return result; 1177 return result;
1198 } 1178 }
1199 1179
1200 1180
1201 Node* WasmGraphBuilder::BuildI32UConvertF32(Node* input) { 1181 Node* WasmGraphBuilder::BuildI32UConvertF32(Node* input) {
1202 MachineOperatorBuilder* m = jsgraph()->machine(); 1182 MachineOperatorBuilder* m = jsgraph()->machine();
1203 if (module_ && module_->asm_js()) { 1183 if (module_ && module_->asm_js()) {
1204 // asm.js must use the wacky JS semantics. 1184 // asm.js must use the wacky JS semantics.
1205 input = graph()->NewNode(m->ChangeFloat32ToFloat64(), input); 1185 input = graph()->NewNode(m->ChangeFloat32ToFloat64(), input);
1206 return graph()->NewNode( 1186 return graph()->NewNode(
1207 m->TruncateFloat64ToInt32(TruncationMode::kJavaScript), input); 1187 m->TruncateFloat64ToInt32(TruncationMode::kJavaScript), input);
1208 } 1188 }
1209 1189
1210 // 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.
1211 Node* trunc = Unop(wasm::kExprF32Trunc, input); 1191 Node* trunc = Unop(wasm::kExprF32Trunc, input);
1212 Node* result = graph()->NewNode(m->TruncateFloat32ToUint32(), trunc); 1192 Node* result = graph()->NewNode(m->TruncateFloat32ToUint32(), trunc);
1213 1193
1214 // Convert the result back to f32. If we end up at a different value than the 1194 // Convert the result back to f32. If we end up at a different value than the
1215 // 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.
1216 Node* check = Unop(wasm::kExprF32UConvertI32, result); 1196 Node* check = Unop(wasm::kExprF32UConvertI32, result);
1217 Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); 1197 Node* overflow = Binop(wasm::kExprF32Ne, trunc, check);
1218 trap_->AddTrapIfTrue(kTrapFloatUnrepresentable, overflow); 1198 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow);
1219 1199
1220 return result; 1200 return result;
1221 } 1201 }
1222 1202
1223 1203
1224 Node* WasmGraphBuilder::BuildI32UConvertF64(Node* input) { 1204 Node* WasmGraphBuilder::BuildI32UConvertF64(Node* input) {
1225 MachineOperatorBuilder* m = jsgraph()->machine(); 1205 MachineOperatorBuilder* m = jsgraph()->machine();
1226 if (module_ && module_->asm_js()) { 1206 if (module_ && module_->asm_js()) {
1227 // asm.js must use the wacky JS semantics. 1207 // asm.js must use the wacky JS semantics.
1228 return graph()->NewNode( 1208 return graph()->NewNode(
1229 m->TruncateFloat64ToInt32(TruncationMode::kJavaScript), input); 1209 m->TruncateFloat64ToInt32(TruncationMode::kJavaScript), input);
1230 } 1210 }
1231 // Truncation of the input value is needed for the overflow check later. 1211 // Truncation of the input value is needed for the overflow check later.
1232 Node* trunc = Unop(wasm::kExprF64Trunc, input); 1212 Node* trunc = Unop(wasm::kExprF64Trunc, input);
1233 Node* result = graph()->NewNode(m->TruncateFloat64ToUint32(), trunc); 1213 Node* result = graph()->NewNode(m->TruncateFloat64ToUint32(), trunc);
1234 1214
1235 // Convert the result back to f64. If we end up at a different value than the 1215 // Convert the result back to f64. If we end up at a different value than the
1236 // truncated input value, then there has been an overflow and we trap. 1216 // truncated input value, then there has been an overflow and we trap.
1237 Node* check = Unop(wasm::kExprF64UConvertI32, result); 1217 Node* check = Unop(wasm::kExprF64UConvertI32, result);
1238 Node* overflow = Binop(wasm::kExprF64Ne, trunc, check); 1218 Node* overflow = Binop(wasm::kExprF64Ne, trunc, check);
1239 trap_->AddTrapIfTrue(kTrapFloatUnrepresentable, overflow); 1219 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow);
1240 1220
1241 return result; 1221 return result;
1242 } 1222 }
1243 1223
1244 1224
1245 Node* WasmGraphBuilder::BuildI32Ctz(Node* input) { 1225 Node* WasmGraphBuilder::BuildI32Ctz(Node* input) {
1246 //// Implement the following code as TF graph. 1226 //// Implement the following code as TF graph.
1247 // value = value | (value << 1); 1227 // value = value | (value << 1);
1248 // value = value | (value << 2); 1228 // value = value | (value << 2);
1249 // value = value | (value << 4); 1229 // value = value | (value << 4);
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
1659 if (jsgraph()->machine()->Is32()) { 1639 if (jsgraph()->machine()->Is32()) {
1660 return BuildFloatToIntConversionInstruction( 1640 return BuildFloatToIntConversionInstruction(
1661 input, ExternalReference::wasm_float32_to_int64(jsgraph()->isolate()), 1641 input, ExternalReference::wasm_float32_to_int64(jsgraph()->isolate()),
1662 MachineRepresentation::kFloat32, MachineType::Int64()); 1642 MachineRepresentation::kFloat32, MachineType::Int64());
1663 } else { 1643 } else {
1664 Node* trunc = graph()->NewNode( 1644 Node* trunc = graph()->NewNode(
1665 jsgraph()->machine()->TryTruncateFloat32ToInt64(), input); 1645 jsgraph()->machine()->TryTruncateFloat32ToInt64(), input);
1666 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); 1646 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
1667 Node* overflow = 1647 Node* overflow =
1668 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); 1648 graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
1669 trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow); 1649 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow);
1670 return result; 1650 return result;
1671 } 1651 }
1672 } 1652 }
1673 1653
1674 Node* WasmGraphBuilder::BuildI64UConvertF32(Node* input) { 1654 Node* WasmGraphBuilder::BuildI64UConvertF32(Node* input) {
1675 if (jsgraph()->machine()->Is32()) { 1655 if (jsgraph()->machine()->Is32()) {
1676 return BuildFloatToIntConversionInstruction( 1656 return BuildFloatToIntConversionInstruction(
1677 input, ExternalReference::wasm_float32_to_uint64(jsgraph()->isolate()), 1657 input, ExternalReference::wasm_float32_to_uint64(jsgraph()->isolate()),
1678 MachineRepresentation::kFloat32, MachineType::Int64()); 1658 MachineRepresentation::kFloat32, MachineType::Int64());
1679 } else { 1659 } else {
1680 Node* trunc = graph()->NewNode( 1660 Node* trunc = graph()->NewNode(
1681 jsgraph()->machine()->TryTruncateFloat32ToUint64(), input); 1661 jsgraph()->machine()->TryTruncateFloat32ToUint64(), input);
1682 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); 1662 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
1683 Node* overflow = 1663 Node* overflow =
1684 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); 1664 graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
1685 trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow); 1665 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow);
1686 return result; 1666 return result;
1687 } 1667 }
1688 } 1668 }
1689 1669
1690 Node* WasmGraphBuilder::BuildI64SConvertF64(Node* input) { 1670 Node* WasmGraphBuilder::BuildI64SConvertF64(Node* input) {
1691 if (jsgraph()->machine()->Is32()) { 1671 if (jsgraph()->machine()->Is32()) {
1692 return BuildFloatToIntConversionInstruction( 1672 return BuildFloatToIntConversionInstruction(
1693 input, ExternalReference::wasm_float64_to_int64(jsgraph()->isolate()), 1673 input, ExternalReference::wasm_float64_to_int64(jsgraph()->isolate()),
1694 MachineRepresentation::kFloat64, MachineType::Int64()); 1674 MachineRepresentation::kFloat64, MachineType::Int64());
1695 } else { 1675 } else {
1696 Node* trunc = graph()->NewNode( 1676 Node* trunc = graph()->NewNode(
1697 jsgraph()->machine()->TryTruncateFloat64ToInt64(), input); 1677 jsgraph()->machine()->TryTruncateFloat64ToInt64(), input);
1698 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); 1678 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
1699 Node* overflow = 1679 Node* overflow =
1700 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); 1680 graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
1701 trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow); 1681 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow);
1702 return result; 1682 return result;
1703 } 1683 }
1704 } 1684 }
1705 1685
1706 Node* WasmGraphBuilder::BuildI64UConvertF64(Node* input) { 1686 Node* WasmGraphBuilder::BuildI64UConvertF64(Node* input) {
1707 if (jsgraph()->machine()->Is32()) { 1687 if (jsgraph()->machine()->Is32()) {
1708 return BuildFloatToIntConversionInstruction( 1688 return BuildFloatToIntConversionInstruction(
1709 input, ExternalReference::wasm_float64_to_uint64(jsgraph()->isolate()), 1689 input, ExternalReference::wasm_float64_to_uint64(jsgraph()->isolate()),
1710 MachineRepresentation::kFloat64, MachineType::Int64()); 1690 MachineRepresentation::kFloat64, MachineType::Int64());
1711 } else { 1691 } else {
1712 Node* trunc = graph()->NewNode( 1692 Node* trunc = graph()->NewNode(
1713 jsgraph()->machine()->TryTruncateFloat64ToUint64(), input); 1693 jsgraph()->machine()->TryTruncateFloat64ToUint64(), input);
1714 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); 1694 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
1715 Node* overflow = 1695 Node* overflow =
1716 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); 1696 graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
1717 trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow); 1697 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow);
1718 return result; 1698 return result;
1719 } 1699 }
1720 } 1700 }
1721 1701
1722 Node* WasmGraphBuilder::BuildFloatToIntConversionInstruction( 1702 Node* WasmGraphBuilder::BuildFloatToIntConversionInstruction(
1723 Node* input, ExternalReference ref, 1703 Node* input, ExternalReference ref,
1724 MachineRepresentation parameter_representation, 1704 MachineRepresentation parameter_representation,
1725 const MachineType result_type) { 1705 const MachineType result_type) {
1726 Node* stack_slot_param = graph()->NewNode( 1706 Node* stack_slot_param = graph()->NewNode(
1727 jsgraph()->machine()->StackSlot(parameter_representation)); 1707 jsgraph()->machine()->StackSlot(parameter_representation));
1728 Node* stack_slot_result = graph()->NewNode( 1708 Node* stack_slot_result = graph()->NewNode(
1729 jsgraph()->machine()->StackSlot(result_type.representation())); 1709 jsgraph()->machine()->StackSlot(result_type.representation()));
1730 const Operator* store_op = jsgraph()->machine()->Store( 1710 const Operator* store_op = jsgraph()->machine()->Store(
1731 StoreRepresentation(parameter_representation, kNoWriteBarrier)); 1711 StoreRepresentation(parameter_representation, kNoWriteBarrier));
1732 *effect_ = 1712 *effect_ =
1733 graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0), 1713 graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0),
1734 input, *effect_, *control_); 1714 input, *effect_, *control_);
1735 MachineSignature::Builder sig_builder(jsgraph()->zone(), 1, 2); 1715 MachineSignature::Builder sig_builder(jsgraph()->zone(), 1, 2);
1736 sig_builder.AddReturn(MachineType::Int32()); 1716 sig_builder.AddReturn(MachineType::Int32());
1737 sig_builder.AddParam(MachineType::Pointer()); 1717 sig_builder.AddParam(MachineType::Pointer());
1738 sig_builder.AddParam(MachineType::Pointer()); 1718 sig_builder.AddParam(MachineType::Pointer());
1739 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref)); 1719 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref));
1740 Node* args[] = {function, stack_slot_param, stack_slot_result}; 1720 Node* args[] = {function, stack_slot_param, stack_slot_result};
1741 trap_->ZeroCheck32(kTrapFloatUnrepresentable, 1721 trap_->ZeroCheck32(wasm::kTrapFloatUnrepresentable,
1742 BuildCCall(sig_builder.Build(), args)); 1722 BuildCCall(sig_builder.Build(), args));
1743 const Operator* load_op = jsgraph()->machine()->Load(result_type); 1723 const Operator* load_op = jsgraph()->machine()->Load(result_type);
1744 Node* load = 1724 Node* load =
1745 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0), 1725 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0),
1746 *effect_, *control_); 1726 *effect_, *control_);
1747 *effect_ = load; 1727 *effect_ = load;
1748 return load; 1728 return load;
1749 } 1729 }
1750 1730
1751 Node* WasmGraphBuilder::BuildI32DivS(Node* left, Node* right) { 1731 Node* WasmGraphBuilder::BuildI32DivS(Node* left, Node* right) {
(...skipping 19 matching lines...) Expand all
1771 1751
1772 Node* div = graph()->NewNode(m->Int32Div(), left, right, z.if_false); 1752 Node* div = graph()->NewNode(m->Int32Div(), left, right, z.if_false);
1773 Node* neg = 1753 Node* neg =
1774 graph()->NewNode(m->Int32Sub(), jsgraph()->Int32Constant(0), left); 1754 graph()->NewNode(m->Int32Sub(), jsgraph()->Int32Constant(0), left);
1775 1755
1776 return n.Phi(MachineRepresentation::kWord32, neg, 1756 return n.Phi(MachineRepresentation::kWord32, neg,
1777 z.Phi(MachineRepresentation::kWord32, 1757 z.Phi(MachineRepresentation::kWord32,
1778 jsgraph()->Int32Constant(0), div)); 1758 jsgraph()->Int32Constant(0), div));
1779 } 1759 }
1780 1760
1781 trap_->ZeroCheck32(kTrapDivByZero, right); 1761 trap_->ZeroCheck32(wasm::kTrapDivByZero, right);
1782 Node* before = *control_; 1762 Node* before = *control_;
1783 Node* denom_is_m1; 1763 Node* denom_is_m1;
1784 Node* denom_is_not_m1; 1764 Node* denom_is_not_m1;
1785 Branch( 1765 Branch(
1786 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)), 1766 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)),
1787 &denom_is_m1, &denom_is_not_m1); 1767 &denom_is_m1, &denom_is_not_m1);
1788 *control_ = denom_is_m1; 1768 *control_ = denom_is_m1;
1789 trap_->TrapIfEq32(kTrapDivUnrepresentable, left, kMinInt); 1769 trap_->TrapIfEq32(wasm::kTrapDivUnrepresentable, left, kMinInt);
1790 if (*control_ != denom_is_m1) { 1770 if (*control_ != denom_is_m1) {
1791 *control_ = graph()->NewNode(jsgraph()->common()->Merge(2), denom_is_not_m1, 1771 *control_ = graph()->NewNode(jsgraph()->common()->Merge(2), denom_is_not_m1,
1792 *control_); 1772 *control_);
1793 } else { 1773 } else {
1794 *control_ = before; 1774 *control_ = before;
1795 } 1775 }
1796 return graph()->NewNode(m->Int32Div(), left, right, *control_); 1776 return graph()->NewNode(m->Int32Div(), left, right, *control_);
1797 } 1777 }
1798 1778
1799 Node* WasmGraphBuilder::BuildI32RemS(Node* left, Node* right) { 1779 Node* WasmGraphBuilder::BuildI32RemS(Node* left, Node* right) {
(...skipping 12 matching lines...) Expand all
1812 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)), 1792 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)),
1813 BranchHint::kFalse); 1793 BranchHint::kFalse);
1814 d.Chain(z.if_false); 1794 d.Chain(z.if_false);
1815 1795
1816 return z.Phi( 1796 return z.Phi(
1817 MachineRepresentation::kWord32, jsgraph()->Int32Constant(0), 1797 MachineRepresentation::kWord32, jsgraph()->Int32Constant(0),
1818 d.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0), 1798 d.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0),
1819 graph()->NewNode(m->Int32Mod(), left, right, d.if_false))); 1799 graph()->NewNode(m->Int32Mod(), left, right, d.if_false)));
1820 } 1800 }
1821 1801
1822 trap_->ZeroCheck32(kTrapRemByZero, right); 1802 trap_->ZeroCheck32(wasm::kTrapRemByZero, right);
1823 1803
1824 Diamond d( 1804 Diamond d(
1825 graph(), jsgraph()->common(), 1805 graph(), jsgraph()->common(),
1826 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)), 1806 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)),
1827 BranchHint::kFalse); 1807 BranchHint::kFalse);
1828 d.Chain(*control_); 1808 d.Chain(*control_);
1829 1809
1830 return d.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0), 1810 return d.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0),
1831 graph()->NewNode(m->Int32Mod(), left, right, d.if_false)); 1811 graph()->NewNode(m->Int32Mod(), left, right, d.if_false));
1832 } 1812 }
(...skipping 11 matching lines...) Expand all
1844 Diamond z( 1824 Diamond z(
1845 graph(), jsgraph()->common(), 1825 graph(), jsgraph()->common(),
1846 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(0)), 1826 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(0)),
1847 BranchHint::kFalse); 1827 BranchHint::kFalse);
1848 1828
1849 return z.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0), 1829 return z.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0),
1850 graph()->NewNode(jsgraph()->machine()->Uint32Div(), left, 1830 graph()->NewNode(jsgraph()->machine()->Uint32Div(), left,
1851 right, z.if_false)); 1831 right, z.if_false));
1852 } 1832 }
1853 return graph()->NewNode(m->Uint32Div(), left, right, 1833 return graph()->NewNode(m->Uint32Div(), left, right,
1854 trap_->ZeroCheck32(kTrapDivByZero, right)); 1834 trap_->ZeroCheck32(wasm::kTrapDivByZero, right));
1855 } 1835 }
1856 1836
1857 Node* WasmGraphBuilder::BuildI32RemU(Node* left, Node* right) { 1837 Node* WasmGraphBuilder::BuildI32RemU(Node* left, Node* right) {
1858 MachineOperatorBuilder* m = jsgraph()->machine(); 1838 MachineOperatorBuilder* m = jsgraph()->machine();
1859 if (module_ && module_->asm_js()) { 1839 if (module_ && module_->asm_js()) {
1860 // asm.js semantics return 0 on divide or mod by zero. 1840 // asm.js semantics return 0 on divide or mod by zero.
1861 // Explicit check for x % 0. 1841 // Explicit check for x % 0.
1862 Diamond z( 1842 Diamond z(
1863 graph(), jsgraph()->common(), 1843 graph(), jsgraph()->common(),
1864 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(0)), 1844 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(0)),
1865 BranchHint::kFalse); 1845 BranchHint::kFalse);
1866 1846
1867 Node* rem = graph()->NewNode(jsgraph()->machine()->Uint32Mod(), left, right, 1847 Node* rem = graph()->NewNode(jsgraph()->machine()->Uint32Mod(), left, right,
1868 z.if_false); 1848 z.if_false);
1869 return z.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0), 1849 return z.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0),
1870 rem); 1850 rem);
1871 } 1851 }
1872 1852
1873 return graph()->NewNode(m->Uint32Mod(), left, right, 1853 return graph()->NewNode(m->Uint32Mod(), left, right,
1874 trap_->ZeroCheck32(kTrapRemByZero, right)); 1854 trap_->ZeroCheck32(wasm::kTrapRemByZero, right));
1875 } 1855 }
1876 1856
1877 Node* WasmGraphBuilder::BuildI64DivS(Node* left, Node* right) { 1857 Node* WasmGraphBuilder::BuildI64DivS(Node* left, Node* right) {
1878 if (jsgraph()->machine()->Is32()) { 1858 if (jsgraph()->machine()->Is32()) {
1879 return BuildDiv64Call( 1859 return BuildDiv64Call(
1880 left, right, ExternalReference::wasm_int64_div(jsgraph()->isolate()), 1860 left, right, ExternalReference::wasm_int64_div(jsgraph()->isolate()),
1881 MachineType::Int64(), kTrapDivByZero); 1861 MachineType::Int64(), wasm::kTrapDivByZero);
1882 } 1862 }
1883 trap_->ZeroCheck64(kTrapDivByZero, right); 1863 trap_->ZeroCheck64(wasm::kTrapDivByZero, right);
1884 Node* before = *control_; 1864 Node* before = *control_;
1885 Node* denom_is_m1; 1865 Node* denom_is_m1;
1886 Node* denom_is_not_m1; 1866 Node* denom_is_not_m1;
1887 Branch(graph()->NewNode(jsgraph()->machine()->Word64Equal(), right, 1867 Branch(graph()->NewNode(jsgraph()->machine()->Word64Equal(), right,
1888 jsgraph()->Int64Constant(-1)), 1868 jsgraph()->Int64Constant(-1)),
1889 &denom_is_m1, &denom_is_not_m1); 1869 &denom_is_m1, &denom_is_not_m1);
1890 *control_ = denom_is_m1; 1870 *control_ = denom_is_m1;
1891 trap_->TrapIfEq64(kTrapDivUnrepresentable, left, 1871 trap_->TrapIfEq64(wasm::kTrapDivUnrepresentable, left,
1892 std::numeric_limits<int64_t>::min()); 1872 std::numeric_limits<int64_t>::min());
1893 if (*control_ != denom_is_m1) { 1873 if (*control_ != denom_is_m1) {
1894 *control_ = graph()->NewNode(jsgraph()->common()->Merge(2), denom_is_not_m1, 1874 *control_ = graph()->NewNode(jsgraph()->common()->Merge(2), denom_is_not_m1,
1895 *control_); 1875 *control_);
1896 } else { 1876 } else {
1897 *control_ = before; 1877 *control_ = before;
1898 } 1878 }
1899 return graph()->NewNode(jsgraph()->machine()->Int64Div(), left, right, 1879 return graph()->NewNode(jsgraph()->machine()->Int64Div(), left, right,
1900 *control_); 1880 *control_);
1901 } 1881 }
1902 1882
1903 Node* WasmGraphBuilder::BuildI64RemS(Node* left, Node* right) { 1883 Node* WasmGraphBuilder::BuildI64RemS(Node* left, Node* right) {
1904 if (jsgraph()->machine()->Is32()) { 1884 if (jsgraph()->machine()->Is32()) {
1905 return BuildDiv64Call( 1885 return BuildDiv64Call(
1906 left, right, ExternalReference::wasm_int64_mod(jsgraph()->isolate()), 1886 left, right, ExternalReference::wasm_int64_mod(jsgraph()->isolate()),
1907 MachineType::Int64(), kTrapRemByZero); 1887 MachineType::Int64(), wasm::kTrapRemByZero);
1908 } 1888 }
1909 trap_->ZeroCheck64(kTrapRemByZero, right); 1889 trap_->ZeroCheck64(wasm::kTrapRemByZero, right);
1910 Diamond d(jsgraph()->graph(), jsgraph()->common(), 1890 Diamond d(jsgraph()->graph(), jsgraph()->common(),
1911 graph()->NewNode(jsgraph()->machine()->Word64Equal(), right, 1891 graph()->NewNode(jsgraph()->machine()->Word64Equal(), right,
1912 jsgraph()->Int64Constant(-1))); 1892 jsgraph()->Int64Constant(-1)));
1913 1893
1914 Node* rem = graph()->NewNode(jsgraph()->machine()->Int64Mod(), left, right, 1894 Node* rem = graph()->NewNode(jsgraph()->machine()->Int64Mod(), left, right,
1915 d.if_false); 1895 d.if_false);
1916 1896
1917 return d.Phi(MachineRepresentation::kWord64, jsgraph()->Int64Constant(0), 1897 return d.Phi(MachineRepresentation::kWord64, jsgraph()->Int64Constant(0),
1918 rem); 1898 rem);
1919 } 1899 }
1920 1900
1921 Node* WasmGraphBuilder::BuildI64DivU(Node* left, Node* right) { 1901 Node* WasmGraphBuilder::BuildI64DivU(Node* left, Node* right) {
1922 if (jsgraph()->machine()->Is32()) { 1902 if (jsgraph()->machine()->Is32()) {
1923 return BuildDiv64Call( 1903 return BuildDiv64Call(
1924 left, right, ExternalReference::wasm_uint64_div(jsgraph()->isolate()), 1904 left, right, ExternalReference::wasm_uint64_div(jsgraph()->isolate()),
1925 MachineType::Int64(), kTrapDivByZero); 1905 MachineType::Int64(), wasm::kTrapDivByZero);
1926 } 1906 }
1927 return graph()->NewNode(jsgraph()->machine()->Uint64Div(), left, right, 1907 return graph()->NewNode(jsgraph()->machine()->Uint64Div(), left, right,
1928 trap_->ZeroCheck64(kTrapDivByZero, right)); 1908 trap_->ZeroCheck64(wasm::kTrapDivByZero, right));
1929 } 1909 }
1930 Node* WasmGraphBuilder::BuildI64RemU(Node* left, Node* right) { 1910 Node* WasmGraphBuilder::BuildI64RemU(Node* left, Node* right) {
1931 if (jsgraph()->machine()->Is32()) { 1911 if (jsgraph()->machine()->Is32()) {
1932 return BuildDiv64Call( 1912 return BuildDiv64Call(
1933 left, right, ExternalReference::wasm_uint64_mod(jsgraph()->isolate()), 1913 left, right, ExternalReference::wasm_uint64_mod(jsgraph()->isolate()),
1934 MachineType::Int64(), kTrapRemByZero); 1914 MachineType::Int64(), wasm::kTrapRemByZero);
1935 } 1915 }
1936 return graph()->NewNode(jsgraph()->machine()->Uint64Mod(), left, right, 1916 return graph()->NewNode(jsgraph()->machine()->Uint64Mod(), left, right,
1937 trap_->ZeroCheck64(kTrapRemByZero, right)); 1917 trap_->ZeroCheck64(wasm::kTrapRemByZero, right));
1938 } 1918 }
1939 1919
1940 Node* WasmGraphBuilder::BuildDiv64Call(Node* left, Node* right, 1920 Node* WasmGraphBuilder::BuildDiv64Call(Node* left, Node* right,
1941 ExternalReference ref, 1921 ExternalReference ref,
1942 MachineType result_type, int trap_zero) { 1922 MachineType result_type, int trap_zero) {
1943 Node* stack_slot_dst = graph()->NewNode( 1923 Node* stack_slot_dst = graph()->NewNode(
1944 jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64)); 1924 jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64));
1945 Node* stack_slot_src = graph()->NewNode( 1925 Node* stack_slot_src = graph()->NewNode(
1946 jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64)); 1926 jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64));
1947 1927
(...skipping 11 matching lines...) Expand all
1959 sig_builder.AddParam(MachineType::Pointer()); 1939 sig_builder.AddParam(MachineType::Pointer());
1960 sig_builder.AddParam(MachineType::Pointer()); 1940 sig_builder.AddParam(MachineType::Pointer());
1961 1941
1962 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref)); 1942 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref));
1963 Node* args[] = {function, stack_slot_dst, stack_slot_src}; 1943 Node* args[] = {function, stack_slot_dst, stack_slot_src};
1964 1944
1965 Node* call = BuildCCall(sig_builder.Build(), args); 1945 Node* call = BuildCCall(sig_builder.Build(), args);
1966 1946
1967 // TODO(wasm): This can get simpler if we have a specialized runtime call to 1947 // TODO(wasm): This can get simpler if we have a specialized runtime call to
1968 // throw WASM exceptions by trap code instead of by string. 1948 // throw WASM exceptions by trap code instead of by string.
1969 trap_->ZeroCheck32(static_cast<TrapReason>(trap_zero), call); 1949 trap_->ZeroCheck32(static_cast<wasm::TrapReason>(trap_zero), call);
1970 trap_->TrapIfEq32(kTrapDivUnrepresentable, call, -1); 1950 trap_->TrapIfEq32(wasm::kTrapDivUnrepresentable, call, -1);
1971 const Operator* load_op = jsgraph()->machine()->Load(result_type); 1951 const Operator* load_op = jsgraph()->machine()->Load(result_type);
1972 Node* load = 1952 Node* load =
1973 graph()->NewNode(load_op, stack_slot_dst, jsgraph()->Int32Constant(0), 1953 graph()->NewNode(load_op, stack_slot_dst, jsgraph()->Int32Constant(0),
1974 *effect_, *control_); 1954 *effect_, *control_);
1975 *effect_ = load; 1955 *effect_ = load;
1976 return load; 1956 return load;
1977 } 1957 }
1978 1958
1979 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) { 1959 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) {
1980 const size_t params = sig->parameter_count(); 1960 const size_t params = sig->parameter_count();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2046 2026
2047 // Compute the code object by loading it from the function table. 2027 // Compute the code object by loading it from the function table.
2048 Node* key = args[0]; 2028 Node* key = args[0];
2049 2029
2050 // Bounds check the index. 2030 // Bounds check the index.
2051 int table_size = static_cast<int>(module_->FunctionTableSize()); 2031 int table_size = static_cast<int>(module_->FunctionTableSize());
2052 if (table_size > 0) { 2032 if (table_size > 0) {
2053 // Bounds check against the table size. 2033 // Bounds check against the table size.
2054 Node* size = Int32Constant(static_cast<int>(table_size)); 2034 Node* size = Int32Constant(static_cast<int>(table_size));
2055 Node* in_bounds = graph()->NewNode(machine->Uint32LessThan(), key, size); 2035 Node* in_bounds = graph()->NewNode(machine->Uint32LessThan(), key, size);
2056 trap_->AddTrapIfFalse(kTrapFuncInvalid, in_bounds); 2036 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, in_bounds);
2057 } else { 2037 } else {
2058 // No function table. Generate a trap and return a constant. 2038 // No function table. Generate a trap and return a constant.
2059 trap_->AddTrapIfFalse(kTrapFuncInvalid, Int32Constant(0)); 2039 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0));
2060 return trap_->GetTrapValue(module_->GetSignature(index)); 2040 return trap_->GetTrapValue(module_->GetSignature(index));
2061 } 2041 }
2062 Node* table = FunctionTable(); 2042 Node* table = FunctionTable();
2063 2043
2064 // Load signature from the table and check. 2044 // Load signature from the table and check.
2065 // The table is a FixedArray; signatures are encoded as SMIs. 2045 // The table is a FixedArray; signatures are encoded as SMIs.
2066 // [sig1, sig2, sig3, ...., code1, code2, code3 ...] 2046 // [sig1, sig2, sig3, ...., code1, code2, code3 ...]
2067 ElementAccess access = AccessBuilder::ForFixedArrayElement(); 2047 ElementAccess access = AccessBuilder::ForFixedArrayElement();
2068 const int fixed_offset = access.header_size - access.tag(); 2048 const int fixed_offset = access.header_size - access.tag();
2069 { 2049 {
2070 Node* load_sig = graph()->NewNode( 2050 Node* load_sig = graph()->NewNode(
2071 machine->Load(MachineType::AnyTagged()), table, 2051 machine->Load(MachineType::AnyTagged()), table,
2072 graph()->NewNode(machine->Int32Add(), 2052 graph()->NewNode(machine->Int32Add(),
2073 graph()->NewNode(machine->Word32Shl(), key, 2053 graph()->NewNode(machine->Word32Shl(), key,
2074 Int32Constant(kPointerSizeLog2)), 2054 Int32Constant(kPointerSizeLog2)),
2075 Int32Constant(fixed_offset)), 2055 Int32Constant(fixed_offset)),
2076 *effect_, *control_); 2056 *effect_, *control_);
2077 Node* sig_match = graph()->NewNode(machine->WordEqual(), load_sig, 2057 Node* sig_match = graph()->NewNode(machine->WordEqual(), load_sig,
2078 jsgraph()->SmiConstant(index)); 2058 jsgraph()->SmiConstant(index));
2079 trap_->AddTrapIfFalse(kTrapFuncSigMismatch, sig_match); 2059 trap_->AddTrapIfFalse(wasm::kTrapFuncSigMismatch, sig_match);
2080 } 2060 }
2081 2061
2082 // Load code object from the table. 2062 // Load code object from the table.
2083 int offset = fixed_offset + kPointerSize * table_size; 2063 int offset = fixed_offset + kPointerSize * table_size;
2084 Node* load_code = graph()->NewNode( 2064 Node* load_code = graph()->NewNode(
2085 machine->Load(MachineType::AnyTagged()), table, 2065 machine->Load(MachineType::AnyTagged()), table,
2086 graph()->NewNode(machine->Int32Add(), 2066 graph()->NewNode(machine->Int32Add(),
2087 graph()->NewNode(machine->Word32Shl(), key, 2067 graph()->NewNode(machine->Word32Shl(), key,
2088 Int32Constant(kPointerSizeLog2)), 2068 Int32Constant(kPointerSizeLog2)),
2089 Int32Constant(offset)), 2069 Int32Constant(offset)),
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
2388 cond = jsgraph()->Int32Constant(0); 2368 cond = jsgraph()->Int32Constant(0);
2389 } else { 2369 } else {
2390 // Check against the limit. 2370 // Check against the limit.
2391 size_t limit = size - offset - memsize; 2371 size_t limit = size - offset - memsize;
2392 CHECK(limit <= kMaxUInt32); 2372 CHECK(limit <= kMaxUInt32);
2393 cond = graph()->NewNode( 2373 cond = graph()->NewNode(
2394 jsgraph()->machine()->Uint32LessThanOrEqual(), index, 2374 jsgraph()->machine()->Uint32LessThanOrEqual(), index,
2395 jsgraph()->Int32Constant(static_cast<uint32_t>(limit))); 2375 jsgraph()->Int32Constant(static_cast<uint32_t>(limit)));
2396 } 2376 }
2397 2377
2398 trap_->AddTrapIfFalse(kTrapMemOutOfBounds, cond); 2378 trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, cond);
2399 } 2379 }
2400 2380
2401 2381
2402 Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype, 2382 Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype,
2403 Node* index, uint32_t offset) { 2383 Node* index, uint32_t offset) {
2404 Node* load; 2384 Node* load;
2405 2385
2406 if (module_ && module_->asm_js()) { 2386 if (module_ && module_->asm_js()) {
2407 // asm.js semantics use CheckedLoad (i.e. OOB reads return 0ish). 2387 // asm.js semantics use CheckedLoad (i.e. OOB reads return 0ish).
2408 DCHECK_EQ(0, offset); 2388 DCHECK_EQ(0, offset);
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
2798 static_cast<int>(function.code_end_offset - function.code_start_offset), 2778 static_cast<int>(function.code_end_offset - function.code_start_offset),
2799 decode_ms, static_cast<int>(graph.NodeCount()), compile_ms); 2779 decode_ms, static_cast<int>(graph.NodeCount()), compile_ms);
2800 } 2780 }
2801 return code; 2781 return code;
2802 } 2782 }
2803 2783
2804 2784
2805 } // namespace compiler 2785 } // namespace compiler
2806 } // namespace internal 2786 } // namespace internal
2807 } // namespace v8 2787 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/wasm/wasm-opcodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698