Skip to content

Commit

Permalink
Version 2.1.0-dev.9.4
Browse files Browse the repository at this point in the history
Cherry-pick e23acaa to dev
Cherry-pick e6d3a45 to dev
Cherry-pick a40fd6a to dev
Cherry-pick 9eb1d74 to dev
  • Loading branch information
whesse committed Nov 8, 2018
2 parents 204556d + 58bb05b commit f9ebf21
Show file tree
Hide file tree
Showing 63 changed files with 584 additions and 174 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# 2.1.0-dev.9.4

Cherry-pick e23acaaf90996b84548ea23af14730ff1a21d826 to dev

Cherry-pick e6d3a45b6a98ea36581ac375ec5cdd63dd829004 to dev

Cherry-pick a40fd6a976d3d3bc341cd2e0f7fb290b7819a52a to dev

Cherry-pick 9eb1d748819530bb3eb2f78699e0968de8b638fe to dev

# 2.1.0-dev.9.3

Cherry-pick 65951ef5080bcfa7d8862685e96f75c2c5d17841 to dev
Expand Down
1 change: 0 additions & 1 deletion pkg/vm/bin/dump_kernel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import 'package:vm/metadata/procedure_attributes.dart'
show ProcedureAttributesMetadataRepository;
import 'package:vm/metadata/unreachable.dart'
show UnreachableNodeMetadataRepository;

import 'package:vm/metadata/call_site_attributes.dart'
show CallSiteAttributesMetadataRepository;

Expand Down
6 changes: 6 additions & 0 deletions pkg/vm/lib/kernel_front_end.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ import 'transformations/no_dynamic_invocations_annotator.dart'
as no_dynamic_invocations_annotator show transformComponent;
import 'transformations/type_flow/transformer.dart' as globalTypeFlow
show transformComponent;
import 'transformations/obfuscation_prohibitions_annotator.dart'
as obfuscationProhibitions;

/// Generates a kernel representation of the program whose main library is in
/// the given [source]. Intended for whole program (non-modular) compilation.
Expand Down Expand Up @@ -140,6 +142,10 @@ Future _runGlobalTransformations(
devirtualization.transformComponent(coreTypes, component);
no_dynamic_invocations_annotator.transformComponent(component);
}

// We don't know yet whether gen_snapshot will want to do obfuscation, but if
// it does it will need the obfuscation prohibitions.
obfuscationProhibitions.transformComponent(component, coreTypes);
}

/// Runs given [action] with [CompilerContext]. This is needed to
Expand Down
49 changes: 49 additions & 0 deletions pkg/vm/lib/metadata/obfuscation_prohibitions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// 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.

library vm.metadata.obfuscation_prohibitions;

import 'package:kernel/ast.dart';

class ObfuscationProhibitionsMetadata {
final Set<String> protectedNames = Set<String>();

ObfuscationProhibitionsMetadata();

@override
String toString() => protectedNames.toString();
}

/// Repository for [ObfuscationProhibitionsMetadata].
class ObfuscationProhibitionsMetadataRepository
extends MetadataRepository<ObfuscationProhibitionsMetadata> {
static final repositoryTag = 'vm.obfuscation-prohibitions.metadata';

@override
final String tag = repositoryTag;

@override
final Map<TreeNode, ObfuscationProhibitionsMetadata> mapping =
<TreeNode, ObfuscationProhibitionsMetadata>{};

@override
void writeToBinary(
ObfuscationProhibitionsMetadata metadata, Node node, BinarySink sink) {
sink.writeUInt32(metadata.protectedNames.length);
for (String name in metadata.protectedNames) {
sink.writeStringReference(name);
}
}

@override
ObfuscationProhibitionsMetadata readFromBinary(
Node node, BinarySource source) {
final metadata = ObfuscationProhibitionsMetadata();
int length = source.readUint32();
for (int i = 0; i < length; ++i) {
metadata.protectedNames.add(source.readStringReference());
}
return metadata;
}
}
61 changes: 61 additions & 0 deletions pkg/vm/lib/transformations/obfuscation_prohibitions_annotator.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// 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.

library vm.transformations.obfuscation_prohibitions_annotator;

import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart' show CoreTypes;

import '../metadata/obfuscation_prohibitions.dart';
import 'pragma.dart';

void transformComponent(Component component, CoreTypes coreTypes) {
final repo = new ObfuscationProhibitionsMetadataRepository();
component.addMetadataRepository(repo);
final visitor =
ObfuscationProhibitionsVisitor(ConstantPragmaAnnotationParser(coreTypes));
visitor.visitComponent(component);
repo.mapping[component] = visitor.metadata;
}

