| Index: runtime/vm/kernel_binary_flowgraph.cc
|
| diff --git a/runtime/vm/kernel_binary_flowgraph.cc b/runtime/vm/kernel_binary_flowgraph.cc
|
| index 6ce365fbffe6aa74d2abd7a29cdefbc6cadb2b57..13b5b1b7a20ee12445402b49941918b6b15e4c0b 100644
|
| --- a/runtime/vm/kernel_binary_flowgraph.cc
|
| +++ b/runtime/vm/kernel_binary_flowgraph.cc
|
| @@ -942,7 +942,7 @@ void StreamingScopeBuilder::VisitExpression() {
|
| builder_->ReadPosition(); // read position.
|
| VisitExpression(); // read receiver.
|
| builder_->SkipName(); // read name.
|
| - // Read unused "interface_target_reference".
|
| + // read interface_target_reference.
|
| builder_->SkipCanonicalNameReference();
|
| return;
|
| case kPropertySet:
|
| @@ -950,7 +950,7 @@ void StreamingScopeBuilder::VisitExpression() {
|
| VisitExpression(); // read receiver.
|
| builder_->SkipName(); // read name.
|
| VisitExpression(); // read value.
|
| - // read unused "interface_target_reference".
|
| + // read interface_target_reference.
|
| builder_->SkipCanonicalNameReference();
|
| return;
|
| case kDirectPropertyGet:
|
| @@ -978,7 +978,7 @@ void StreamingScopeBuilder::VisitExpression() {
|
| VisitExpression(); // read receiver.
|
| builder_->SkipName(); // read name.
|
| VisitArguments(); // read arguments.
|
| - // read unused "interface_target_reference".
|
| + // read interface_target_reference.
|
| builder_->SkipCanonicalNameReference();
|
| return;
|
| case kDirectMethodInvocation:
|
| @@ -2404,8 +2404,7 @@ void StreamingConstantEvaluator::EvaluatePropertyGet() {
|
| intptr_t expression_offset = builder_->ReaderOffset();
|
| builder_->SkipExpression(); // read receiver.
|
| StringIndex name = builder_->ReadNameAsStringIndex(); // read name.
|
| - // Read unused "interface_target_reference".
|
| - builder_->SkipCanonicalNameReference();
|
| + builder_->SkipCanonicalNameReference(); // read interface_target_reference.
|
|
|
| if (H.StringEquals(name, "length")) {
|
| EvaluateExpression(expression_offset);
|
| @@ -2491,7 +2490,7 @@ void StreamingConstantEvaluator::EvaluateMethodInvocation() {
|
| result_ ^= result.raw();
|
| result_ = H.Canonicalize(result_);
|
|
|
| - builder_->SkipCanonicalNameReference(); // read "interface_target_reference"
|
| + builder_->SkipCanonicalNameReference(); // read interface_target_reference.
|
| }
|
|
|
| void StreamingConstantEvaluator::EvaluateStaticInvocation() {
|
| @@ -4320,16 +4319,14 @@ void StreamingFlowGraphBuilder::SkipExpression() {
|
| ReadPosition(); // read position.
|
| SkipExpression(); // read receiver.
|
| SkipName(); // read name.
|
| - // Read unused "interface_target_reference".
|
| - SkipCanonicalNameReference();
|
| + SkipCanonicalNameReference(); // read interface_target_reference.
|
| return;
|
| case kPropertySet:
|
| ReadPosition(); // read position.
|
| SkipExpression(); // read receiver.
|
| SkipName(); // read name.
|
| SkipExpression(); // read value.
|
| - // read unused "interface_target_reference".
|
| - SkipCanonicalNameReference();
|
| + SkipCanonicalNameReference(); // read interface_target_reference.
|
| return;
|
| case kDirectPropertyGet:
|
| ReadPosition(); // read position.
|
| @@ -4356,8 +4353,7 @@ void StreamingFlowGraphBuilder::SkipExpression() {
|
| SkipExpression(); // read receiver.
|
| SkipName(); // read name.
|
| SkipArguments(); // read arguments.
|
| - // read unused "interface_target_reference".
|
| - SkipCanonicalNameReference();
|
| + SkipCanonicalNameReference(); // read interface_target_reference.
|
| return;
|
| case kDirectMethodInvocation:
|
| SkipExpression(); // read receiver.
|
| @@ -4964,8 +4960,24 @@ Fragment StreamingFlowGraphBuilder::InstanceCall(
|
| Token::Kind kind,
|
| intptr_t argument_count,
|
| intptr_t checked_argument_count) {
|
| - return flow_graph_builder_->InstanceCall(position, name, kind, argument_count,
|
| - checked_argument_count);
|
| + const intptr_t kTypeArgsLen = 0;
|
| + return flow_graph_builder_->InstanceCall(
|
| + position, name, kind, kTypeArgsLen, argument_count, Array::null_array(),
|
| + checked_argument_count, Function::null_function());
|
| +}
|
| +
|
| +Fragment StreamingFlowGraphBuilder::InstanceCall(
|
| + TokenPosition position,
|
| + const dart::String& name,
|
| + Token::Kind kind,
|
| + intptr_t type_args_len,
|
| + intptr_t argument_count,
|
| + const Array& argument_names,
|
| + intptr_t checked_argument_count,
|
| + const Function& interface_target) {
|
| + return flow_graph_builder_->InstanceCall(
|
| + position, name, kind, type_args_len, argument_count, argument_names,
|
| + checked_argument_count, interface_target);
|
| }
|
|
|
| Fragment StreamingFlowGraphBuilder::ThrowException(TokenPosition position) {
|
| @@ -5007,19 +5019,6 @@ Fragment StreamingFlowGraphBuilder::LoadField(intptr_t offset) {
|
| return flow_graph_builder_->LoadField(offset);
|
| }
|
|
|
| -Fragment StreamingFlowGraphBuilder::InstanceCall(
|
| - TokenPosition position,
|
| - const dart::String& name,
|
| - Token::Kind kind,
|
| - intptr_t type_args_len,
|
| - intptr_t argument_count,
|
| - const Array& argument_names,
|
| - intptr_t checked_argument_count) {
|
| - return flow_graph_builder_->InstanceCall(position, name, kind, type_args_len,
|
| - argument_count, argument_names,
|
| - checked_argument_count);
|
| -}
|
| -
|
| Fragment StreamingFlowGraphBuilder::StoreLocal(TokenPosition position,
|
| LocalVariable* variable) {
|
| return flow_graph_builder_->StoreLocal(position, variable);
|
| @@ -5315,9 +5314,21 @@ Fragment StreamingFlowGraphBuilder::BuildPropertyGet(TokenPosition* p) {
|
| instructions += PushArgument();
|
|
|
| const dart::String& getter_name = ReadNameAsGetterName(); // read name.
|
| - SkipCanonicalNameReference(); // Read unused "interface_target_reference".
|
|
|
| - return instructions + InstanceCall(position, getter_name, Token::kGET, 1);
|
| + const Function* interface_target = &Function::null_function();
|
| + NameIndex itarget_name =
|
| + ReadCanonicalNameReference(); // read interface_target_reference.
|
| + if (FLAG_experimental_strong_mode && !H.IsRoot(itarget_name) &&
|
| + (H.IsGetter(itarget_name) || H.IsField(itarget_name))) {
|
| + interface_target = &Function::ZoneHandle(
|
| + Z, LookupMethodByMember(itarget_name, H.DartGetterName(itarget_name)));
|
| + }
|
| +
|
| + const intptr_t kTypeArgsLen = 0;
|
| + const intptr_t kNumArgsChecked = 1;
|
| + return instructions + InstanceCall(position, getter_name, Token::kGET,
|
| + kTypeArgsLen, 1, Array::null_array(),
|
| + kNumArgsChecked, *interface_target);
|
| }
|
|
|
| Fragment StreamingFlowGraphBuilder::BuildPropertySet(TokenPosition* p) {
|
| @@ -5336,9 +5347,20 @@ Fragment StreamingFlowGraphBuilder::BuildPropertySet(TokenPosition* p) {
|
| instructions += StoreLocal(TokenPosition::kNoSource, variable);
|
| instructions += PushArgument();
|
|
|
| - SkipCanonicalNameReference(); // read unused "interface_target_reference".
|
| + const Function* interface_target = &Function::null_function();
|
| + NameIndex itarget_name =
|
| + ReadCanonicalNameReference(); // read interface_target_reference.
|
| + if (FLAG_experimental_strong_mode && !H.IsRoot(itarget_name)) {
|
| + interface_target = &Function::ZoneHandle(
|
| + Z, LookupMethodByMember(itarget_name, H.DartSetterName(itarget_name)));
|
| + }
|
| +
|
| + const intptr_t kTypeArgsLen = 0;
|
| + const intptr_t kNumArgsChecked = 1;
|
| + instructions +=
|
| + InstanceCall(position, setter_name, Token::kSET, kTypeArgsLen, 2,
|
| + Array::null_array(), kNumArgsChecked, *interface_target);
|
|
|
| - instructions += InstanceCall(position, setter_name, Token::kSET, 2);
|
| return instructions + Drop();
|
| }
|
|
|
| @@ -5504,9 +5526,8 @@ Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p) {
|
| if ((argument_count == 1) && (token_kind == Token::kNEGATE)) {
|
| const Object& result = constant_evaluator_.EvaluateExpressionSafe(offset);
|
| if (!result.IsError()) {
|
| - SkipArguments(); // read arguments,
|
| - // read unused "interface_target_reference".
|
| - SkipCanonicalNameReference();
|
| + SkipArguments(); // read arguments.
|
| + SkipCanonicalNameReference(); // read interface_target_reference.
|
| return Constant(result);
|
| }
|
| } else if ((argument_count == 2) &&
|
| @@ -5514,9 +5535,8 @@ Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p) {
|
| IsNumberLiteral(PeekArgumentsFirstPositionalTag())) {
|
| const Object& result = constant_evaluator_.EvaluateExpressionSafe(offset);
|
| if (!result.IsError()) {
|
| - SkipArguments();
|
| - // read unused "interface_target_reference".
|
| - SkipCanonicalNameReference();
|
| + SkipArguments(); // read arguments.
|
| + SkipCanonicalNameReference(); // read interface_target_reference.
|
| return Constant(result);
|
| }
|
| }
|
| @@ -5536,7 +5556,7 @@ Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p) {
|
| PeekArgumentsFirstPositionalTag() == kNullLiteral)) {
|
| // "==" or "!=" with null on either side.
|
| instructions += BuildArguments(NULL, NULL, true); // read arguments.
|
| - SkipCanonicalNameReference(); // read unused "interface_target_reference".
|
| + SkipCanonicalNameReference(); // read interface_target_reference.
|
| Token::Kind strict_cmp_kind =
|
| token_kind == Token::kEQ ? Token::kEQ_STRICT : Token::kNE_STRICT;
|
| return instructions +
|
| @@ -5561,9 +5581,18 @@ Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p) {
|
| checked_argument_count = argument_count;
|
| }
|
|
|
| + const Function* interface_target = &Function::null_function();
|
| + NameIndex itarget_name =
|
| + ReadCanonicalNameReference(); // read interface_target_reference.
|
| + if (FLAG_experimental_strong_mode && !H.IsRoot(itarget_name)) {
|
| + interface_target = &Function::ZoneHandle(
|
| + Z,
|
| + LookupMethodByMember(itarget_name, H.DartProcedureName(itarget_name)));
|
| + }
|
| +
|
| instructions +=
|
| InstanceCall(position, name, token_kind, kTypeArgsLen, argument_count,
|
| - argument_names, checked_argument_count);
|
| + argument_names, checked_argument_count, *interface_target);
|
| // Later optimization passes assume that result of a x.[]=(...) call is not
|
| // used. We must guarantee this invariant because violation will lead to an
|
| // illegal IL once we replace x.[]=(...) with a sequence that does not
|
| @@ -5573,8 +5602,6 @@ Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p) {
|
| instructions += NullConstant();
|
| }
|
|
|
| - SkipCanonicalNameReference(); // read unused "interface_target_reference".
|
| -
|
| return instructions;
|
| }
|
|
|
|
|