3263550e86
This way requests to compile won't end prematurely after reading bytecode if interpreter is enabled. Change-Id: Ic06cae98ea65bc4656ef491fbd306d34b0e1ef4c Reviewed-on: https://dart-review.googlesource.com/75628 Reviewed-by: Zach Anderson <zra@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
242 lines
7.7 KiB
C++
242 lines
7.7 KiB
C++
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#ifndef RUNTIME_VM_COMPILER_FRONTEND_SCOPE_BUILDER_H_
|
|
#define RUNTIME_VM_COMPILER_FRONTEND_SCOPE_BUILDER_H_
|
|
|
|
#if !defined(DART_PRECOMPILED_RUNTIME)
|
|
|
|
#include "vm/compiler/frontend/kernel_translation_helper.h"
|
|
#include "vm/hash_map.h"
|
|
#include "vm/object.h"
|
|
#include "vm/parser.h" // For ParsedFunction.
|
|
|
|
namespace dart {
|
|
namespace kernel {
|
|
|
|
class ScopeBuildingResult;
|
|
|
|
class ScopeBuilder {
|
|
public:
|
|
explicit ScopeBuilder(ParsedFunction* parsed_function);
|
|
|
|
virtual ~ScopeBuilder() = default;
|
|
|
|
ScopeBuildingResult* BuildScopes();
|
|
|
|
private:
|
|
void VisitField();
|
|
|
|
void VisitProcedure();
|
|
|
|
void VisitConstructor();
|
|
|
|
void VisitFunctionNode();
|
|
void VisitNode();
|
|
void VisitInitializer();
|
|
void VisitExpression();
|
|
void VisitStatement();
|
|
void VisitArguments();
|
|
void VisitVariableDeclaration();
|
|
void VisitDartType();
|
|
void VisitInterfaceType(bool simple);
|
|
void VisitFunctionType(bool simple);
|
|
void VisitTypeParameterType();
|
|
void HandleLocalFunction(intptr_t parent_kernel_offset);
|
|
|
|
AbstractType& BuildAndVisitVariableType();
|
|
|
|
void EnterScope(intptr_t kernel_offset);
|
|
void ExitScope(TokenPosition start_position, TokenPosition end_position);
|
|
|
|
virtual void ReportUnexpectedTag(const char* variant, Tag tag);
|
|
|
|
// This enum controls which parameters would be marked as requring type
|
|
// check on the callee side.
|
|
enum ParameterTypeCheckMode {
|
|
// All parameters will be checked.
|
|
kTypeCheckAllParameters,
|
|
|
|
// Only parameters marked as covariant or generic-covariant-impl will be
|
|
// checked.
|
|
kTypeCheckForNonDynamicallyInvokedMethod,
|
|
|
|
// Only parameters *not* marked as covariant or generic-covariant-impl will
|
|
// be checked. The rest would be checked in the method itself.
|
|
// Inverse of kTypeCheckForNonDynamicallyInvokedMethod.
|
|
kTypeCheckEverythingNotCheckedInNonDynamicallyInvokedMethod,
|
|
|
|
// No parameters will be checked.
|
|
kTypeCheckForStaticFunction,
|
|
};
|
|
|
|
// This assumes that the reader is at a FunctionNode,
|
|
// about to read the positional parameters.
|
|
void AddPositionalAndNamedParameters(
|
|
intptr_t pos,
|
|
ParameterTypeCheckMode type_check_mode,
|
|
const ProcedureAttributesMetadata& attrs);
|
|
|
|
// This assumes that the reader is at a FunctionNode,
|
|
// about to read a parameter (i.e. VariableDeclaration).
|
|
void AddVariableDeclarationParameter(
|
|
intptr_t pos,
|
|
ParameterTypeCheckMode type_check_mode,
|
|
const ProcedureAttributesMetadata& attrs);
|
|
|
|
LocalVariable* MakeVariable(TokenPosition declaration_pos,
|
|
TokenPosition token_pos,
|
|
const String& name,
|
|
const AbstractType& type,
|
|
const InferredTypeMetadata* param_type_md = NULL);
|
|
|
|
void AddExceptionVariable(GrowableArray<LocalVariable*>* variables,
|
|
const char* prefix,
|
|
intptr_t nesting_depth);
|
|
|
|
void FinalizeExceptionVariable(GrowableArray<LocalVariable*>* variables,
|
|
GrowableArray<LocalVariable*>* raw_variables,
|
|
const String& symbol,
|
|
intptr_t nesting_depth);
|
|
|
|
void AddTryVariables();
|
|
void AddCatchVariables();
|
|
void FinalizeCatchVariables();
|
|
void AddIteratorVariable();
|
|
void AddSwitchVariable();
|
|
|
|
// Record an assignment or reference to a variable. If the occurrence is
|
|
// in a nested function, ensure that the variable is handled properly as a
|
|
// captured variable.
|
|
void LookupVariable(intptr_t declaration_binary_offset);
|
|
|
|
StringIndex GetNameFromVariableDeclaration(intptr_t kernel_offset,
|
|
const Function& function);
|
|
|
|
const String& GenerateName(const char* prefix, intptr_t suffix);
|
|
|
|
void HandleSpecialLoad(LocalVariable** variable, const String& symbol);
|
|
void LookupCapturedVariableByName(LocalVariable** variable,
|
|
const String& name);
|
|
|
|
struct DepthState {
|
|
explicit DepthState(intptr_t function)
|
|
: loop_(0),
|
|
function_(function),
|
|
try_(0),
|
|
catch_(0),
|
|
finally_(0),
|
|
for_in_(0) {}
|
|
|
|
intptr_t loop_;
|
|
intptr_t function_;
|
|
intptr_t try_;
|
|
intptr_t catch_;
|
|
intptr_t finally_;
|
|
intptr_t for_in_;
|
|
};
|
|
|
|
ScopeBuildingResult* result_;
|
|
ParsedFunction* parsed_function_;
|
|
|
|
ActiveClass active_class_;
|
|
|
|
TranslationHelper translation_helper_;
|
|
Zone* zone_;
|
|
|
|
FunctionNodeHelper::AsyncMarker current_function_async_marker_;
|
|
LocalScope* current_function_scope_;
|
|
LocalScope* scope_;
|
|
DepthState depth_;
|
|
|
|
intptr_t name_index_;
|
|
|
|
bool needs_expr_temp_;
|
|
TokenPosition first_body_token_position_;
|
|
|
|
KernelReaderHelper helper_;
|
|
InferredTypeMetadataHelper inferred_type_metadata_helper_;
|
|
ProcedureAttributesMetadataHelper procedure_attributes_metadata_helper_;
|
|
TypeTranslator type_translator_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(ScopeBuilder);
|
|
};
|
|
|
|
struct FunctionScope {
|
|
intptr_t kernel_offset;
|
|
LocalScope* scope;
|
|
};
|
|
|
|
class ScopeBuildingResult : public ZoneAllocated {
|
|
public:
|
|
ScopeBuildingResult()
|
|
: this_variable(NULL),
|
|
type_arguments_variable(NULL),
|
|
switch_variable(NULL),
|
|
finally_return_variable(NULL),
|
|
setter_value(NULL),
|
|
yield_jump_variable(NULL),
|
|
yield_context_variable(NULL),
|
|
raw_variable_counter_(0) {}
|
|
|
|
IntMap<LocalVariable*> locals;
|
|
IntMap<LocalScope*> scopes;
|
|
GrowableArray<FunctionScope> function_scopes;
|
|
|
|
// Only non-NULL for instance functions.
|
|
LocalVariable* this_variable;
|
|
|
|
// Only non-NULL for factory constructor functions.
|
|
LocalVariable* type_arguments_variable;
|
|
|
|
// Non-NULL when the function contains a switch statement.
|
|
LocalVariable* switch_variable;
|
|
|
|
// Non-NULL when the function contains a return inside a finally block.
|
|
LocalVariable* finally_return_variable;
|
|
|
|
// Non-NULL when the function is a setter.
|
|
LocalVariable* setter_value;
|
|
|
|
// Non-NULL if the function contains yield statement.
|
|
// TODO(27590) actual variable is called :await_jump_var, we should rename
|
|
// it to reflect the fact that it is used for both await and yield.
|
|
LocalVariable* yield_jump_variable;
|
|
|
|
// Non-NULL if the function contains yield statement.
|
|
// TODO(27590) actual variable is called :await_ctx_var, we should rename
|
|
// it to reflect the fact that it is used for both await and yield.
|
|
LocalVariable* yield_context_variable;
|
|
|
|
// Variables used in exception handlers, one per exception handler nesting
|
|
// level.
|
|
GrowableArray<LocalVariable*> exception_variables;
|
|
GrowableArray<LocalVariable*> stack_trace_variables;
|
|
GrowableArray<LocalVariable*> catch_context_variables;
|
|
|
|
// These are used to access the raw exception/stacktrace variables (and are
|
|
// used to put them into the captured variables in the context).
|
|
GrowableArray<LocalVariable*> raw_exception_variables;
|
|
GrowableArray<LocalVariable*> raw_stack_trace_variables;
|
|
intptr_t raw_variable_counter_;
|
|
|
|
// For-in iterators, one per for-in nesting level.
|
|
GrowableArray<LocalVariable*> iterator_variables;
|
|
|
|
private:
|
|
DISALLOW_COPY_AND_ASSIGN(ScopeBuildingResult);
|
|
};
|
|
|
|
// Returns true if the given method can skip type checks for all arguments
|
|
// that are not covariant or generic covariant in its implementation.
|
|
bool MethodCanSkipTypeChecksForNonCovariantArguments(
|
|
const Function& method,
|
|
const ProcedureAttributesMetadata& attrs);
|
|
|
|
} // namespace kernel
|
|
} // namespace dart
|
|
|
|
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
|
#endif // RUNTIME_VM_COMPILER_FRONTEND_SCOPE_BUILDER_H_
|