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

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

Issue 2254803002: [wasm] Throw a type error if an I64 is exported to JS. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove IfSuccess nodes for now. Created 4 years, 4 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/messages.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 <memory> 7 #include <memory>
8 8
9 #include "src/isolate-inl.h" 9 #include "src/isolate-inl.h"
10 10
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 56
57 void MergeControlToEnd(JSGraph* jsgraph, Node* node) { 57 void MergeControlToEnd(JSGraph* jsgraph, Node* node) {
58 Graph* g = jsgraph->graph(); 58 Graph* g = jsgraph->graph();
59 if (g->end()) { 59 if (g->end()) {
60 NodeProperties::MergeControlToEnd(g, jsgraph->common(), node); 60 NodeProperties::MergeControlToEnd(g, jsgraph->common(), node);
61 } else { 61 } else {
62 g->SetEnd(g->NewNode(jsgraph->common()->End(1), node)); 62 g->SetEnd(g->NewNode(jsgraph->common()->End(1), node));
63 } 63 }
64 } 64 }
65 65
66 Node* BuildCallToRuntime(Runtime::FunctionId f, JSGraph* jsgraph,
67 Handle<Context> context, Node** parameters,
68 int parameter_count, Node** effect_ptr,
69 Node** control_ptr) {
70 // At the moment we only allow 2 parameters. If more parameters are needed,
71 // then the size of {inputs} below has to be increased accordingly.
72 DCHECK(parameter_count <= 2);
73 const Runtime::Function* fun = Runtime::FunctionForId(f);
74 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
75 jsgraph->zone(), f, fun->nargs, Operator::kNoProperties,
76 CallDescriptor::kNoFlags);
77 // CEntryStubConstant nodes have to be created and cached in the main
78 // thread. At the moment this is only done for CEntryStubConstant(1).
79 DCHECK_EQ(1, fun->result_size);
80 Node* inputs[8];
81 int count = 0;
82 inputs[count++] = jsgraph->CEntryStubConstant(fun->result_size);
83 for (int i = 0; i < parameter_count; i++) {
84 inputs[count++] = parameters[i];
85 }
86 inputs[count++] = jsgraph->ExternalConstant(
87 ExternalReference(f, jsgraph->isolate())); // ref
88 inputs[count++] = jsgraph->Int32Constant(fun->nargs); // arity
89 inputs[count++] = jsgraph->HeapConstant(context); // context
90 inputs[count++] = *effect_ptr;
91 inputs[count++] = *control_ptr;
92
93 Node* node =
94 jsgraph->graph()->NewNode(jsgraph->common()->Call(desc), count, inputs);
95 *effect_ptr = node;
96 return node;
97 }
98
66 } // namespace 99 } // namespace
67 100
68 // A helper that handles building graph fragments for trapping. 101 // A helper that handles building graph fragments for trapping.
69 // To avoid generating a ton of redundant code that just calls the runtime 102 // To avoid generating a ton of redundant code that just calls the runtime
70 // to trap, we generate a per-trap-reason block of code that all trap sites 103 // to trap, we generate a per-trap-reason block of code that all trap sites
71 // in this function will branch to. 104 // in this function will branch to.
72 class WasmTrapHelper : public ZoneObject { 105 class WasmTrapHelper : public ZoneObject {
73 public: 106 public:
74 explicit WasmTrapHelper(WasmGraphBuilder* builder) 107 explicit WasmTrapHelper(WasmGraphBuilder* builder)
75 : builder_(builder), 108 : builder_(builder),
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 1), 252 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 1),
220 reason_node, *control_ptr); 253 reason_node, *control_ptr);
221 trap_position_ = 254 trap_position_ =
222 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 1), 255 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 1),
223 position_node, *control_ptr); 256 position_node, *control_ptr);
224 257
225 Node* trap_reason_smi = builder_->BuildChangeInt32ToSmi(trap_reason_); 258 Node* trap_reason_smi = builder_->BuildChangeInt32ToSmi(trap_reason_);
226 Node* trap_position_smi = builder_->BuildChangeInt32ToSmi(trap_position_); 259 Node* trap_position_smi = builder_->BuildChangeInt32ToSmi(trap_position_);
227 260
228 if (module && !module->instance->context.is_null()) { 261 if (module && !module->instance->context.is_null()) {
229 // Use the module context to call the runtime to throw an exception. 262 Node* parameters[] = {trap_reason_smi, // message id
230 Runtime::FunctionId f = Runtime::kThrowWasmError; 263 trap_position_smi}; // byte position
231 const Runtime::Function* fun = Runtime::FunctionForId(f); 264 BuildCallToRuntime(Runtime::kThrowWasmError, jsgraph(),
232 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor( 265 module->instance->context, parameters,
233 jsgraph()->zone(), f, fun->nargs, Operator::kNoProperties, 266 arraysize(parameters), effect_ptr, control_ptr);
234 CallDescriptor::kNoFlags);
235 // CEntryStubConstant nodes have to be created and cached in the main
236 // thread. At the moment this is only done for CEntryStubConstant(1).
237 DCHECK_EQ(1, fun->result_size);
238 Node* inputs[] = {
239 jsgraph()->CEntryStubConstant(fun->result_size), // C entry
240 trap_reason_smi, // message id
241 trap_position_smi, // byte position
242 jsgraph()->ExternalConstant(
243 ExternalReference(f, jsgraph()->isolate())), // ref
244 jsgraph()->Int32Constant(fun->nargs), // arity
245 builder_->HeapConstant(module->instance->context), // context
246 *effect_ptr,
247 *control_ptr};
248
249 Node* node = graph()->NewNode(
250 common()->Call(desc), static_cast<int>(arraysize(inputs)), inputs);
251 *effect_ptr = node;
252 *control_ptr = graph()->NewNode(common()->IfSuccess(), node);
253 } 267 }
254 if (false) { 268 if (false) {
255 // End the control flow with a throw 269 // End the control flow with a throw
256 Node* thrw = 270 Node* thrw =
257 graph()->NewNode(common()->Throw(), jsgraph()->ZeroConstant(), 271 graph()->NewNode(common()->Throw(), jsgraph()->ZeroConstant(),
258 *effect_ptr, *control_ptr); 272 *effect_ptr, *control_ptr);
259 end = thrw; 273 end = thrw;
260 } else { 274 } else {
261 // End the control flow with returning 0xdeadbeef 275 // End the control flow with returning 0xdeadbeef
262 Node* ret_value = GetTrapValue(builder_->GetFunctionSignature()); 276 Node* ret_value = GetTrapValue(builder_->GetFunctionSignature());
(...skipping 1917 matching lines...) Expand 10 before | Expand all | Expand 10 after
2180 value = graph()->NewNode(common->Phi(MachineRepresentation::kTagged, 2), vsmi, 2194 value = graph()->NewNode(common->Phi(MachineRepresentation::kTagged, 2), vsmi,
2181 vbox, control); 2195 vbox, control);
2182 return value; 2196 return value;
2183 } 2197 }
2184 2198
2185 Node* WasmGraphBuilder::ToJS(Node* node, wasm::LocalType type) { 2199 Node* WasmGraphBuilder::ToJS(Node* node, wasm::LocalType type) {
2186 switch (type) { 2200 switch (type) {
2187 case wasm::kAstI32: 2201 case wasm::kAstI32:
2188 return BuildChangeInt32ToTagged(node); 2202 return BuildChangeInt32ToTagged(node);
2189 case wasm::kAstI64: 2203 case wasm::kAstI64:
2190 // TODO(titzer): i64->JS has no good solution right now. Using lower 32 2204 DCHECK(module_ && !module_->instance->context.is_null());
2191 // bits. 2205 // Throw a TypeError.
2192 if (jsgraph()->machine()->Is64()) { 2206 return BuildCallToRuntime(Runtime::kWasmThrowTypeError, jsgraph(),
2193 // On 32 bit platforms we do not have to do the truncation because the 2207 module_->instance->context, nullptr, 0, effect_,
2194 // node we get in as a parameter only contains the low word anyways. 2208 control_);
2195 node = graph()->NewNode(jsgraph()->machine()->TruncateInt64ToInt32(),
2196 node);
2197 }
2198 return BuildChangeInt32ToTagged(node);
2199 case wasm::kAstF32: 2209 case wasm::kAstF32:
2200 node = graph()->NewNode(jsgraph()->machine()->ChangeFloat32ToFloat64(), 2210 node = graph()->NewNode(jsgraph()->machine()->ChangeFloat32ToFloat64(),
2201 node); 2211 node);
2202 return BuildChangeFloat64ToTagged(node); 2212 return BuildChangeFloat64ToTagged(node);
2203 case wasm::kAstF64: 2213 case wasm::kAstF64:
2204 return BuildChangeFloat64ToTagged(node); 2214 return BuildChangeFloat64ToTagged(node);
2205 case wasm::kAstStmt: 2215 case wasm::kAstStmt:
2206 return jsgraph()->UndefinedConstant(); 2216 return jsgraph()->UndefinedConstant();
2207 default: 2217 default:
2208 UNREACHABLE(); 2218 UNREACHABLE();
2209 return nullptr; 2219 return nullptr;
2210 } 2220 }
2211 } 2221 }
2212 2222
2213 Node* WasmGraphBuilder::BuildJavaScriptToNumber(Node* node, Node* context, 2223 Node* WasmGraphBuilder::BuildJavaScriptToNumber(Node* node, Node* context,
2214 Node* effect, Node* control) { 2224 Node* effect, Node* control) {
2215 Callable callable = CodeFactory::ToNumber(jsgraph()->isolate()); 2225 Callable callable = CodeFactory::ToNumber(jsgraph()->isolate());
2216 CallDescriptor* desc = Linkage::GetStubCallDescriptor( 2226 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
2217 jsgraph()->isolate(), jsgraph()->zone(), callable.descriptor(), 0, 2227 jsgraph()->isolate(), jsgraph()->zone(), callable.descriptor(), 0,
2218 CallDescriptor::kNoFlags, Operator::kNoProperties); 2228 CallDescriptor::kNoFlags, Operator::kNoProperties);
2219 Node* stub_code = jsgraph()->HeapConstant(callable.code()); 2229 Node* stub_code = jsgraph()->HeapConstant(callable.code());
2220 2230
2221 Node* result = graph()->NewNode(jsgraph()->common()->Call(desc), stub_code, 2231 Node* result = graph()->NewNode(jsgraph()->common()->Call(desc), stub_code,
2222 node, context, effect, control); 2232 node, context, effect, control);
2223 2233
2224 *effect_ = result; 2234 *effect_ = result;
2225 *control_ = graph()->NewNode(jsgraph()->common()->IfSuccess(), result);
2226 2235
2227 return result; 2236 return result;
2228 } 2237 }
2229 2238
2230 bool CanCover(Node* value, IrOpcode::Value opcode) { 2239 bool CanCover(Node* value, IrOpcode::Value opcode) {
2231 if (value->opcode() != opcode) return false; 2240 if (value->opcode() != opcode) return false;
2232 bool first = true; 2241 bool first = true;
2233 for (Edge const edge : value->use_edges()) { 2242 for (Edge const edge : value->use_edges()) {
2234 if (NodeProperties::IsControlEdge(edge)) continue; 2243 if (NodeProperties::IsControlEdge(edge)) continue;
2235 if (NodeProperties::IsEffectEdge(edge)) continue; 2244 if (NodeProperties::IsEffectEdge(edge)) continue;
(...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after
3227 function_->code_start_offset), 3236 function_->code_start_offset),
3228 compile_ms); 3237 compile_ms);
3229 } 3238 }
3230 3239
3231 return code; 3240 return code;
3232 } 3241 }
3233 3242
3234 } // namespace compiler 3243 } // namespace compiler
3235 } // namespace internal 3244 } // namespace internal
3236 } // namespace v8 3245 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698