[vm] Return token position from BuildStatement.

Not every statement has a serialized position we can use for coverage.
For example, the otherwise part of an if statement doesn't have a
position. So for branch coverage, BuildStatement needs to return a token
position of the statement, so that we can pass it to the record coverage
instruction.

For example, if statement's otherwise fragment will look like this:

TokenPosition other_pos = TokenPosition::kNoSource;
Fragment otherwise_statement = BuildStatement(&other_pos);
otherwise_fragment += flow_graph_builder_->RecordCoverage(other_pos);
otherwise_fragment += otherwise_statement;

TEST=CI
Change-Id: Ibfb7b81bf0b98b12e850e60f565fcc0ced521f04
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/223900
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Liam Appelbe <liama@google.com>
This commit is contained in:
Liam Appelbe 2021-12-14 21:50:44 +00:00 committed by Commit Bot
parent 784ea0bed5
commit 53e64e2dc2
2 changed files with 213 additions and 174 deletions

View file

@ -364,7 +364,7 @@ Fragment StreamingFlowGraphBuilder::BuildInitializers(
intptr_t argument_count;
instructions += BuildArguments(
&argument_names, &argument_count,
/* positional_parameter_count = */ NULL); // read arguments.
/* positional_parameter_count = */ nullptr); // read arguments.
argument_count += 1;
Class& parent_klass = GetSuperOrDie();
@ -390,7 +390,7 @@ Fragment StreamingFlowGraphBuilder::BuildInitializers(
intptr_t argument_count;
instructions += BuildArguments(
&argument_names, &argument_count,
/* positional_parameter_count = */ NULL); // read arguments.
/* positional_parameter_count = */ nullptr); // read arguments.
argument_count += 1;
const Function& target = Function::ZoneHandle(
@ -487,7 +487,7 @@ Fragment StreamingFlowGraphBuilder::TypeArgumentsHandling(
ASSERT(yield_continuations().is_empty() || !dart_function.IsGeneric());
LocalVariable* fn_type_args = parsed_function()->function_type_arguments();
ASSERT(fn_type_args != NULL && closure != NULL);
ASSERT(fn_type_args != nullptr && closure != nullptr);
if (dart_function.IsGeneric()) {
prologue += LoadLocal(fn_type_args);
@ -527,7 +527,8 @@ Fragment StreamingFlowGraphBuilder::CompleteBodyWithYieldContinuations(
// Prepend an entry corresponding to normal entry to the function.
yield_continuations().InsertAt(
0, YieldContinuation(new (Z) DropTempsInstr(0, NULL), kInvalidTryIndex));
0,
YieldContinuation(new (Z) DropTempsInstr(0, nullptr), kInvalidTryIndex));
yield_continuations()[0].entry->LinkTo(body.entry);
// Load :await_jump_var into a temporary.
@ -648,7 +649,7 @@ Fragment StreamingFlowGraphBuilder::SetupCapturedParameters(
ASSERT((function.HasOptionalParameters() &&
raw_parameter.owner() == scope) ||
(!function.HasOptionalParameters() &&
raw_parameter.owner() == NULL));
raw_parameter.owner() == nullptr));
ASSERT(!raw_parameter.is_captured());
// Copy the parameter from the stack to the context.
@ -1017,7 +1018,7 @@ FlowGraph* StreamingFlowGraphBuilder::BuildGraph() {
break;
}
UNREACHABLE();
return NULL;
return nullptr;
}
void StreamingFlowGraphBuilder::ParseKernelASTFunction() {
@ -1239,52 +1240,52 @@ Fragment StreamingFlowGraphBuilder::BuildExpression(TokenPosition* position) {
return Fragment();
}
Fragment StreamingFlowGraphBuilder::BuildStatement() {
Fragment StreamingFlowGraphBuilder::BuildStatement(TokenPosition* position) {
intptr_t offset = ReaderOffset();
Tag tag = ReadTag(); // read tag.
switch (tag) {
case kExpressionStatement:
return BuildExpressionStatement();
return BuildExpressionStatement(position);
case kBlock:
return BuildBlock();
return BuildBlock(position);
case kEmptyStatement:
return BuildEmptyStatement();
case kAssertBlock:
return BuildAssertBlock();
return BuildAssertBlock(position);
case kAssertStatement:
return BuildAssertStatement();
return BuildAssertStatement(position);
case kLabeledStatement:
return BuildLabeledStatement();
return BuildLabeledStatement(position);
case kBreakStatement:
return BuildBreakStatement();
return BuildBreakStatement(position);
case kWhileStatement:
return BuildWhileStatement();
return BuildWhileStatement(position);
case kDoStatement:
return BuildDoStatement();
return BuildDoStatement(position);
case kForStatement:
return BuildForStatement();
return BuildForStatement(position);
case kForInStatement:
return BuildForInStatement(false);
return BuildForInStatement(false, position);
case kAsyncForInStatement:
return BuildForInStatement(true);
return BuildForInStatement(true, position);
case kSwitchStatement:
return BuildSwitchStatement();
return BuildSwitchStatement(position);
case kContinueSwitchStatement:
return BuildContinueSwitchStatement();
return BuildContinueSwitchStatement(position);
case kIfStatement:
return BuildIfStatement();
return BuildIfStatement(position);
case kReturnStatement:
return BuildReturnStatement();
return BuildReturnStatement(position);
case kTryCatch:
return BuildTryCatch();
return BuildTryCatch(position);
case kTryFinally:
return BuildTryFinally();
return BuildTryFinally(position);
case kYieldStatement:
return BuildYieldStatement();
return BuildYieldStatement(position);
case kVariableDeclaration:
return BuildVariableDeclaration();
return BuildVariableDeclaration(position);
case kFunctionDeclaration:
return BuildFunctionDeclaration(offset);
return BuildFunctionDeclaration(offset, position);
default:
ReportUnexpectedTag("statement", tag);
UNREACHABLE();
@ -1294,7 +1295,7 @@ Fragment StreamingFlowGraphBuilder::BuildStatement() {
void StreamingFlowGraphBuilder::ReportUnexpectedTag(const char* variant,
Tag tag) {
if ((flow_graph_builder_ == NULL) || (parsed_function() == NULL)) {
if ((flow_graph_builder_ == nullptr) || (parsed_function() == nullptr)) {
KernelReaderHelper::ReportUnexpectedTag(variant, tag);
} else {
H.ReportError(script_, TokenPosition::kNoSource,
@ -1974,7 +1975,7 @@ Fragment StreamingFlowGraphBuilder::BuildArguments(Array* argument_names,
intptr_t* argument_count,
intptr_t* positional_count) {
intptr_t dummy;
if (argument_count == NULL) argument_count = &dummy;
if (argument_count == nullptr) argument_count = &dummy;
*argument_count = ReadUInt(); // read arguments count.
// List of types.
@ -1982,7 +1983,7 @@ Fragment StreamingFlowGraphBuilder::BuildArguments(Array* argument_names,
{
AlternativeReadingScope _(&reader_);
if (positional_count == NULL) positional_count = &dummy;
if (positional_count == nullptr) positional_count = &dummy;
*positional_count = ReadListLength(); // read length of expression list
}
return BuildArgumentsFromActualArguments(argument_names);
@ -2000,14 +2001,14 @@ Fragment StreamingFlowGraphBuilder::BuildArgumentsFromActualArguments(
// List of named.
list_length = ReadListLength(); // read list length.
if (argument_names != NULL && list_length > 0) {
if (argument_names != nullptr && list_length > 0) {
*argument_names = Array::New(list_length, Heap::kOld);
}
for (intptr_t i = 0; i < list_length; ++i) {
String& name =
H.DartSymbolObfuscate(ReadStringReference()); // read ith name index.
instructions += BuildExpression(); // read ith expression.
if (argument_names != NULL) {
if (argument_names != nullptr) {
argument_names->SetAt(i, name);
}
}
@ -2021,7 +2022,7 @@ Fragment StreamingFlowGraphBuilder::BuildInvalidExpression(
// [NoSuchMethodError]s) and only emit [InvalidExpression]s in very special
// situations (e.g. an invalid annotation).
TokenPosition pos = ReadPosition();
if (position != NULL) *position = pos;
if (position != nullptr) *position = pos;
const String& message = H.DartString(ReadStringReference());
Tag tag = ReadTag(); // read (first part of) expression.
if (tag == kSomething) {
@ -2129,7 +2130,7 @@ Fragment StreamingFlowGraphBuilder::BuildVariableGetImpl(
Fragment StreamingFlowGraphBuilder::BuildVariableSet(TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
if (p != NULL) *p = position;
if (p != nullptr) *p = position;
intptr_t variable_kernel_position = ReadUInt(); // read kernel position.
ReadUInt(); // read relative variable index.
@ -2139,7 +2140,7 @@ Fragment StreamingFlowGraphBuilder::BuildVariableSet(TokenPosition* p) {
Fragment StreamingFlowGraphBuilder::BuildVariableSet(uint8_t payload,
TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
if (p != NULL) *p = position;
if (p != nullptr) *p = position;
intptr_t variable_kernel_position = ReadUInt(); // read kernel position.
return BuildVariableSetImpl(position, variable_kernel_position);
@ -2629,7 +2630,7 @@ Fragment StreamingFlowGraphBuilder::BuildAllocateInvocationMirrorCall(
Fragment StreamingFlowGraphBuilder::BuildSuperPropertyGet(TokenPosition* p) {
const intptr_t offset = ReaderOffset() - 1; // Include the tag.
const TokenPosition position = ReadPosition(); // read position.
if (p != NULL) *p = position;
if (p != nullptr) *p = position;
const InferredTypeMetadata result_type =
inferred_type_metadata_helper_.GetInferredType(offset);
@ -2705,7 +2706,7 @@ Fragment StreamingFlowGraphBuilder::BuildSuperPropertyGet(TokenPosition* p) {
Fragment StreamingFlowGraphBuilder::BuildSuperPropertySet(TokenPosition* p) {
const TokenPosition position = ReadPosition(); // read position.
if (p != NULL) *p = position;
if (p != nullptr) *p = position;
Class& klass = GetSuperOrDie();
@ -2772,7 +2773,7 @@ Fragment StreamingFlowGraphBuilder::BuildStaticGet(TokenPosition* p) {
const intptr_t offset = ReaderOffset() - 1; // Include the tag.
TokenPosition position = ReadPosition(); // read position.
if (p != NULL) *p = position;
if (p != nullptr) *p = position;
const InferredTypeMetadata result_type =
inferred_type_metadata_helper_.GetInferredType(offset);
@ -2836,7 +2837,7 @@ Fragment StreamingFlowGraphBuilder::BuildStaticGet(TokenPosition* p) {
Fragment StreamingFlowGraphBuilder::BuildStaticSet(TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
if (p != NULL) *p = position;
if (p != nullptr) *p = position;
NameIndex target = ReadCanonicalNameReference(); // read target_reference.
ASSERT(H.IsSetter(target));
@ -2885,7 +2886,7 @@ Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p,
const bool is_invariant = (flags & kInstanceInvocationFlagInvariant) != 0;
const TokenPosition position = ReadPosition(); // read position.
if (p != NULL) *p = position;
if (p != nullptr) *p = position;
const DirectCallMetadata direct_call =
direct_call_metadata_helper_.GetDirectTargetForMethodInvocation(offset);
@ -2908,7 +2909,7 @@ Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p,
Fragment instructions;
intptr_t type_args_len = 0;
LocalVariable* type_arguments_temp = NULL;
LocalVariable* type_arguments_temp = nullptr;
{
AlternativeReadingScope alt(&reader_);
SkipExpression(); // skip receiver
@ -2950,8 +2951,8 @@ Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p,
ASSERT(type_args_len == 0);
// "==" or "!=" with null on either side.
instructions +=
BuildArguments(NULL /* named */, NULL /* arg count */,
NULL /* positional arg count */); // read arguments.
BuildArguments(nullptr /* named */, nullptr /* arg count */,
nullptr /* positional arg count */); // read arguments.
SkipInterfaceMemberNameReference(); // read interface_target_reference.
Token::Kind strict_cmp_kind =
token_kind == Token::kEQ ? Token::kEQ_STRICT : Token::kNE_STRICT;
@ -2959,11 +2960,11 @@ Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p,
StrictCompare(position, strict_cmp_kind, /*number_check = */ true);
}
LocalVariable* receiver_temp = NULL;
LocalVariable* receiver_temp = nullptr;
if (direct_call.check_receiver_for_null_) {
// Duplicate receiver for CheckNull before it is consumed by PushArgument.
receiver_temp = MakeTemporary();
if (type_arguments_temp != NULL) {
if (type_arguments_temp != nullptr) {
// If call has type arguments then push them before pushing the receiver.
// The stack will contain:
//
@ -3049,10 +3050,10 @@ Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p,
}
// Drop temporaries preserving result on the top of the stack.
ASSERT((receiver_temp != NULL) || (type_arguments_temp == NULL));
if (receiver_temp != NULL) {
const intptr_t num_temps =
(receiver_temp != NULL ? 1 : 0) + (type_arguments_temp != NULL ? 1 : 0);
ASSERT((receiver_temp != nullptr) || (type_arguments_temp == nullptr));
if (receiver_temp != nullptr) {
const intptr_t num_temps = (receiver_temp != nullptr ? 1 : 0) +
(type_arguments_temp != nullptr ? 1 : 0);
instructions += DropTempsPreserveTop(num_temps);
}
@ -3259,7 +3260,7 @@ Fragment StreamingFlowGraphBuilder::BuildSuperMethodInvocation(
TokenPosition* p) {
const intptr_t offset = ReaderOffset() - 1; // Include the tag.
const TokenPosition position = ReadPosition(); // read position.
if (p != NULL) *p = position;
if (p != nullptr) *p = position;
const InferredTypeMetadata result_type =
inferred_type_metadata_helper_.GetInferredType(offset);
@ -3383,7 +3384,7 @@ Fragment StreamingFlowGraphBuilder::BuildSuperMethodInvocation(
intptr_t argument_count;
instructions += BuildArguments(
&argument_names, &argument_count,
/* positional_argument_count = */ NULL); // read arguments.
/* positional_argument_count = */ nullptr); // read arguments.
++argument_count; // include receiver
SkipInterfaceMemberNameReference(); // interfaceTargetReference
return instructions +
@ -3397,7 +3398,7 @@ Fragment StreamingFlowGraphBuilder::BuildSuperMethodInvocation(
Fragment StreamingFlowGraphBuilder::BuildStaticInvocation(TokenPosition* p) {
const intptr_t offset = ReaderOffset() - 1; // Include the tag.
TokenPosition position = ReadPosition(); // read position.
if (p != NULL) *p = position;
if (p != nullptr) *p = position;
const InferredTypeMetadata result_type =
inferred_type_metadata_helper_.GetInferredType(offset);
@ -3425,7 +3426,7 @@ Fragment StreamingFlowGraphBuilder::BuildStaticInvocation(TokenPosition* p) {
}
Fragment instructions;
LocalVariable* instance_variable = NULL;
LocalVariable* instance_variable = nullptr;
const bool special_case_unchecked_cast =
klass.IsTopLevel() && (klass.library() == Library::InternalLibrary()) &&
@ -3483,11 +3484,11 @@ Fragment StreamingFlowGraphBuilder::BuildStaticInvocation(TokenPosition* p) {
Array& argument_names = Array::ZoneHandle(Z);
instructions +=
BuildArguments(&argument_names, NULL /* arg count */,
NULL /* positional arg count */); // read arguments.
BuildArguments(&argument_names, nullptr /* arg count */,
nullptr /* positional arg count */); // read arguments.
ASSERT(!special_case ||
target.AreValidArguments(type_args_len, argument_count, argument_names,
NULL));
nullptr));
// Special case identical(x, y) call.
// TODO(27590) consider moving this into the inliner and force inline it
@ -3514,7 +3515,7 @@ Fragment StreamingFlowGraphBuilder::BuildStaticInvocation(TokenPosition* p) {
Fragment StreamingFlowGraphBuilder::BuildConstructorInvocation(
TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
if (p != NULL) *p = position;
if (p != nullptr) *p = position;
NameIndex kernel_name =
ReadCanonicalNameReference(); // read target_reference.
@ -3555,18 +3556,18 @@ Fragment StreamingFlowGraphBuilder::BuildConstructorInvocation(
intptr_t argument_count;
instructions += BuildArguments(
&argument_names, &argument_count,
/* positional_argument_count = */ NULL); // read arguments.
/* positional_argument_count = */ nullptr); // read arguments.
const Function& target = Function::ZoneHandle(
Z, H.LookupConstructorByKernelConstructor(klass, kernel_name));
++argument_count;
instructions += StaticCall(position, target, argument_count, argument_names,
ICData::kStatic, /* result_type = */ NULL);
ICData::kStatic, /* result_type = */ nullptr);
return instructions + Drop();
}
Fragment StreamingFlowGraphBuilder::BuildNot(TokenPosition* position) {
if (position != NULL) *position = TokenPosition::kNoSource;
if (position != nullptr) *position = TokenPosition::kNoSource;
TokenPosition operand_position = TokenPosition::kNoSource;
Fragment instructions =
@ -3664,7 +3665,7 @@ Fragment StreamingFlowGraphBuilder::TranslateLogicalExpressionForValue(
Fragment StreamingFlowGraphBuilder::BuildLogicalExpression(
TokenPosition* position) {
if (position != NULL) *position = TokenPosition::kNoSource;
if (position != nullptr) *position = TokenPosition::kNoSource;
TestFragment exits;
exits.true_successor_addresses = new TestFragment::SuccessorAddressArray(2);
@ -3701,7 +3702,7 @@ Fragment StreamingFlowGraphBuilder::BuildLogicalExpression(
Fragment StreamingFlowGraphBuilder::BuildConditionalExpression(
TokenPosition* position) {
if (position != NULL) *position = TokenPosition::kNoSource;
if (position != nullptr) *position = TokenPosition::kNoSource;
TestFragment condition = TranslateConditionForControl(); // read condition.
@ -3817,7 +3818,7 @@ Fragment StreamingFlowGraphBuilder::BuildStringConcatenation(TokenPosition* p) {
Fragment StreamingFlowGraphBuilder::BuildIsExpression(TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
if (p != NULL) *p = position;
if (p != nullptr) *p = position;
if (translation_helper_.info().kernel_binary_version() >= 38) {
// We do not use the library mode for the type test, which is indicated by
@ -3870,7 +3871,7 @@ Fragment StreamingFlowGraphBuilder::BuildIsExpression(TokenPosition* p) {
Fragment StreamingFlowGraphBuilder::BuildAsExpression(TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
if (p != NULL) *p = position;
if (p != nullptr) *p = position;
const uint8_t flags = ReadFlags(); // read flags.
const bool is_type_error = (flags & kAsExpressionFlagTypeError) != 0;
@ -3894,7 +3895,7 @@ Fragment StreamingFlowGraphBuilder::BuildAsExpression(TokenPosition* p) {
}
Fragment StreamingFlowGraphBuilder::BuildTypeLiteral(TokenPosition* position) {
if (position != NULL) *position = TokenPosition::kNoSource;
if (position != nullptr) *position = TokenPosition::kNoSource;
const AbstractType& type = T.BuildType(); // read type.
Fragment instructions;
@ -3918,14 +3919,14 @@ Fragment StreamingFlowGraphBuilder::BuildTypeLiteral(TokenPosition* position) {
Fragment StreamingFlowGraphBuilder::BuildThisExpression(
TokenPosition* position) {
if (position != NULL) *position = TokenPosition::kNoSource;
if (position != nullptr) *position = TokenPosition::kNoSource;
return LoadLocal(parsed_function()->receiver_var());
}
Fragment StreamingFlowGraphBuilder::BuildRethrow(TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
if (p != NULL) *p = position;
if (p != nullptr) *p = position;
Fragment instructions = DebugStepCheck(position);
instructions += LoadLocal(catch_block()->exception_var());
@ -3937,7 +3938,7 @@ Fragment StreamingFlowGraphBuilder::BuildRethrow(TokenPosition* p) {
Fragment StreamingFlowGraphBuilder::BuildThrow(TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
if (p != NULL) *p = position;
if (p != nullptr) *p = position;
Fragment instructions;
@ -3954,7 +3955,7 @@ Fragment StreamingFlowGraphBuilder::BuildThrow(TokenPosition* p) {
Fragment StreamingFlowGraphBuilder::BuildListLiteral(TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
if (p != NULL) *p = position;
if (p != nullptr) *p = position;
const TypeArguments& type_arguments = T.BuildTypeArguments(1); // read type.
intptr_t length = ReadListLength(); // read list length.
@ -4000,7 +4001,7 @@ Fragment StreamingFlowGraphBuilder::BuildListLiteral(TokenPosition* p) {
Fragment StreamingFlowGraphBuilder::BuildMapLiteral(TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
if (p != NULL) *p = position;
if (p != nullptr) *p = position;
const TypeArguments& type_arguments =
T.BuildTypeArguments(2); // read key_type and value_type.
@ -4057,8 +4058,8 @@ Fragment StreamingFlowGraphBuilder::BuildFunctionExpression() {
Fragment StreamingFlowGraphBuilder::BuildLet(TokenPosition* p) {
const TokenPosition position = ReadPosition(); // read position.
if (p != nullptr) *p = position;
Fragment instructions = BuildVariableDeclaration(); // read variable.
instructions += BuildExpression(); // read body.
Fragment instructions = BuildVariableDeclaration(nullptr); // read variable.
instructions += BuildExpression(); // read body.
return instructions;
}
@ -4082,7 +4083,7 @@ Fragment StreamingFlowGraphBuilder::BuildBlockExpression() {
Fragment StreamingFlowGraphBuilder::BuildBigIntLiteral(
TokenPosition* position) {
if (position != NULL) *position = TokenPosition::kNoSource;
if (position != nullptr) *position = TokenPosition::kNoSource;
const String& value =
H.DartString(ReadStringReference()); // read index into string table.
@ -4097,7 +4098,7 @@ Fragment StreamingFlowGraphBuilder::BuildBigIntLiteral(
Fragment StreamingFlowGraphBuilder::BuildStringLiteral(
TokenPosition* position) {
if (position != NULL) *position = TokenPosition::kNoSource;
if (position != nullptr) *position = TokenPosition::kNoSource;
return Constant(H.DartSymbolPlain(
ReadStringReference())); // read index into string table.
@ -4105,7 +4106,7 @@ Fragment StreamingFlowGraphBuilder::BuildStringLiteral(
Fragment StreamingFlowGraphBuilder::BuildIntLiteral(uint8_t payload,
TokenPosition* position) {
if (position != NULL) *position = TokenPosition::kNoSource;
if (position != nullptr) *position = TokenPosition::kNoSource;
int64_t value = static_cast<int32_t>(payload) - SpecializedIntLiteralBias;
return IntConstant(value);
@ -4113,7 +4114,7 @@ Fragment StreamingFlowGraphBuilder::BuildIntLiteral(uint8_t payload,
Fragment StreamingFlowGraphBuilder::BuildIntLiteral(bool is_negative,
TokenPosition* position) {
if (position != NULL) *position = TokenPosition::kNoSource;
if (position != nullptr) *position = TokenPosition::kNoSource;
int64_t value = is_negative ? -static_cast<int64_t>(ReadUInt())
: ReadUInt(); // read value.
@ -4122,7 +4123,7 @@ Fragment StreamingFlowGraphBuilder::BuildIntLiteral(bool is_negative,
Fragment StreamingFlowGraphBuilder::BuildDoubleLiteral(
TokenPosition* position) {
if (position != NULL) *position = TokenPosition::kNoSource;
if (position != nullptr) *position = TokenPosition::kNoSource;
Double& constant = Double::ZoneHandle(
Z, Double::NewCanonical(ReadDouble())); // read double.
@ -4131,20 +4132,20 @@ Fragment StreamingFlowGraphBuilder::BuildDoubleLiteral(
Fragment StreamingFlowGraphBuilder::BuildBoolLiteral(bool value,
TokenPosition* position) {
if (position != NULL) *position = TokenPosition::kNoSource;
if (position != nullptr) *position = TokenPosition::kNoSource;
return Constant(Bool::Get(value));
}
Fragment StreamingFlowGraphBuilder::BuildNullLiteral(TokenPosition* position) {
if (position != NULL) *position = TokenPosition::kNoSource;
if (position != nullptr) *position = TokenPosition::kNoSource;
return Constant(Instance::ZoneHandle(Z, Instance::null()));
}
Fragment StreamingFlowGraphBuilder::BuildFutureNullValue(
TokenPosition* position) {
if (position != NULL) *position = TokenPosition::kNoSource;
if (position != nullptr) *position = TokenPosition::kNoSource;
const Class& future = Class::Handle(Z, IG->object_store()->future_class());
ASSERT(!future.IsNull());
const auto& error = future.EnsureIsFinalized(thread());
@ -4177,7 +4178,7 @@ Fragment StreamingFlowGraphBuilder::BuildConstantExpression(
Fragment StreamingFlowGraphBuilder::BuildPartialTearoffInstantiation(
TokenPosition* position) {
if (position != NULL) *position = TokenPosition::kNoSource;
if (position != nullptr) *position = TokenPosition::kNoSource;
// Create a copy of the closure.
@ -4264,20 +4265,24 @@ Fragment StreamingFlowGraphBuilder::BuildLibraryPrefixAction(
return instructions;
}
Fragment StreamingFlowGraphBuilder::BuildExpressionStatement() {
Fragment instructions = BuildExpression(); // read expression.
Fragment StreamingFlowGraphBuilder::BuildExpressionStatement(
TokenPosition* position) {
Fragment instructions = BuildExpression(position); // read expression.
instructions += Drop();
return instructions;
}
Fragment StreamingFlowGraphBuilder::BuildBlock() {
Fragment StreamingFlowGraphBuilder::BuildBlock(TokenPosition* position) {
intptr_t offset = ReaderOffset() - 1; // Include the tag.
Fragment instructions;
instructions += EnterScope(offset);
ReadPosition(); // read file offset.
const TokenPosition pos = ReadPosition(); // read file offset.
if (position != nullptr) *position = pos;
ReadPosition(); // read file end offset.
intptr_t list_length = ReadListLength(); // read number of statements.
for (intptr_t i = 0; i < list_length; ++i) {
if (instructions.is_open()) {
@ -4295,7 +4300,7 @@ Fragment StreamingFlowGraphBuilder::BuildEmptyStatement() {
return Fragment();
}
Fragment StreamingFlowGraphBuilder::BuildAssertBlock() {
Fragment StreamingFlowGraphBuilder::BuildAssertBlock(TokenPosition* position) {
if (!IG->asserts()) {
SkipStatementList();
return Fragment();
@ -4309,7 +4314,8 @@ Fragment StreamingFlowGraphBuilder::BuildAssertBlock() {
intptr_t list_length = ReadListLength(); // read number of statements.
for (intptr_t i = 0; i < list_length; ++i) {
if (instructions.is_open()) {
instructions += BuildStatement(); // read ith statement.
// read ith statement.
instructions += BuildStatement(i == 0 ? position : nullptr);
} else {
SkipStatement(); // read ith statement.
}
@ -4319,7 +4325,8 @@ Fragment StreamingFlowGraphBuilder::BuildAssertBlock() {
return instructions;
}
Fragment StreamingFlowGraphBuilder::BuildAssertStatement() {
Fragment StreamingFlowGraphBuilder::BuildAssertStatement(
TokenPosition* position) {
if (!IG->asserts()) {
SetOffset(ReaderOffset() - 1); // Include the tag.
SkipStatement(); // read this statement.
@ -4337,7 +4344,7 @@ Fragment StreamingFlowGraphBuilder::BuildAssertStatement() {
//
// The call to `_AssertionError._evaluateAssertion()` will take care of both
// and returns a boolean.
instructions += BuildExpression(); // read condition.
instructions += BuildExpression(position); // read condition.
const TokenPosition condition_start_offset =
ReadPosition(); // read condition start offset.
@ -4382,7 +4389,8 @@ Fragment StreamingFlowGraphBuilder::BuildAssertStatement() {
return Fragment(instructions.entry, then);
}
Fragment StreamingFlowGraphBuilder::BuildLabeledStatement() {
Fragment StreamingFlowGraphBuilder::BuildLabeledStatement(
TokenPosition* position) {
// There can be serveral cases:
//
// * the body contains a break
@ -4395,7 +4403,7 @@ Fragment StreamingFlowGraphBuilder::BuildLabeledStatement() {
// traversed.
BreakableBlock block(flow_graph_builder_);
Fragment instructions = BuildStatement(); // read body.
Fragment instructions = BuildStatement(position); // read body.
if (block.HadJumper()) {
if (instructions.is_open()) {
instructions += Goto(block.destination());
@ -4406,11 +4414,14 @@ Fragment StreamingFlowGraphBuilder::BuildLabeledStatement() {
}
}
Fragment StreamingFlowGraphBuilder::BuildBreakStatement() {
TokenPosition position = ReadPosition(); // read position.
Fragment StreamingFlowGraphBuilder::BuildBreakStatement(
TokenPosition* position) {
const TokenPosition pos = ReadPosition(); // read position.
if (position != nullptr) *position = pos;
intptr_t target_index = ReadUInt(); // read target index.
TryFinallyBlock* outer_finally = NULL;
TryFinallyBlock* outer_finally = nullptr;
intptr_t target_context_depth = -1;
JoinEntryInstr* destination = breakable_block()->BreakDestination(
target_index, &outer_finally, &target_context_depth);
@ -4418,8 +4429,8 @@ Fragment StreamingFlowGraphBuilder::BuildBreakStatement() {
Fragment instructions;
// Break statement should pause before manipulation of context, which
// will possibly cause debugger having incorrect context object.
if (NeedsDebugStepCheck(parsed_function()->function(), position)) {
instructions += DebugStepCheck(position);
if (NeedsDebugStepCheck(parsed_function()->function(), pos)) {
instructions += DebugStepCheck(pos);
}
instructions +=
TranslateFinallyFinalizers(outer_finally, target_context_depth);
@ -4429,10 +4440,13 @@ Fragment StreamingFlowGraphBuilder::BuildBreakStatement() {
return instructions;
}
Fragment StreamingFlowGraphBuilder::BuildWhileStatement() {
Fragment StreamingFlowGraphBuilder::BuildWhileStatement(
TokenPosition* position) {
ASSERT(block_expression_depth() == 0); // no while in block-expr
loop_depth_inc();
const TokenPosition position = ReadPosition(); // read position.
const TokenPosition pos = ReadPosition(); // read position.
if (position != nullptr) *position = pos;
TestFragment condition = TranslateConditionForControl(); // read condition.
const Fragment body = BuildStatement(); // read body
@ -4446,7 +4460,7 @@ Fragment StreamingFlowGraphBuilder::BuildWhileStatement() {
Fragment loop(join);
ASSERT(B->GetStackDepth() == 0);
loop += CheckStackOverflow(position);
loop += CheckStackOverflow(pos);
loop.current->LinkTo(condition.entry);
entry = Goto(join).entry;
@ -4458,11 +4472,13 @@ Fragment StreamingFlowGraphBuilder::BuildWhileStatement() {
return Fragment(entry, condition.CreateFalseSuccessor(flow_graph_builder_));
}
Fragment StreamingFlowGraphBuilder::BuildDoStatement() {
Fragment StreamingFlowGraphBuilder::BuildDoStatement(TokenPosition* position) {
ASSERT(block_expression_depth() == 0); // no do-while in block-expr
loop_depth_inc();
const TokenPosition position = ReadPosition(); // read position.
Fragment body = BuildStatement(); // read body.
const TokenPosition pos = ReadPosition(); // read position.
if (position != nullptr) *position = pos;
Fragment body = BuildStatement(); // read body.
if (body.is_closed()) {
SkipExpression(); // read condition.
@ -4475,7 +4491,7 @@ Fragment StreamingFlowGraphBuilder::BuildDoStatement() {
JoinEntryInstr* join = BuildJoinEntry();
Fragment loop(join);
ASSERT(B->GetStackDepth() == 0);
loop += CheckStackOverflow(position);
loop += CheckStackOverflow(pos);
loop += body;
loop <<= condition.entry;
@ -4487,10 +4503,11 @@ Fragment StreamingFlowGraphBuilder::BuildDoStatement() {
condition.CreateFalseSuccessor(flow_graph_builder_));
}
Fragment StreamingFlowGraphBuilder::BuildForStatement() {
Fragment StreamingFlowGraphBuilder::BuildForStatement(TokenPosition* position) {
intptr_t offset = ReaderOffset() - 1; // Include the tag.
const TokenPosition position = ReadPosition(); // read position.
const TokenPosition pos = ReadPosition(); // read position.
if (position != nullptr) *position = pos;
Fragment declarations;
@ -4501,7 +4518,7 @@ Fragment StreamingFlowGraphBuilder::BuildForStatement() {
intptr_t list_length = ReadListLength(); // read number of variables.
for (intptr_t i = 0; i < list_length; ++i) {
declarations += BuildVariableDeclaration(); // read ith variable.
declarations += BuildVariableDeclaration(nullptr); // read ith variable.
}
Tag tag = ReadTag(); // Read first part of condition.
@ -4543,7 +4560,7 @@ Fragment StreamingFlowGraphBuilder::BuildForStatement() {
body += Goto(join);
Fragment loop(join);
loop += CheckStackOverflow(position); // may have non-empty stack
loop += CheckStackOverflow(pos); // may have non-empty stack
if (condition.entry != nullptr) {
loop <<= condition.entry;
} else {
@ -4566,10 +4583,14 @@ Fragment StreamingFlowGraphBuilder::BuildForStatement() {
return loop;
}
Fragment StreamingFlowGraphBuilder::BuildForInStatement(bool async) {
Fragment StreamingFlowGraphBuilder::BuildForInStatement(
bool async,
TokenPosition* position) {
intptr_t offset = ReaderOffset() - 1; // Include the tag.
const TokenPosition position = ReadPosition(); // read position.
const TokenPosition pos = ReadPosition(); // read position.
if (position != nullptr) *position = pos;
TokenPosition body_position = ReadPosition(); // read body position.
intptr_t variable_kernel_position = ReaderOffset() + data_program_offset_;
SkipVariableDeclaration(); // read variable.
@ -4613,7 +4634,7 @@ Fragment StreamingFlowGraphBuilder::BuildForInStatement(bool async) {
body += Goto(join);
Fragment loop(join);
loop += CheckStackOverflow(position); // may have non-empty stack
loop += CheckStackOverflow(pos); // may have non-empty stack
loop += condition;
} else {
instructions += condition;
@ -4624,8 +4645,11 @@ Fragment StreamingFlowGraphBuilder::BuildForInStatement(bool async) {
return Fragment(instructions.entry, loop_exit);
}
Fragment StreamingFlowGraphBuilder::BuildSwitchStatement() {
ReadPosition(); // read position.
Fragment StreamingFlowGraphBuilder::BuildSwitchStatement(
TokenPosition* position) {
const TokenPosition pos = ReadPosition(); // read position.
if (position != nullptr) *position = pos;
// We need the number of cases. So start by getting that, then go back.
intptr_t offset = ReaderOffset();
SkipExpression(); // temporarily skip condition
@ -4663,7 +4687,7 @@ Fragment StreamingFlowGraphBuilder::BuildSwitchStatement() {
Fragment& body_fragment = body_fragments[i] =
BuildStatement(); // read body.
if (body_fragment.entry == NULL) {
if (body_fragment.entry == nullptr) {
// Make a NOP in order to ensure linking works properly.
body_fragment = NullConstant();
body_fragment += Drop();
@ -4750,7 +4774,7 @@ Fragment StreamingFlowGraphBuilder::BuildSwitchStatement() {
current_instructions += body_fragments[i];
}
} else {
JoinEntryInstr* body_join = NULL;
JoinEntryInstr* body_join = nullptr;
if (block.HadJumper(i)) {
body_join = block.DestinationDirect(i);
body_fragments[i] = Fragment(body_join) + body_fragments[i];
@ -4760,19 +4784,19 @@ Fragment StreamingFlowGraphBuilder::BuildSwitchStatement() {
TargetEntryInstr* then;
TargetEntryInstr* otherwise;
TokenPosition position = ReadPosition(); // read jth position.
const TokenPosition pos = ReadPosition(); // read jth position.
current_instructions += Constant(
Instance::ZoneHandle(Z, constant_reader_.ReadConstantExpression()));
current_instructions += LoadLocal(scopes()->switch_variable);
current_instructions +=
InstanceCall(position, Symbols::EqualOperator(), Token::kEQ,
InstanceCall(pos, Symbols::EqualOperator(), Token::kEQ,
/*argument_count=*/2,
/*checked_argument_count=*/2);
current_instructions += BranchIfTrue(&then, &otherwise, false);
Fragment then_fragment(then);
if (body_join != NULL) {
if (body_join != nullptr) {
// There are several branches to the body, so we will make a goto to
// the join block (the real body has already been prepended with a
// join instruction).
@ -4816,11 +4840,14 @@ Fragment StreamingFlowGraphBuilder::BuildSwitchStatement() {
return Fragment(head_instructions.entry, current_instructions.current);
}
Fragment StreamingFlowGraphBuilder::BuildContinueSwitchStatement() {
TokenPosition position = ReadPosition(); // read position.
Fragment StreamingFlowGraphBuilder::BuildContinueSwitchStatement(
TokenPosition* position) {
const TokenPosition pos = ReadPosition(); // read position.
if (position != nullptr) *position = pos;
intptr_t target_index = ReadUInt(); // read target index.
TryFinallyBlock* outer_finally = NULL;
TryFinallyBlock* outer_finally = nullptr;
intptr_t target_context_depth = -1;
JoinEntryInstr* entry = switch_block()->Destination(
target_index, &outer_finally, &target_context_depth);
@ -4829,16 +4856,17 @@ Fragment StreamingFlowGraphBuilder::BuildContinueSwitchStatement() {
instructions +=
TranslateFinallyFinalizers(outer_finally, target_context_depth);
if (instructions.is_open()) {
if (NeedsDebugStepCheck(parsed_function()->function(), position)) {
instructions += DebugStepCheck(position);
if (NeedsDebugStepCheck(parsed_function()->function(), pos)) {
instructions += DebugStepCheck(pos);
}
instructions += Goto(entry);
}
return instructions;
}
Fragment StreamingFlowGraphBuilder::BuildIfStatement() {
ReadPosition(); // read position.
Fragment StreamingFlowGraphBuilder::BuildIfStatement(TokenPosition* position) {
const TokenPosition pos = ReadPosition(); // read position.
if (position != nullptr) *position = pos;
TestFragment condition = TranslateConditionForControl();
@ -4865,11 +4893,14 @@ Fragment StreamingFlowGraphBuilder::BuildIfStatement() {
}
}
Fragment StreamingFlowGraphBuilder::BuildReturnStatement() {
TokenPosition position = ReadPosition(); // read position.
Tag tag = ReadTag(); // read first part of expression.
Fragment StreamingFlowGraphBuilder::BuildReturnStatement(
TokenPosition* position) {
const TokenPosition pos = ReadPosition(); // read position.
if (position != nullptr) *position = pos;
bool inside_try_finally = try_finally_block() != NULL;
Tag tag = ReadTag(); // read first part of expression.
bool inside_try_finally = try_finally_block() != nullptr;
Fragment instructions = tag == kNothing
? NullConstant()
@ -4881,10 +4912,10 @@ Fragment StreamingFlowGraphBuilder::BuildReturnStatement() {
scopes()->finally_return_variable;
ASSERT(finally_return_variable != nullptr);
const Function& function = parsed_function()->function();
if (NeedsDebugStepCheck(function, position)) {
instructions += DebugStepCheck(position);
if (NeedsDebugStepCheck(function, pos)) {
instructions += DebugStepCheck(pos);
}
instructions += StoreLocal(position, finally_return_variable);
instructions += StoreLocal(pos, finally_return_variable);
instructions += Drop();
const intptr_t target_context_depth =
finally_return_variable->is_captured()
@ -4901,7 +4932,7 @@ Fragment StreamingFlowGraphBuilder::BuildReturnStatement() {
B->context_depth_ = saved_context_depth;
}
} else {
instructions += Return(position);
instructions += Return(pos);
}
} else {
Pop();
@ -4910,7 +4941,7 @@ Fragment StreamingFlowGraphBuilder::BuildReturnStatement() {
return instructions;
}
Fragment StreamingFlowGraphBuilder::BuildTryCatch() {
Fragment StreamingFlowGraphBuilder::BuildTryCatch(TokenPosition* position) {
ASSERT(block_expression_depth() == 0); // no try-catch in block-expr
InlineBailout("kernel::FlowgraphBuilder::VisitTryCatch");
@ -4922,7 +4953,7 @@ Fragment StreamingFlowGraphBuilder::BuildTryCatch() {
try_depth_inc();
{
TryCatchBlock block(flow_graph_builder_, try_handler_index);
try_body += BuildStatement(); // read body.
try_body += BuildStatement(position); // read body.
try_body += Goto(after_try);
}
try_depth_dec();
@ -4945,7 +4976,7 @@ Fragment StreamingFlowGraphBuilder::BuildTryCatch() {
// Fill in the body of the catch.
for (intptr_t i = 0; i < catch_count; ++i) {
intptr_t catch_offset = ReaderOffset(); // Catch has no tag.
TokenPosition position = ReadPosition(); // read position.
TokenPosition pos = ReadPosition(); // read position.
const AbstractType& type_guard = T.BuildType(); // read guard.
handler_types.SetAt(i, type_guard);
@ -5002,9 +5033,9 @@ Fragment StreamingFlowGraphBuilder::BuildTryCatch() {
catch_body += Constant(type_guard);
catch_body += InstanceCall(
position, Library::PrivateCoreLibName(Symbols::_instanceOf()),
Token::kIS, 4);
catch_body +=
InstanceCall(pos, Library::PrivateCoreLibName(Symbols::_instanceOf()),
Token::kIS, 4);
TargetEntryInstr* catch_entry;
TargetEntryInstr* next_catch_entry;
@ -5031,7 +5062,7 @@ Fragment StreamingFlowGraphBuilder::BuildTryCatch() {
return Fragment(try_body.entry, after_try);
}
Fragment StreamingFlowGraphBuilder::BuildTryFinally() {
Fragment StreamingFlowGraphBuilder::BuildTryFinally(TokenPosition* position) {
ASSERT(block_expression_depth() == 0); // no try-finally in block-expr
// Note on streaming:
// We only stream this TryFinally if we can stream everything inside it,
@ -5076,7 +5107,7 @@ Fragment StreamingFlowGraphBuilder::BuildTryFinally() {
{
TryFinallyBlock tfb(flow_graph_builder_, finalizer_offset);
TryCatchBlock tcb(flow_graph_builder_, try_handler_index);
try_body += BuildStatement(); // read body.
try_body += BuildStatement(position); // read body.
}
try_depth_dec();
@ -5115,10 +5146,12 @@ Fragment StreamingFlowGraphBuilder::BuildTryFinally() {
return Fragment(try_body.entry, after_try);
}
Fragment StreamingFlowGraphBuilder::BuildYieldStatement() {
TokenPosition position = ReadPosition(); // read position.
uint8_t flags = ReadByte(); // read flags.
Fragment StreamingFlowGraphBuilder::BuildYieldStatement(
TokenPosition* position) {
const TokenPosition pos = ReadPosition(); // read position.
if (position != nullptr) *position = pos;
uint8_t flags = ReadByte(); // read flags.
ASSERT(flags == kNativeYieldFlags); // Must have been desugared.
// Setup yield/continue point:
@ -5145,11 +5178,11 @@ Fragment StreamingFlowGraphBuilder::BuildYieldStatement() {
StoreLocal(TokenPosition::kNoSource, scopes()->yield_context_variable);
instructions += Drop();
instructions += BuildExpression(); // read expression.
instructions += Return(position, new_yield_pos);
instructions += Return(pos, new_yield_pos);
// Note: DropTempsInstr serves as an anchor instruction. It will not
// be linked into the resulting graph.
DropTempsInstr* anchor = new (Z) DropTempsInstr(0, NULL);
DropTempsInstr* anchor = new (Z) DropTempsInstr(0, nullptr);
yield_continuations().Add(YieldContinuation(anchor, CurrentTryIndex()));
Fragment continuation(instructions.entry, anchor);
@ -5189,7 +5222,7 @@ Fragment StreamingFlowGraphBuilder::BuildYieldStatement() {
rethrow += LoadLocal(exception_var);
rethrow += LoadLocal(stack_trace_var);
rethrow += RethrowException(position, kInvalidTryIndex);
rethrow += RethrowException(pos, kInvalidTryIndex);
Drop();
// Set current to the end of the no_error branch.
@ -5199,7 +5232,8 @@ Fragment StreamingFlowGraphBuilder::BuildYieldStatement() {
return continuation;
}
Fragment StreamingFlowGraphBuilder::BuildVariableDeclaration() {
Fragment StreamingFlowGraphBuilder::BuildVariableDeclaration(
TokenPosition* position) {
intptr_t kernel_position_no_tag = ReaderOffset() + data_program_offset_;
LocalVariable* variable = LookupVariable(kernel_position_no_tag);
@ -5233,6 +5267,7 @@ Fragment StreamingFlowGraphBuilder::BuildVariableDeclaration() {
const TokenPosition debug_position = helper.equals_position_.IsReal()
? helper.equals_position_
: helper.position_;
if (position != nullptr) *position = helper.position_;
if (NeedsDebugStepCheck(stack(), debug_position)) {
instructions = DebugStepCheck(debug_position) + instructions;
}
@ -5241,8 +5276,12 @@ Fragment StreamingFlowGraphBuilder::BuildVariableDeclaration() {
return instructions;
}
Fragment StreamingFlowGraphBuilder::BuildFunctionDeclaration(intptr_t offset) {
TokenPosition position = ReadPosition();
Fragment StreamingFlowGraphBuilder::BuildFunctionDeclaration(
intptr_t offset,
TokenPosition* position) {
const TokenPosition pos = ReadPosition();
if (position != nullptr) *position = pos;
const intptr_t variable_offset = ReaderOffset() + data_program_offset_;
// Read variable declaration.
@ -5271,10 +5310,10 @@ Fragment StreamingFlowGraphBuilder::BuildFunctionDeclaration(intptr_t offset) {
helper.ReadUntilExcluding(VariableDeclarationHelper::kEnd);
Fragment instructions = DebugStepCheck(position);
instructions += BuildFunctionNode(position, helper.name_index_,
Fragment instructions = DebugStepCheck(pos);
instructions += BuildFunctionNode(pos, helper.name_index_,
has_valid_annotation, has_pragma, offset);
instructions += StoreLocal(position, LookupVariable(variable_offset));
instructions += StoreLocal(pos, LookupVariable(variable_offset));
instructions += Drop();
return instructions;
}

View file

@ -68,8 +68,8 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper {
Fragment BuildInitializers(const Class& parent_class);
FlowGraph* BuildGraphOfFunction(bool constructor);
Fragment BuildExpression(TokenPosition* position = NULL);
Fragment BuildStatement();
Fragment BuildExpression(TokenPosition* position = nullptr);
Fragment BuildStatement(TokenPosition* position = nullptr);
// Kernel offset:
// start of function expression -> end of function body statement
@ -178,7 +178,7 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper {
intptr_t argument_count,
const Array& argument_names,
ICData::RebindRule rebind_rule,
const InferredTypeMetadata* result_type = NULL,
const InferredTypeMetadata* result_type = nullptr,
intptr_t type_args_len = 0,
bool use_unchecked_entry = false);
Fragment InstanceCall(TokenPosition position,
@ -333,26 +333,26 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper {
Fragment BuildLibraryPrefixAction(TokenPosition* position,
const String& selector);
Fragment BuildExpressionStatement();
Fragment BuildBlock();
Fragment BuildExpressionStatement(TokenPosition* position);
Fragment BuildBlock(TokenPosition* position);
Fragment BuildEmptyStatement();
Fragment BuildAssertBlock();
Fragment BuildAssertStatement();
Fragment BuildLabeledStatement();
Fragment BuildBreakStatement();
Fragment BuildWhileStatement();
Fragment BuildDoStatement();
Fragment BuildForStatement();
Fragment BuildForInStatement(bool async);
Fragment BuildSwitchStatement();
Fragment BuildContinueSwitchStatement();
Fragment BuildIfStatement();
Fragment BuildReturnStatement();
Fragment BuildTryCatch();
Fragment BuildTryFinally();
Fragment BuildYieldStatement();
Fragment BuildVariableDeclaration();
Fragment BuildFunctionDeclaration(intptr_t offset);
Fragment BuildAssertBlock(TokenPosition* position);
Fragment BuildAssertStatement(TokenPosition* position);
Fragment BuildLabeledStatement(TokenPosition* position);
Fragment BuildBreakStatement(TokenPosition* position);
Fragment BuildWhileStatement(TokenPosition* position);
Fragment BuildDoStatement(TokenPosition* position);
Fragment BuildForStatement(TokenPosition* position);
Fragment BuildForInStatement(bool async, TokenPosition* position);
Fragment BuildSwitchStatement(TokenPosition* position);
Fragment BuildContinueSwitchStatement(TokenPosition* position);
Fragment BuildIfStatement(TokenPosition* position);
Fragment BuildReturnStatement(TokenPosition* position);
Fragment BuildTryCatch(TokenPosition* position);
Fragment BuildTryFinally(TokenPosition* position);
Fragment BuildYieldStatement(TokenPosition* position);
Fragment BuildVariableDeclaration(TokenPosition* position);
Fragment BuildFunctionDeclaration(intptr_t offset, TokenPosition* position);
Fragment BuildFunctionNode(TokenPosition parent_position,
StringIndex name_index,
bool has_valid_annotation,