Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 2530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2541 } | 2541 } |
| 2542 | 2542 |
| 2543 // Build the start and the parameter nodes. | 2543 // Build the start and the parameter nodes. |
| 2544 Isolate* isolate = jsgraph()->isolate(); | 2544 Isolate* isolate = jsgraph()->isolate(); |
| 2545 CallDescriptor* desc; | 2545 CallDescriptor* desc; |
| 2546 Node* start = Start(param_count + 3); | 2546 Node* start = Start(param_count + 3); |
| 2547 *effect_ = start; | 2547 *effect_ = start; |
| 2548 *control_ = start; | 2548 *control_ = start; |
| 2549 Node** args = Buffer(wasm_count + 7); | 2549 Node** args = Buffer(wasm_count + 7); |
| 2550 | 2550 |
| 2551 // The default context of the target. | 2551 Node* call; |
| 2552 Handle<Context> target_context = isolate->native_context(); | 2552 bool direct_call = false; |
| 2553 | 2553 |
| 2554 // Optimization: check if the target is a JSFunction with the right arity so | |
| 2555 // that we can call it directly. | |
| 2556 bool call_direct = false; | |
| 2557 int pos = 0; | |
| 2558 if (target->IsJSFunction()) { | 2554 if (target->IsJSFunction()) { |
| 2559 Handle<JSFunction> function = Handle<JSFunction>::cast(target); | 2555 Handle<JSFunction> function = Handle<JSFunction>::cast(target); |
| 2560 if (function->shared()->internal_formal_parameter_count() == wasm_count) { | 2556 if (function->shared()->internal_formal_parameter_count() == wasm_count) { |
| 2561 call_direct = true; | 2557 direct_call = true; |
| 2562 | 2558 int pos = 0; |
| 2563 args[pos++] = jsgraph()->Constant(target); // target callable. | 2559 args[pos++] = jsgraph()->Constant(target); // target callable. |
| 2564 // Receiver. | 2560 // Receiver. |
| 2565 if (is_sloppy(function->shared()->language_mode()) && | 2561 if (is_sloppy(function->shared()->language_mode()) && |
| 2566 !function->shared()->native()) { | 2562 !function->shared()->native()) { |
| 2567 args[pos++] = | 2563 args[pos++] = |
| 2568 HeapConstant(handle(function->context()->global_proxy(), isolate)); | 2564 HeapConstant(handle(function->context()->global_proxy(), isolate)); |
| 2569 } else { | 2565 } else { |
| 2570 args[pos++] = jsgraph()->Constant( | 2566 args[pos++] = jsgraph()->Constant( |
| 2571 handle(isolate->heap()->undefined_value(), isolate)); | 2567 handle(isolate->heap()->undefined_value(), isolate)); |
| 2572 } | 2568 } |
| 2573 | 2569 |
| 2574 desc = Linkage::GetJSCallDescriptor( | 2570 desc = Linkage::GetJSCallDescriptor( |
| 2575 graph()->zone(), false, wasm_count + 1, CallDescriptor::kNoFlags); | 2571 graph()->zone(), false, wasm_count + 1, CallDescriptor::kNoFlags); |
| 2576 | 2572 |
| 2577 // For a direct call we have to use the context of the JSFunction. | 2573 // Convert WASM numbers to JS values. |
|
titzer
2016/09/01 14:35:17
Is it possible to factor this loop out with its ca
ahaas
2016/09/01 17:17:52
Done.
| |
| 2578 target_context = handle(function->context()); | 2574 int param_index = 0; |
| 2575 for (int i = 0; i < wasm_count; ++i) { | |
| 2576 Node* param = graph()->NewNode( | |
| 2577 jsgraph()->common()->Parameter(param_index++), start); | |
| 2578 args[pos++] = ToJS(param, sig->GetParam(i)); | |
| 2579 if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kAstI64) { | |
| 2580 // On 32 bit platforms we have to skip the high word of int64 | |
| 2581 // parameters. | |
| 2582 param_index++; | |
| 2583 } | |
| 2584 } | |
| 2585 | |
| 2586 args[pos++] = jsgraph()->UndefinedConstant(); // new target | |
| 2587 args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count | |
| 2588 args[pos++] = HeapConstant(handle(function->context())); | |
| 2589 args[pos++] = *effect_; | |
| 2590 args[pos++] = *control_; | |
| 2591 | |
| 2592 call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args); | |
| 2579 } | 2593 } |
| 2580 } | 2594 } |
| 2581 | 2595 |
| 2582 // We cannot call the target directly, we have to use the Call builtin. | 2596 // We cannot call the target directly, we have to use the Call builtin. |
| 2583 if (!call_direct) { | 2597 if (!direct_call) { |
| 2598 int pos = 0; | |
| 2584 Callable callable = CodeFactory::Call(isolate); | 2599 Callable callable = CodeFactory::Call(isolate); |
| 2585 args[pos++] = jsgraph()->HeapConstant(callable.code()); | 2600 args[pos++] = jsgraph()->HeapConstant(callable.code()); |
| 2586 args[pos++] = jsgraph()->Constant(target); // target callable | 2601 args[pos++] = jsgraph()->Constant(target); // target callable |
| 2587 args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count | 2602 args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count |
| 2588 args[pos++] = jsgraph()->Constant( | 2603 args[pos++] = jsgraph()->Constant( |
| 2589 handle(isolate->heap()->undefined_value(), isolate)); // receiver | 2604 handle(isolate->heap()->undefined_value(), isolate)); // receiver |
| 2590 | 2605 |
| 2591 desc = Linkage::GetStubCallDescriptor(isolate, graph()->zone(), | 2606 desc = Linkage::GetStubCallDescriptor(isolate, graph()->zone(), |
| 2592 callable.descriptor(), wasm_count + 1, | 2607 callable.descriptor(), wasm_count + 1, |
| 2593 CallDescriptor::kNoFlags); | 2608 CallDescriptor::kNoFlags); |
| 2609 | |
| 2610 // Convert WASM numbers to JS values. | |
| 2611 int param_index = 0; | |
| 2612 for (int i = 0; i < wasm_count; ++i) { | |
| 2613 Node* param = graph()->NewNode( | |
| 2614 jsgraph()->common()->Parameter(param_index++), start); | |
| 2615 args[pos++] = ToJS(param, sig->GetParam(i)); | |
| 2616 if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kAstI64) { | |
| 2617 // On 32 bit platforms we have to skip the high word of int64 | |
| 2618 // parameters. | |
| 2619 param_index++; | |
| 2620 } | |
| 2621 } | |
| 2622 | |
| 2623 // The native_context is sufficient here, because all kind of callables | |
| 2624 // which depend on the context provide their own context. The context here | |
| 2625 // is only needed if the target is a constructor to throw a TypeError, if | |
| 2626 // the target is a native function, or if the target is a callable JSObject, | |
| 2627 // which can only be constructed by the runtime. | |
| 2628 args[pos++] = HeapConstant(isolate->native_context()); | |
| 2629 args[pos++] = *effect_; | |
| 2630 args[pos++] = *control_; | |
| 2631 | |
| 2632 call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args); | |
| 2594 } | 2633 } |
| 2595 | 2634 |
| 2596 // Convert WASM numbers to JS values. | |
| 2597 int param_index = 0; | |
| 2598 for (int i = 0; i < wasm_count; ++i) { | |
| 2599 Node* param = | |
| 2600 graph()->NewNode(jsgraph()->common()->Parameter(param_index++), start); | |
| 2601 args[pos++] = ToJS(param, sig->GetParam(i)); | |
| 2602 if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kAstI64) { | |
| 2603 // On 32 bit platforms we have to skip the high word of int64 parameters. | |
| 2604 param_index++; | |
| 2605 } | |
| 2606 } | |
| 2607 | |
| 2608 if (call_direct) { | |
| 2609 args[pos++] = jsgraph()->UndefinedConstant(); // new target | |
| 2610 args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count | |
| 2611 } | |
| 2612 | |
| 2613 args[pos++] = HeapConstant(target_context); | |
| 2614 args[pos++] = *effect_; | |
| 2615 args[pos++] = *control_; | |
| 2616 | |
| 2617 Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args); | |
| 2618 | |
| 2619 // Convert the return value back. | 2635 // Convert the return value back. |
| 2620 Node* ret; | 2636 Node* ret; |
| 2621 Node* val = | 2637 Node* val = |
| 2622 FromJS(call, HeapConstant(isolate->native_context()), | 2638 FromJS(call, HeapConstant(isolate->native_context()), |
| 2623 sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); | 2639 sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); |
| 2624 if (jsgraph()->machine()->Is32() && sig->return_count() > 0 && | 2640 if (jsgraph()->machine()->Is32() && sig->return_count() > 0 && |
| 2625 sig->GetReturn() == wasm::kAstI64) { | 2641 sig->GetReturn() == wasm::kAstI64) { |
| 2626 ret = graph()->NewNode(jsgraph()->common()->Return(), val, | 2642 ret = graph()->NewNode(jsgraph()->common()->Return(), val, |
| 2627 graph()->NewNode(jsgraph()->machine()->Word32Sar(), | 2643 graph()->NewNode(jsgraph()->machine()->Word32Sar(), |
| 2628 val, jsgraph()->Int32Constant(31)), | 2644 val, jsgraph()->Int32Constant(31)), |
| (...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3236 function_->code_start_offset), | 3252 function_->code_start_offset), |
| 3237 compile_ms); | 3253 compile_ms); |
| 3238 } | 3254 } |
| 3239 | 3255 |
| 3240 return code; | 3256 return code; |
| 3241 } | 3257 } |
| 3242 | 3258 |
| 3243 } // namespace compiler | 3259 } // namespace compiler |
| 3244 } // namespace internal | 3260 } // namespace internal |
| 3245 } // namespace v8 | 3261 } // namespace v8 |
| OLD | NEW |