class ObfuscationProhibitionsVisitor extends RecursiveVisitor {
final PragmaAnnotationParser parser;
final metadata = ObfuscationProhibitionsMetadata();

ObfuscationProhibitionsVisitor(this.parser);

void _addIfEntryPoint(
List<Expression> annotations, String name, TreeNode node) {
for (var ann in annotations) {
ParsedPragma pragma = parser.parsePragma(ann);
if (pragma is ParsedEntryPointPragma) {
metadata.protectedNames.add(name);
if (node is Field) {
metadata.protectedNames.add(name + "=");
}
final parent = node.parent;
if (parent is Class) {
metadata.protectedNames.add(parent.name);
}
break;
}
}
}

@override
visitClass(Class klass) {
_addIfEntryPoint(klass.annotations, klass.name, klass);
klass.visitChildren(this);
}

@override
visitProcedure(Procedure proc) {
_addIfEntryPoint(proc.annotations, proc.name.name, proc);
}

@override
visitField(Field field) {
_addIfEntryPoint(field.annotations, field.name.name, field);
}
}
98 changes: 98 additions & 0 deletions pkg/vm/lib/transformations/pragma.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// 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.

library vm.transformations.pragma;

import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart' show CoreTypes;

const kEntryPointPragmaName = "vm:entry-point";
const kExactResultTypePragmaName = "vm:exact-result-type";

abstract class ParsedPragma {}

enum PragmaEntryPointType { Always, GetterOnly, SetterOnly }

class ParsedEntryPointPragma extends ParsedPragma {
final PragmaEntryPointType type;
ParsedEntryPointPragma(this.type);
}

class ParsedResultTypeByTypePragma extends ParsedPragma {
final DartType type;
ParsedResultTypeByTypePragma(this.type);
}

class ParsedResultTypeByPathPragma extends ParsedPragma {
final String path;
ParsedResultTypeByPathPragma(this.path);
}

abstract class PragmaAnnotationParser {
/// May return 'null' if the annotation does not represent a recognized
/// @pragma.
ParsedPragma parsePragma(Expression annotation);
}

class ConstantPragmaAnnotationParser extends PragmaAnnotationParser {
final CoreTypes coreTypes;

ConstantPragmaAnnotationParser(this.coreTypes);

ParsedPragma parsePragma(Expression annotation) {
InstanceConstant pragmaConstant;
if (annotation is ConstantExpression) {
Constant constant = annotation.constant;
if (constant is InstanceConstant) {
if (constant.classReference.node == coreTypes.pragmaClass) {
pragmaConstant = constant;
}
}
}
if (pragmaConstant == null) return null;

String pragmaName;
Constant name = pragmaConstant.fieldValues[coreTypes.pragmaName.reference];
if (name is StringConstant) {
pragmaName = name.value;
} else {
return null;
}

Constant options =
pragmaConstant.fieldValues[coreTypes.pragmaOptions.reference];
assert(options != null);

switch (pragmaName) {
case kEntryPointPragmaName:
PragmaEntryPointType type;
if (options is NullConstant) {
type = PragmaEntryPointType.Always;
} else if (options is BoolConstant && options.value == true) {
type = PragmaEntryPointType.Always;
} else if (options is StringConstant) {
if (options.value == "get") {
type = PragmaEntryPointType.GetterOnly;
} else if (options.value == "set") {
type = PragmaEntryPointType.SetterOnly;
} else {
throw "Error: string directive to @pragma('$kEntryPointPragmaName', ...) "
"must be either 'get' or 'set'.";
}
}
return type != null ? new ParsedEntryPointPragma(type) : null;
case kExactResultTypePragmaName:
if (options == null) return null;
if (options is TypeLiteralConstant) {
return new ParsedResultTypeByTypePragma(options.type);
} else if (options is StringConstant) {
return new ParsedResultTypeByPathPragma(options.value);
}
throw "ERROR: Unsupported option to '$kExactResultTypePragmaName' "
"pragma: $options";
default:
return null;
}
}
}
1 change: 1 addition & 0 deletions pkg/vm/lib/transformations/type_flow/analysis.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import 'summary.dart';
import 'summary_collector.dart';
import 'types.dart';
import 'utils.dart';
import '../pragma.dart';

