1// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_COMPILER_FRONTEND_PROLOGUE_BUILDER_H_
6#define RUNTIME_VM_COMPILER_FRONTEND_PROLOGUE_BUILDER_H_
7
8#if defined(DART_PRECOMPILED_RUNTIME)
9#error "AOT runtime should not use compiler sources (including header files)"
10#endif // defined(DART_PRECOMPILED_RUNTIME)
11
12#include "vm/compiler/frontend/base_flow_graph_builder.h"
13
14namespace dart {
15namespace kernel {
16
17// Responsible for building IR code for prologues of functions.
18//
19// This code handles initialization of local variables which the
20// prologue needs to setup, including initialization of the:
21//
22// * current context variable, from the passed closure object
23// * function_type_arguments variable, from the stack above fp
24// * raw parameter variables, from the stack above fp
25//
26// if needed.
27//
28// Furthermore it performs all necessary checks which could lead into a
29// no-such-method bailout, including check that:
30//
31// * the number of passed positional arguments is correct
32// * the names of passed named arguments are correct
33// * the number of function type arguments is correct
34//
35// if needed.
36//
37// Most of these things are done by interpreting the caller-supplied arguments
38// descriptor.
39class PrologueBuilder : public BaseFlowGraphBuilder {
40 public:
41 PrologueBuilder(const ParsedFunction* parsed_function,
42 intptr_t last_used_id,
43 bool compiling_for_osr,
44 bool is_inlining)
45 : BaseFlowGraphBuilder(parsed_function, last_used_id),
46 compiling_for_osr_(compiling_for_osr),
47 is_inlining_(is_inlining) {}
48
49 BlockEntryInstr* BuildPrologue(BlockEntryInstr* entry,
50 PrologueInfo* prologue_info);
51
52 Fragment BuildOptionalParameterHandling(JoinEntryInstr* nsm,
53 LocalVariable* temp_var);
54
55 static bool HasEmptyPrologue(const Function& function);
56 static bool PrologueSkippableOnUncheckedEntry(const Function& function);
57
58 intptr_t last_used_block_id() const { return last_used_block_id_; }
59
60 private:
61 Fragment BuildTypeArgumentsLengthCheck(JoinEntryInstr* nsm,
62 bool expect_type_args);
63
64 Fragment BuildFixedParameterLengthChecks(JoinEntryInstr* nsm);
65
66 Fragment BuildClosureContextHandling();
67
68 Fragment BuildTypeArgumentsHandling(JoinEntryInstr* nsm);
69
70 LocalVariable* ParameterVariable(intptr_t index) {
71 return parsed_function_->RawParameterVariable(index);
72 }
73
74 const Instance& DefaultParameterValueAt(intptr_t i) {
75 if (parsed_function_->default_parameter_values() != NULL) {
76 return parsed_function_->DefaultParameterValueAt(i);
77 }
78
79 ASSERT(parsed_function_->function().kind() ==
80 FunctionLayout::kNoSuchMethodDispatcher);
81 return Instance::null_instance();
82 }
83
84 void SortOptionalNamedParametersInto(int* opt_param_position,
85 int num_fixed_params,
86 int num_params);
87
88 bool compiling_for_osr_;
89 bool is_inlining_;
90};
91
92} // namespace kernel
93} // namespace dart
94
95#endif // RUNTIME_VM_COMPILER_FRONTEND_PROLOGUE_BUILDER_H_
96