Skip to content

Commit

Permalink
[CFE] Constant transformation for expression compilation
Browse files Browse the repository at this point in the history
Fixes #42240

Change-Id: Idc75e99aed6acbb67755c77faa1904183a630f91
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153355
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
  • Loading branch information
jensjoha authored and commit-bot@chromium.org committed Jul 8, 2020
1 parent 219935a commit ad4d43c
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 24 deletions.
26 changes: 26 additions & 0 deletions pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,32 @@ void transformLibraries(
}
}

void transformProcedure(
Procedure procedure,
ConstantsBackend backend,
Map<String, String> environmentDefines,
TypeEnvironment typeEnvironment,
ErrorReporter errorReporter,
EvaluationMode evaluationMode,
{bool keepFields: true,
bool evaluateAnnotations: true,
bool desugarSets: false,
bool enableTripleShift: false,
bool errorOnUnevaluatedConstant: false}) {
final ConstantsTransformer constantsTransformer = new ConstantsTransformer(
backend,
environmentDefines,
keepFields,
evaluateAnnotations,
desugarSets,
enableTripleShift,
errorOnUnevaluatedConstant,
typeEnvironment,
errorReporter,
evaluationMode);
constantsTransformer.visitProcedure(procedure);
}

enum EvaluationMode {
weak,
agnostic,
Expand Down
64 changes: 43 additions & 21 deletions pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ import '../target_implementation.dart' show TargetImplementation;
import '../uri_translator.dart' show UriTranslator;

import 'constant_evaluator.dart' as constants
show EvaluationMode, transformLibraries;
show EvaluationMode, transformLibraries, transformProcedure;

import 'kernel_constants.dart' show KernelConstantErrorReporter;

Expand Down Expand Up @@ -1092,26 +1092,7 @@ class KernelTarget extends TargetImplementation {

TypeEnvironment environment =
new TypeEnvironment(loader.coreTypes, loader.hierarchy);
constants.EvaluationMode evaluationMode;
// If nnbd is not enabled we will use weak evaluation mode. This is needed
// because the SDK might be agnostic and therefore needs to be weakened
// for legacy mode.
assert(
isExperimentEnabledGlobally(ExperimentalFlag.nonNullable) ||
loader.nnbdMode == NnbdMode.Weak,
"Non-weak nnbd mode found without experiment enabled: "
"${loader.nnbdMode}.");
switch (loader.nnbdMode) {
case NnbdMode.Weak:
evaluationMode = constants.EvaluationMode.weak;
break;
case NnbdMode.Strong:
evaluationMode = constants.EvaluationMode.strong;
break;
case NnbdMode.Agnostic:
evaluationMode = constants.EvaluationMode.agnostic;
break;
}
constants.EvaluationMode evaluationMode = _getConstantEvaluationMode();

constants.transformLibraries(
loader.libraries,
Expand Down Expand Up @@ -1141,11 +1122,52 @@ class KernelTarget extends TargetImplementation {
ChangedStructureNotifier get changedStructureNotifier => null;

void runProcedureTransformations(Procedure procedure) {
TypeEnvironment environment =
new TypeEnvironment(loader.coreTypes, loader.hierarchy);
constants.EvaluationMode evaluationMode = _getConstantEvaluationMode();

constants.transformProcedure(
procedure,
backendTarget.constantsBackend(loader.coreTypes),
environmentDefines,
environment,
new KernelConstantErrorReporter(loader),
evaluationMode,
desugarSets: !backendTarget.supportsSetLiterals,
enableTripleShift:
isExperimentEnabledGlobally(ExperimentalFlag.tripleShift),
errorOnUnevaluatedConstant: errorOnUnevaluatedConstant);
ticker.logMs("Evaluated constants");

backendTarget.performTransformationsOnProcedure(
loader.coreTypes, loader.hierarchy, procedure,
logger: (String msg) => ticker.logMs(msg));
}

constants.EvaluationMode _getConstantEvaluationMode() {
constants.EvaluationMode evaluationMode;
// If nnbd is not enabled we will use weak evaluation mode. This is needed
// because the SDK might be agnostic and therefore needs to be weakened
// for legacy mode.
assert(
isExperimentEnabledGlobally(ExperimentalFlag.nonNullable) ||
loader.nnbdMode == NnbdMode.Weak,
"Non-weak nnbd mode found without experiment enabled: "
"${loader.nnbdMode}.");
switch (loader.nnbdMode) {
case NnbdMode.Weak:
evaluationMode = constants.EvaluationMode.weak;
break;
case NnbdMode.Strong:
evaluationMode = constants.EvaluationMode.strong;
break;
case NnbdMode.Agnostic:
evaluationMode = constants.EvaluationMode.agnostic;
break;
}
return evaluationMode;
}

void verify() {
// TODO(ahe): How to handle errors.
verifyComponent(component);
Expand Down
4 changes: 3 additions & 1 deletion pkg/front_end/test/fasta/expression_suite.dart
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,9 @@ class CompilationResult {
if (compiledProcedure == null) {
buffer.write("<no procedure>");
} else {
new Printer(buffer).visitProcedure(compiledProcedure);
Printer printer = new Printer(buffer);
printer.visitProcedure(compiledProcedure);
printer.writeConstantTable(new Component());
}
Uri base = entryPoint.resolve(".");
return "$buffer".replaceAll("$base", "org-dartlang-testcase:///");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2020, 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.

entry_point: "main.dart"
definitions: []
position: "main.dart"
expression: |
const42.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Errors: {
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
return (#C2).{main::ConstClass::x};
constants {
#C1 = 42
#C2 = main::ConstClass {x:#C1}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2020, 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.

entry_point: "main.dart"
definitions: []
position: "main.dart#ConstClass"
expression: |
classConst42.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Errors: {
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
return (#C2).{main::ConstClass::x};
constants {
#C1 = 42
#C2 = main::ConstClass {x:#C1}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,9 @@ Errors: {
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
return () → dart.core::Null? {
new main::A::•<dynamic>();
const main::A::•<dynamic>();
#C2;
};
constants {
#C1 = 0
#C2 = main::A<dynamic> {_priv:#C1}
}
8 changes: 8 additions & 0 deletions pkg/front_end/testcases/expression/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ int _privateToplevel(int x) => x + 1;
int globalVar = 6;
int _globalPrivate = 7;

const ConstClass const42 = ConstClass(42);

class ConstClass {
static const ConstClass classConst42 = ConstClass(42);
final int x;
const ConstClass(this.x);
}

class A<T> {
const A();
static int doit(int x) => x + 1;
Expand Down
2 changes: 1 addition & 1 deletion pkg/frontend_server/test/src/expression_compiler_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1164,7 +1164,7 @@ int main() {
expression: 'const MyClass(1)',
expectedResult: '''
(function(p) {
return dart.const(new foo.MyClass.new(1));
return C0 || CT.C0;
}(
1
))
Expand Down

0 comments on commit ad4d43c

Please sign in to comment.