// TODO(alexmarkov)
// Unordered list of various improvements in type flow analysis,
Expand Down
106 changes: 9 additions & 97 deletions pkg/vm/lib/transformations/type_flow/native_code.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ library vm.transformations.type_flow.native_code;
import 'dart:core' hide Type;

import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/library_index.dart' show LibraryIndex;

import 'calls.dart';
import 'types.dart';
import 'utils.dart';
import '../pragma.dart';

abstract class EntryPointsListener {
/// Add call by the given selector with arbitrary ('raw') arguments.
Expand All @@ -33,96 +33,6 @@ abstract class EntryPointsListener {
void recordMemberCalledViaThis(Member target);
}

abstract class ParsedPragma {}

enum PragmaEntryPointType { Always, GetterOnly, SetterOnly }

class ParsedEntryPointPragma extends ParsedPragma {
final PragmaEntryPointType type;
ParsedEntryPointPragma(this.type);
}

class ParsedResultTypeByTypePragma extends ParsedPragma {
final DartType type;
ParsedResultTypeByTypePragma(this.type);
}

class ParsedResultTypeByPathPragma extends ParsedPragma {
final String path;
ParsedResultTypeByPathPragma(this.path);
}

const kEntryPointPragmaName = "vm:entry-point";
const kExactResultTypePragmaName = "vm:exact-result-type";

abstract class PragmaAnnotationParser {
/// May return 'null' if the annotation does not represent a recognized
/// @pragma.
ParsedPragma parsePragma(Expression annotation);
}

class ConstantPragmaAnnotationParser extends PragmaAnnotationParser {
final CoreTypes coreTypes;

ConstantPragmaAnnotationParser(this.coreTypes);

ParsedPragma parsePragma(Expression annotation) {
InstanceConstant pragmaConstant;
if (annotation is ConstantExpression) {
Constant constant = annotation.constant;
if (constant is InstanceConstant) {
if (constant.classReference.node == coreTypes.pragmaClass) {
pragmaConstant = constant;
}
}
}
if (pragmaConstant == null) return null;

String pragmaName;
Constant name = pragmaConstant.fieldValues[coreTypes.pragmaName.reference];
if (name is StringConstant) {
pragmaName = name.value;
} else {
return null;
}

Constant options =
pragmaConstant.fieldValues[coreTypes.pragmaOptions.reference];
assertx(options != null);

switch (pragmaName) {
case kEntryPointPragmaName:
PragmaEntryPointType type;
if (options is NullConstant) {
type = PragmaEntryPointType.Always;
} else if (options is BoolConstant && options.value == true) {
type = PragmaEntryPointType.Always;
} else if (options is StringConstant) {
if (options.value == "get") {
type = PragmaEntryPointType.GetterOnly;
} else if (options.value == "set") {
type = PragmaEntryPointType.SetterOnly;
} else {
throw "Error: string directive to @pragma('$kEntryPointPragmaName', ...) "
"must be either 'get' or 'set'.";
}
}
return type != null ? new ParsedEntryPointPragma(type) : null;
case kExactResultTypePragmaName:
if (options == null) return null;
if (options is TypeLiteralConstant) {
return new ParsedResultTypeByTypePragma(options.type);
} else if (options is StringConstant) {
return new ParsedResultTypeByPathPragma(options.value);
}
throw "ERROR: Unsupported option to '$kExactResultTypePragmaName' "
"pragma: $options";
default:
return null;
}
}
}

class PragmaEntryPointsVisitor extends RecursiveVisitor {
final EntryPointsListener entryPoints;
final NativeCodeOracle nativeCodeOracle;
Expand All @@ -145,13 +55,15 @@ class PragmaEntryPointsVisitor extends RecursiveVisitor {

@override
visitClass(Class klass) {
var type = _annotationsDefineRoot(klass.annotations);
if (type != null) {
if (type != PragmaEntryPointType.Always) {
throw "Error: pragma entry-point definition on a class must evaluate "
"to null, true or false. See entry_points_pragma.md.";
if (!klass.isAbstract) {
var type = _annotationsDefineRoot(klass.annotations);
if (type != null) {
if (type != PragmaEntryPointType.Always) {
throw "Error: pragma entry-point definition on a class must evaluate "
"to null, true or false. See entry_points_pragma.md.";
}
entryPoints.addAllocatedClass(klass);
}
entryPoints.addAllocatedClass(klass);
}
currentClass = klass;
klass.visitChildren(this);
Expand Down
Loading

0 comments on commit f9ebf21

Please sign in to comment.