Version 0.1.3.0
svn merge -r 13512:13592 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
git-svn-id: http://dart.googlecode.com/svn/trunk@13596 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
index d198622..0c74025 100644
--- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
+++ b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
@@ -1482,7 +1482,8 @@
}
if (target instanceof DartBinaryExpression) {
DartBinaryExpression binary = (DartBinaryExpression) target;
- if (binary.getOperator() == Token.DIV) {
+ if (binary.getOperator() == Token.DIV && intType.equals(binary.getArg1().getType())
+ && intType.equals(binary.getArg2().getType())) {
typeError(node, TypeErrorCode.USE_INTEGER_DIVISION);
}
}
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
index cb8a83a..961a981 100644
--- a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
+++ b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
@@ -5307,11 +5307,28 @@
/**
* Developers unfamiliar with Dart frequently write (x/y).toInt() instead of x ~/ y. The editor
- * should recognize that pattern
+ * should recognize that pattern.
* <p>
* http://code.google.com/p/dart/issues/detail?id=5652
*/
- public void test_useEffectiveIntegerDivision() throws Exception {
+ public void test_useEffectiveIntegerDivision_int() throws Exception {
+ AnalyzeLibraryResult result = analyzeLibrary(
+ "// filler filler filler filler filler filler filler filler filler filler",
+ "main() {",
+ " int x = 7;",
+ " int y = 2;",
+ " print( (x / y).toInt() );",
+ "}",
+ "");
+ assertErrors(result.getErrors(), errEx(TypeErrorCode.USE_INTEGER_DIVISION, 5, 10, 15));
+ }
+
+ /**
+ * We need to report warning only when arguments are integers.
+ * <p>
+ * http://code.google.com/p/dart/issues/detail?id=5652
+ */
+ public void test_useEffectiveIntegerDivision_num() throws Exception {
AnalyzeLibraryResult result = analyzeLibrary(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
@@ -5320,6 +5337,6 @@
" print( (x / y).toInt() );",
"}",
"");
- assertErrors(result.getErrors(), errEx(TypeErrorCode.USE_INTEGER_DIVISION, 5, 10, 15));
+ assertErrors(result.getErrors());
}
}
diff --git a/lib/compiler/implementation/apiimpl.dart b/lib/compiler/implementation/apiimpl.dart
index 9a669dc..40030da 100644
--- a/lib/compiler/implementation/apiimpl.dart
+++ b/lib/compiler/implementation/apiimpl.dart
@@ -31,7 +31,9 @@
enableUserAssertions: hasOption(options, '--enable-checked-mode'),
enableMinification: hasOption(options, '--minify'),
emitJavaScript: !hasOption(options, '--output-type=dart'),
- strips: getStrips(options));
+ strips: getStrips(options),
+ enableConcreteTypeInference:
+ hasOption(options, '--enable-concrete-type-inference'));
static List<String> getStrips(List<String> options) {
for (String option in options) {
diff --git a/lib/compiler/implementation/closure.dart b/lib/compiler/implementation/closure.dart
index ec82f30..6e11253 100644
--- a/lib/compiler/implementation/closure.dart
+++ b/lib/compiler/implementation/closure.dart
@@ -18,7 +18,8 @@
String get name => "Closure Simplifier";
- ClosureClassMap computeClosureToClassMapping(FunctionExpression node,
+ ClosureClassMap computeClosureToClassMapping(Element element,
+ Expression node,
TreeElements elements) {
return measure(() {
ClosureClassMap cached = closureMappingCache[node];
@@ -26,9 +27,16 @@
ClosureTranslator translator =
new ClosureTranslator(compiler, elements, closureMappingCache);
+
// The translator will store the computed closure-mappings inside the
- // cache. One for given method and one for each nested closure.
- translator.translate(node);
+ // cache. One for given node and one for each nested closure.
+ if (node is FunctionExpression) {
+ translator.translateFunction(element, node);
+ } else {
+ // Must be the lazy initializer of a static.
+ assert(node is SendSet);
+ translator.translateLazyInitializer(element, node);
+ }
assert(closureMappingCache[node] != null);
return closureMappingCache[node];
});
@@ -71,8 +79,8 @@
STATE_DONE) {
compiler.closureClass.ensureResolved(compiler);
supertype = compiler.closureClass.computeType(compiler);
- interfaces = const EmptyLink<DartType>();
- allSupertypes = new Link<DartType>(supertype);
+ interfaces = const Link<DartType>();
+ allSupertypes = const Link<DartType>().prepend(supertype);
}
bool isClosure() => true;
@@ -113,7 +121,7 @@
class ClosureClassMap {
// The closure's element before any translation. Will be null for methods.
- final FunctionElement closureElement;
+ final Element closureElement;
// The closureClassElement will be null for methods that are not local
// closures.
final ClassElement closureClassElement;
@@ -170,7 +178,7 @@
// will update this mapping.
Map<Element, Element> capturedVariableMapping;
// List of encountered closures.
- List<FunctionExpression> closures;
+ List<Expression> closures;
// The variables that have been declared in the current scope.
List<Element> scopeVariables;
@@ -179,8 +187,8 @@
// non-mutated variables.
Set<Element> mutatedVariables;
- FunctionElement outermostFunctionElement;
- FunctionElement currentFunctionElement;
+ Element outermostElement;
+ Element currentElement;
// The closureData of the currentFunctionElement.
ClosureClassMap closureData;
@@ -189,11 +197,14 @@
ClosureTranslator(this.compiler, this.elements, this.closureMappingCache)
: capturedVariableMapping = new Map<Element, Element>(),
- closures = <FunctionExpression>[],
+ closures = <Expression>[],
mutatedVariables = new Set<Element>();
- void translate(Node node) {
- visit(node);
+ void translateFunction(Element element, FunctionExpression node) {
+ // For constructors the [element] and the [:elements[node]:] may differ.
+ // The [:elements[node]:] always points to the generative-constructor
+ // element, whereas the [element] might be the constructor-body element.
+ visit(node); // [visitFunctionExpression] will call [visitInvokable].
// When variables need to be boxed their [capturedVariableMapping] is
// updated, but we delay updating the similar freeVariableMapping in the
// closure datas that capture these variables.
@@ -201,12 +212,19 @@
updateClosures();
}
+ void translateLazyInitializer(Element element, SendSet node) {
+ assert(node.assignmentOperator.source == const SourceString("="));
+ Expression initialValue = node.argumentsNode.nodes.head;
+ visitInvokable(element, node, () { visit(initialValue); });
+ updateClosures();
+ }
+
// This function runs through all of the existing closures and updates their
// free variables to the boxed value. It also adds the field-elements to the
// class representing the closure. At the same time it fills the
// [capturedFieldMapping].
void updateClosures() {
- for (FunctionExpression closure in closures) {
+ for (Expression closure in closures) {
// The captured variables that need to be stored in a field of the closure
// class.
Set<Element> fieldCaptures = new Set<Element>();
@@ -260,8 +278,8 @@
// parameters, and type parameters are declared in the class, not
// the factory.
if (insideClosure &&
- element.enclosingElement != currentFunctionElement &&
- element != currentFunctionElement) {
+ element.enclosingElement != currentElement &&
+ element != currentElement) {
assert(closureData.freeVariableMapping[element] == null ||
closureData.freeVariableMapping[element] == element);
closureData.freeVariableMapping[element] = element;
@@ -373,12 +391,12 @@
}
}
}
- if (outermostFunctionElement.isMember() &&
- compiler.world.needsRti(outermostFunctionElement.getEnclosingClass())) {
- if (outermostFunctionElement.isInstanceMember()
- || outermostFunctionElement.isGenerativeConstructor()) {
+ if (outermostElement.isMember() &&
+ compiler.world.needsRti(outermostElement.getEnclosingClass())) {
+ if (outermostElement.isInstanceMember()
+ || outermostElement.isGenerativeConstructor()) {
if (hasTypeVariable(type)) useLocal(closureData.thisElement);
- } else if (outermostFunctionElement.isFactoryConstructor()) {
+ } else if (outermostElement.isFactoryConstructor()) {
analyzeTypeVariables(type);
}
}
@@ -402,7 +420,7 @@
// TODO(floitsch): construct better box names.
SourceString boxName =
new SourceString("box_${closureFieldCounter++}");
- box = new BoxElement(boxName, currentFunctionElement);
+ box = new BoxElement(boxName, currentElement);
}
// TODO(floitsch): construct better boxed names.
String elementName = element.name.slowToString();
@@ -501,7 +519,7 @@
element,
globalizedElement);
globalizedElement.backendMembers =
- const EmptyLink<Element>().prepend(callElement);
+ const Link<Element>().prepend(callElement);
// The nested function's 'this' is the same as the one for the outer
// function. It could be [null] if we are inside a static method.
Element thisElement = closureData.thisElement;
@@ -509,25 +527,18 @@
callElement, thisElement);
}
- visitFunctionExpression(FunctionExpression node) {
- Element element = elements[node];
- if (element.isParameter()) {
- // TODO(ahe): This is a hack. This method should *not* call
- // visitChildren.
- return node.name.accept(this);
- }
-
+ void visitInvokable(Element element, Expression node, void visitChildren()) {
bool oldInsideClosure = insideClosure;
- FunctionElement oldFunctionElement = currentFunctionElement;
+ Element oldFunctionElement = currentElement;
ClosureClassMap oldClosureData = closureData;
- insideClosure = outermostFunctionElement != null;
- currentFunctionElement = element;
+ insideClosure = outermostElement != null;
+ currentElement = element;
if (insideClosure) {
closures.add(node);
closureData = globalizeClosure(node, element);
} else {
- outermostFunctionElement = element;
+ outermostElement = element;
Element thisElement = null;
if (element.isInstanceMember() || element.isGenerativeConstructor()) {
thisElement = new ThisElement(element);
@@ -549,23 +560,17 @@
declareLocal(element);
}
- if (currentFunctionElement.isFactoryConstructor()
- && compiler.world.needsRti(currentFunctionElement.enclosingElement)) {
+ if (currentElement.isFactoryConstructor()
+ && compiler.world.needsRti(currentElement.enclosingElement)) {
// Declare the type parameters in the scope. Generative
// constructors just use 'this'.
- ClassElement cls = currentFunctionElement.enclosingElement;
+ ClassElement cls = currentElement.enclosingElement;
cls.typeVariables.forEach((TypeVariableType typeVariable) {
declareLocal(typeVariable.element);
});
}
- // TODO(ahe): This is problematic. The backend should not repeat
- // the work of the resolver. It is the resolver's job to create
- // parameters, etc. Other phases should only visit statements.
- // TODO(floitsch): we avoid visiting the initializers on purpose so that
- // we get an error-message later in the builder.
- if (node.parameters !== null) node.parameters.accept(this);
- if (node.body !== null) node.body.accept(this);
+ visitChildren();
});
@@ -575,7 +580,7 @@
// Restore old values.
insideClosure = oldInsideClosure;
closureData = oldClosureData;
- currentFunctionElement = oldFunctionElement;
+ currentElement = oldFunctionElement;
// Mark all free variables as captured and use them in the outer function.
List<Element> freeVariables =
@@ -591,6 +596,26 @@
}
}
+ visitFunctionExpression(FunctionExpression node) {
+ Element element = elements[node];
+
+ if (element.isParameter()) {
+ // TODO(ahe): This is a hack. This method should *not* call
+ // visitChildren.
+ return node.name.accept(this);
+ }
+
+ visitInvokable(element, node, () {
+ // TODO(ahe): This is problematic. The backend should not repeat
+ // the work of the resolver. It is the resolver's job to create
+ // parameters, etc. Other phases should only visit statements.
+ // TODO(floitsch): we avoid visiting the initializers on purpose so that
+ // we get an error-message later in the builder.
+ if (node.parameters !== null) node.parameters.accept(this);
+ if (node.body !== null) node.body.accept(this);
+ });
+ }
+
visitFunctionDeclaration(FunctionDeclaration node) {
node.visitChildren(this);
declareLocal(elements[node]);
diff --git a/lib/compiler/implementation/compile_time_constants.dart b/lib/compiler/implementation/compile_time_constants.dart
index 8e67ebc..ce96502 100644
--- a/lib/compiler/implementation/compile_time_constants.dart
+++ b/lib/compiler/implementation/compile_time_constants.dart
@@ -779,7 +779,7 @@
0);
evaluateSuperOrRedirectSend(functionNode,
selector,
- const EmptyLink<Node>(),
+ const Link<Node>(),
targetConstructor);
}
}
diff --git a/lib/compiler/implementation/compiler.dart b/lib/compiler/implementation/compiler.dart
index 821fc12..e461074 100644
--- a/lib/compiler/implementation/compiler.dart
+++ b/lib/compiler/implementation/compiler.dart
@@ -100,6 +100,7 @@
final bool enableMinification;
final bool enableTypeAssertions;
final bool enableUserAssertions;
+ final bool enableConcreteTypeInference;
bool disableInlining = false;
@@ -196,6 +197,7 @@
Compiler([this.tracer = const Tracer(),
this.enableTypeAssertions = false,
this.enableUserAssertions = false,
+ this.enableConcreteTypeInference = false,
this.enableMinification = false,
bool emitJavaScript = true,
bool generateSourceMap = true,
@@ -213,7 +215,7 @@
resolver = new ResolverTask(this);
closureToClassMapper = new closureMapping.ClosureTask(this);
checker = new TypeCheckerTask(this);
- typesTask = new ti.TypesTask(this);
+ typesTask = new ti.TypesTask(this, enableConcreteTypeInference);
backend = emitJavaScript ?
new js_backend.JavaScriptBackend(this, generateSourceMap) :
new dart_backend.DartBackend(this, strips);
@@ -477,7 +479,7 @@
if (compilationFailed) return;
log('Inferring types...');
- typesTask.onResolutionComplete();
+ typesTask.onResolutionComplete(main);
// TODO(ahe): Remove this line. Eventually, enqueuer.resolution
// should know this.
diff --git a/lib/compiler/implementation/dart2js.dart b/lib/compiler/implementation/dart2js.dart
index ee41641..91e7b92 100644
--- a/lib/compiler/implementation/dart2js.dart
+++ b/lib/compiler/implementation/dart2js.dart
@@ -147,10 +147,13 @@
new OptionHandler('--minify', passThrough),
new OptionHandler('--force-strip=.*', setStrip),
// TODO(ahe): Remove the --no-colors option.
- new OptionHandler('--disable-diagnostic-colors', (_) => enableColors = false),
+ new OptionHandler('--disable-diagnostic-colors',
+ (_) => enableColors = false),
new OptionHandler('--enable-diagnostic-colors', (_) => enableColors = true),
new OptionHandler('--enable[_-]checked[_-]mode|--checked',
(_) => passThrough('--enable-checked-mode')),
+ new OptionHandler('--enable-concrete-type-inference',
+ (_) => passThrough('--enable-concrete-type-inference')),
new OptionHandler(r'--help|/\?|/h', (_) => wantHelp = true),
new OptionHandler(r'--package-root=.+|-p.+', setPackageRoot),
// The following two options must come last.
@@ -386,7 +389,10 @@
--allow-mock-compilation
Do not generate a call to main if either of the following
- libraries are used: dart:dom, dart:html dart:io.''');
+ libraries are used: dart:dom, dart:html dart:io.
+
+ --enable-concrete-type-inference
+ Enable experimental concrete type inference.''');
}
void helpAndExit(bool verbose) {
diff --git a/lib/compiler/implementation/dart_backend/backend.dart b/lib/compiler/implementation/dart_backend/backend.dart
index dd9596b..a6d59d9 100644
--- a/lib/compiler/implementation/dart_backend/backend.dart
+++ b/lib/compiler/implementation/dart_backend/backend.dart
@@ -351,14 +351,14 @@
SynthesizedConstructorElement constructor =
new SynthesizedConstructorElement(classElement);
constructor.type = new FunctionType(
- compiler.types.voidType, const EmptyLink<DartType>(),
+ compiler.types.voidType, const Link<DartType>(),
constructor);
constructor.cachedNode = new FunctionExpression(
new Send(receiver: classElement.parseNode(compiler).name,
selector: synthesizedIdentifier),
new NodeList(beginToken: new StringToken(OPEN_PAREN_INFO, '(', -1),
endToken: new StringToken(CLOSE_PAREN_INFO, ')', -1),
- nodes: const EmptyLink<Node>()),
+ nodes: const Link<Node>()),
new EmptyStatement(new StringToken(SEMICOLON_INFO, ';', -1)),
null, Modifiers.EMPTY, null, null);
diff --git a/lib/compiler/implementation/dart_backend/utils.dart b/lib/compiler/implementation/dart_backend/utils.dart
index d19b6d8..53f75ea 100644
--- a/lib/compiler/implementation/dart_backend/utils.dart
+++ b/lib/compiler/implementation/dart_backend/utils.dart
@@ -44,7 +44,7 @@
node.onKeyword, node.catchKeyword);
visitClassNode(ClassNode node) => new ClassNode(
- visit(node.name), visit(node.typeParameters),
+ visit(node.modifiers), visit(node.name), visit(node.typeParameters),
visit(node.superclass), visit(node.interfaces), visit(node.defaultClause),
node.beginToken, node.extendsKeyword, visit(node.body), node.endToken);
diff --git a/lib/compiler/implementation/elements/elements.dart b/lib/compiler/implementation/elements/elements.dart
index 9877fe7..5ae0939 100644
--- a/lib/compiler/implementation/elements/elements.dart
+++ b/lib/compiler/implementation/elements/elements.dart
@@ -114,7 +114,7 @@
final SourceString name;
final ElementKind kind;
final Element enclosingElement;
- Link<MetadataAnnotation> metadata = const EmptyLink<MetadataAnnotation>();
+ Link<MetadataAnnotation> metadata = const Link<MetadataAnnotation>();
Element(this.name, this.kind, this.enclosingElement) {
assert(isErroneous() || getImplementationLibrary() !== null);
@@ -247,11 +247,7 @@
CompilationUnitElement getCompilationUnit() {
Element element = this;
- while (element !== null && !element.isCompilationUnit()) {
- if (element.isLibrary()) {
- LibraryElement library = element;
- return library.entryCompilationUnit;
- }
+ while (!element.isCompilationUnit()) {
element = element.enclosingElement;
}
return element;
@@ -398,7 +394,7 @@
}
class ContainerElement extends Element {
- Link<Element> localMembers = const EmptyLink<Element>();
+ Link<Element> localMembers = const Link<Element>();
ContainerElement(name, kind, enclosingElement)
: super(name, kind, enclosingElement);
@@ -561,8 +557,8 @@
final Uri uri;
CompilationUnitElement entryCompilationUnit;
Link<CompilationUnitElement> compilationUnits =
- const EmptyLink<CompilationUnitElement>();
- Link<LibraryTag> tags = const EmptyLink<LibraryTag>();
+ const Link<CompilationUnitElement>();
+ Link<LibraryTag> tags = const Link<LibraryTag>();
LibraryName libraryTag;
bool canUseNative = false;
@@ -614,6 +610,8 @@
LibraryElement get declaration => super.declaration;
LibraryElement get implementation => super.implementation;
+ CompilationUnitElement getCompilationUnit() => entryCompilationUnit;
+
void addCompilationUnit(CompilationUnitElement element) {
compilationUnits = compilationUnits.prepend(element);
}
@@ -1278,7 +1276,7 @@
*/
static Link<DartType> createTypeVariables(TypeDeclarationElement element,
NodeList parameters) {
- if (parameters === null) return const EmptyLink<DartType>();
+ if (parameters === null) return const Link<DartType>();
// Create types and elements for type variable.
var arguments = new LinkBuilder<DartType>();
@@ -1308,7 +1306,7 @@
// backendMembers are members that have been added by the backend to simplify
// compilation. They don't have any user-side counter-part.
- Link<Element> backendMembers = const EmptyLink<Element>();
+ Link<Element> backendMembers = const Link<Element>();
Link<DartType> allSupertypes;
@@ -1507,7 +1505,7 @@
Link<Element> get constructors {
// TODO(ajohnsen): See if we can avoid this method at some point.
- Link<Element> result = const EmptyLink<Element>();
+ Link<Element> result = const Link<Element>();
// TODO(johnniwinther): Should we include injected constructors?
forEachMember((_, Element member) {
if (member.isConstructor()) result = result.prepend(member);
@@ -1867,7 +1865,7 @@
class TargetElement extends Element {
final Node statement;
final int nestingLevel;
- Link<LabelElement> labels = const EmptyLink<LabelElement>();
+ Link<LabelElement> labels = const Link<LabelElement>();
bool isBreakTarget = false;
bool isContinueTarget = false;
diff --git a/lib/compiler/implementation/enqueue.dart b/lib/compiler/implementation/enqueue.dart
index d41f3c4..f2e9101 100644
--- a/lib/compiler/implementation/enqueue.dart
+++ b/lib/compiler/implementation/enqueue.dart
@@ -167,7 +167,7 @@
String memberName = member.name.slowToString();
Link<Element> members = instanceMembersByName.putIfAbsent(
- memberName, () => const EmptyLink<Element>());
+ memberName, () => const Link<Element>());
instanceMembersByName[memberName] = members.prepend(member);
if (member.kind == ElementKind.FUNCTION) {
diff --git a/lib/compiler/implementation/js/printer.dart b/lib/compiler/implementation/js/printer.dart
index 9305995..27c9aa5 100644
--- a/lib/compiler/implementation/js/printer.dart
+++ b/lib/compiler/implementation/js/printer.dart
@@ -17,9 +17,9 @@
this.compiler = compiler,
outBuffer = new leg.CodeBuffer(),
danglingElseVisitor = new DanglingElseVisitor(compiler),
- namer = DetermineRenamer(compiler.enableMinification);
+ namer = determineRenamer(compiler.enableMinification);
- static Namer DetermineRenamer(bool shouldCompressOutput) {
+ static Namer determineRenamer(bool shouldCompressOutput) {
return shouldCompressOutput ? new MinifyRenamer() : new IdentityNamer();
}
@@ -852,11 +852,11 @@
class MinifyRenamer implements Namer {
- final List<Map<String, String>> maps;
- final List<int> nameNumberStack;
- int nameNumber;
+ final List<Map<String, String>> maps = [];
+ final List<int> nameNumberStack = [];
+ int nameNumber = 0;
- MinifyRenamer() : maps = [], nameNumberStack = [], nameNumber = 0;
+ MinifyRenamer();
void enterScope() {
maps.add(new Map<String, String>());
@@ -877,11 +877,46 @@
return oldName;
}
+ static int nthLetter(int n) {
+ return (n < 26) ? charCodes.$a + n : charCodes.$A + n - 26;
+ }
+
String declareName(String oldName) {
- if (maps.length == 0) return oldName;
- var newName = "z${nameNumber++}";
+ const LETTERS = 52;
+ const DIGITS = 10;
+ if (maps.isEmpty()) return oldName;
+ String newName;
+ int n = nameNumber;
+ if (n < LETTERS) {
+ // Start naming variables a, b, c, ..., z, A, B, C, ..., Z.
+ newName = new String.fromCharCodes([nthLetter(n)]);
+ } else {
+ // Then name variables a0, a1, a2, ..., a9, b0, b1, ..., Z9, aa0, aa1, ...
+ // For all functions with fewer than 500 locals this is just as compact
+ // as using aa, ab, etc. but avoids clashes with keywords.
+ n -= LETTERS;
+ int digit = n % DIGITS;
+ n ~/= DIGITS;
+ int alphaChars = 1;
+ int nameSpaceSize = LETTERS;
+ // Find out whether we should use the 1-character namespace (size 52), the
+ // 2-character namespace (size 52*52), etc.
+ while (n >= nameSpaceSize) {
+ n -= nameSpaceSize;
+ alphaChars++;
+ nameSpaceSize *= LETTERS;
+ }
+ var codes = <int>[];
+ for (var i = 0; i < alphaChars; i++) {
+ nameSpaceSize ~/= LETTERS;
+ codes.add(nthLetter((n ~/ nameSpaceSize) % LETTERS));
+ }
+ codes.add(charCodes.$0 + digit);
+ newName = new String.fromCharCodes(codes);
+ }
+ assert(const RegExp(r'[a-zA-Z][a-zA-Z0-9]*').hasMatch(newName));
+ nameNumber++;
maps.last()[oldName] = newName;
return newName;
}
-
}
diff --git a/lib/compiler/implementation/lib/isolate_patch.dart b/lib/compiler/implementation/lib/isolate_patch.dart
index 76fe2d0..e6fc239 100644
--- a/lib/compiler/implementation/lib/isolate_patch.dart
+++ b/lib/compiler/implementation/lib/isolate_patch.dart
@@ -85,13 +85,15 @@
// TODO(eub, sigmund): move the "manager" to be entirely in JS.
// Running any Dart code outside the context of an isolate gives it
// the change to break the isolate abstraction.
-_Manager get _globalState() native "return \$globalState;";
-set _globalState(_Manager val) native "\$globalState = val;";
+_Manager get _globalState() => JS("Object", r"$globalState");
+set _globalState(_Manager val) {
+ JS("void", r"$globalState = #", val);
+}
-void _fillStatics(context) native r"""
- $globals = context.isolateStatics;
- $static_init();
-""";
+void _fillStatics(context) {
+ JS("void", r"$globals = #.isolateStatics", context);
+ JS("void", r"$static_init()");
+}
ReceivePort _lazyPort;
patch ReceivePort get port() {
@@ -185,17 +187,18 @@
}
}
- void _nativeDetectEnvironment() native r"""
- this.isWorker = $isWorker;
- this.supportsWorkers = $supportsWorkers;
- this.fromCommandLine = typeof(window) == 'undefined';
- """;
+ void _nativeDetectEnvironment() {
+ JS("void", r"#.isWorker = $isWorker", this);
+ JS("void", r"#.supportsWorkers = $supportsWorkers", this);
+ JS("void", r"#.fromCommandLine = typeof(window) == 'undefined'", this);
+ }
- void _nativeInitWorkerMessageHandler() native r"""
- $globalThis.onmessage = function (e) {
- _IsolateNatives._processWorkerMessage(this.mainManager, e);
- }
- """;
+ void _nativeInitWorkerMessageHandler() {
+ JS("void", r"""
+$globalThis.onmessage = function (e) {
+ _IsolateNatives._processWorkerMessage(this.mainManager, e);
+}""");
+ }
/*: TODO: check that _processWorkerMessage is not discarded while treeshaking.
""" {
_IsolateNatives._processWorkerMessage(null, null);
@@ -229,7 +232,7 @@
}
// these are filled lazily the first time the isolate starts running.
- void initGlobals() native r'$initGlobals(this);';
+ void initGlobals() { JS("void", r'$initGlobals(#)', this); }
/**
* Run [code] in the context of the isolate represented by [this]. Note this
@@ -249,7 +252,7 @@
return result;
}
- void _setGlobals() native r'$setGlobals(this);';
+ void _setGlobals() { JS("void", r'$setGlobals(#)', this); }
/** Lookup a port registered for this isolate. */
ReceivePort lookup(int portId) => ports[portId];
@@ -379,7 +382,7 @@
void set onmessage(f) {
throw new Exception("onmessage should not be set on MainManagerStub");
}
- void postMessage(msg) native r"$globalThis.postMessage(msg);";
+ void postMessage(msg) { JS("void", r"$globalThis.postMessage(#)", msg); }
void terminate() {} // Nothing useful to do here.
}
@@ -390,10 +393,10 @@
* are actually available.
*/
class _WorkerStub implements _ManagerStub native "*Worker" {
- get id() native "return this.id;";
- void set id(i) native "this.id = i;";
- void set onmessage(f) native "this.onmessage = f;";
- void postMessage(msg) native "return this.postMessage(msg);";
+ get id() => JS("Object", "#.id", this);
+ void set id(i) { JS("void", "#.id = #", this, i); }
+ void set onmessage(f) { JS("void", "#.onmessage = #", this, f); }
+ void postMessage(msg) => JS("Object", "#.postMessage(#)", this, msg);
// terminate() is implemented by Worker.
abstract void terminate();
}
@@ -406,17 +409,17 @@
* The src url for the script tag that loaded this code. Used to create
* JavaScript workers.
*/
- static String get _thisScript() native r"return $thisScriptUrl";
+ static String get _thisScript() => JS("String", r"$thisScriptUrl");
/** Starts a new worker with the given URL. */
- static _WorkerStub _newWorker(url) native "return new Worker(url);";
+ static _WorkerStub _newWorker(url) => JS("Object", r"new Worker(#)", url);
/**
* Assume that [e] is a browser message event and extract its message data.
* We don't import the dom explicitly so, when workers are disabled, this
* library can also run on top of nodejs.
*/
- static _getEventData(e) native "return e.data";
+ static _getEventData(e) => JS("Object", "#.data", e);
/**
* Process messages on a worker, either to control the worker instance or to
@@ -477,41 +480,48 @@
}
}
- static void _consoleLog(msg) native "\$globalThis.console.log(msg);";
+ static void _consoleLog(msg) {
+ JS("void", r"$globalThis.console.log(#)", msg);
+ }
/**
* Extract the constructor of runnable, so it can be allocated in another
* isolate.
*/
- static Dynamic _getJSConstructor(Isolate runnable) native """
- return runnable.constructor;
- """;
+ static Dynamic _getJSConstructor(Isolate runnable) {
+ return JS("Object", "#.constructor", runnable);
+ }
/** Extract the constructor name of a runnable */
// TODO(sigmund): find a browser-generic way to support this.
- static Dynamic _getJSConstructorName(Isolate runnable) native """
- return runnable.constructor.name;
- """;
+ // TODO(floitsch): is this function still used? If yes, should we use
+ // Primitives.objectTypeName instead?
+ static Dynamic _getJSConstructorName(Isolate runnable) {
+ return JS("Object", "#.constructor.name", runnable);
+ }
/** Find a constructor given its name. */
- static Dynamic _getJSConstructorFromName(String factoryName) native """
- return \$globalThis[factoryName];
- """;
+ static Dynamic _getJSConstructorFromName(String factoryName) {
+ return JS("Object", r"$globalThis[#]", factoryName);
+ }
- static Dynamic _getJSFunctionFromName(String functionName) native """
- return \$globalThis[functionName];
- """;
+ static Dynamic _getJSFunctionFromName(String functionName) {
+ return JS("Object", r"$globalThis[#]", functionName);
+ }
/**
* Get a string name for the function, if possible. The result for
* anonymous functions is browser-dependent -- it may be "" or "anonymous"
* but you should probably not count on this.
*/
- static String _getJSFunctionName(Function f)
- native r"return f.$name || (void 0);";
+ static String _getJSFunctionName(Function f) {
+ return JS("Object", r"(#.$name || #)", f, null);
+ }
/** Create a new JavaScript object instance given its constructor. */
- static Dynamic _allocate(var ctor) native "return new ctor();";
+ static Dynamic _allocate(var ctor) {
+ return JS("Object", "new #()", ctor);
+ }
// TODO(sigmund): clean up above, after we make the new API the default:
@@ -989,21 +999,24 @@
}
/** Remove all information injected in the native objects. */
- cleanup() {
+ void cleanup() {
for (int i = 0, length = tagged.length; i < length; i++) {
_clearAttachedInfo(tagged[i]);
}
tagged = null;
}
- _clearAttachedInfo(var o) native
- "o['__MessageTraverser__attached_info__'] = (void 0);";
+ void _clearAttachedInfo(var o) {
+ JS("void", "#['__MessageTraverser__attached_info__'] = #", o, null);
+ }
- _setAttachedInfo(var o, var info) native
- "o['__MessageTraverser__attached_info__'] = info;";
+ void _setAttachedInfo(var o, var info) {
+ JS("void", "#['__MessageTraverser__attached_info__'] = #", o, info);
+ }
- _getAttachedInfo(var o) native
- "return o['__MessageTraverser__attached_info__'];";
+ _getAttachedInfo(var o) {
+ return JS("Object", "#['__MessageTraverser__attached_info__']", o);
+ }
}
// only visible for testing purposes
diff --git a/lib/compiler/implementation/library_loader.dart b/lib/compiler/implementation/library_loader.dart
index c101176..a7ca9e0 100644
--- a/lib/compiler/implementation/library_loader.dart
+++ b/lib/compiler/implementation/library_loader.dart
@@ -37,6 +37,87 @@
}
/**
+ * [CombinatorFilter] is a succinct representation of a list of combinators from
+ * a library dependency tag.
+ */
+class CombinatorFilter {
+ const CombinatorFilter();
+
+ /**
+ * Returns [:true:] if [element] is excluded by this filter.
+ */
+ bool exclude(Element element) => false;
+
+ /**
+ * Creates a filter based on the combinators of [tag].
+ */
+ factory CombinatorFilter.fromTag(LibraryDependency tag) {
+ if (tag == null || tag.combinators == null) {
+ return const CombinatorFilter();
+ }
+
+ // If the list of combinators contain at least one [:show:] we can create
+ // a positive list of elements to include, otherwise we create a negative
+ // list of elements to exclude.
+ bool show = false;
+ Set<SourceString> nameSet;
+ for (Combinator combinator in tag.combinators) {
+ if (combinator.isShow) {
+ show = true;
+ var set = new Set<SourceString>();
+ for (Identifier identifier in combinator.identifiers) {
+ set.add(identifier.source);
+ }
+ if (nameSet == null) {
+ nameSet = set;
+ } else {
+ nameSet = nameSet.intersection(set);
+ }
+ }
+ }
+ if (nameSet == null) {
+ nameSet = new Set<SourceString>();
+ }
+ for (Combinator combinator in tag.combinators) {
+ if (combinator.isHide) {
+ for (Identifier identifier in combinator.identifiers) {
+ if (show) {
+ // We have a positive list => Remove hidden elements.
+ nameSet.remove(identifier.source);
+ } else {
+ // We have no positive list => Accumulate hidden elements.
+ nameSet.add(identifier.source);
+ }
+ }
+ }
+ }
+ return show ? new ShowFilter(nameSet) : new HideFilter(nameSet);
+ }
+}
+
+/**
+ * A list of combinators represented as a list of element names to include.
+ */
+class ShowFilter extends CombinatorFilter {
+ final Set<SourceString> includedNames;
+
+ ShowFilter(this.includedNames);
+
+ bool exclude(Element element) => !includedNames.contains(element.name);
+}
+
+/**
+ * A list of combinators represented as a list of element names to exclude.
+ */
+class HideFilter extends CombinatorFilter {
+ final Set<SourceString> excludedNames;
+
+ HideFilter(this.excludedNames);
+
+ bool exclude(Element element) => excludedNames.contains(element.name);
+}
+
+/**
* Implementation class for [LibraryLoader]. The distinction between
* [LibraryLoader] and [LibraryLoaderTask] is made to hide internal members from
* the [LibraryLoader] interface.
@@ -91,9 +172,6 @@
for (LibraryTag tag in library.tags.reverse()) {
if (tag.isImport) {
tagState = checkTag(TagState.IMPORT_OR_EXPORT, tag);
- if (tag.combinators != null) {
- compiler.unimplemented('combinators', node: tag.combinators);
- }
if (tag.uri.dartString.slowToString() == 'dart:core') {
importsDartCore = true;
}
@@ -291,6 +369,7 @@
assert(invariant(importingLibrary,
importedLibrary.exportsHandled,
message: 'Exports not handled on $importedLibrary'));
+ var combinatorFilter = new CombinatorFilter.fromTag(import);
if (import !== null && import.prefix !== null) {
SourceString prefix = import.prefix.source;
Element e = importingLibrary.find(prefix);
@@ -308,7 +387,7 @@
}
PrefixElement prefixElement = e;
importedLibrary.forEachExport((Element element) {
- // TODO(johnniwinther): Handle show and hide combinators.
+ if (combinatorFilter.exclude(element)) return;
// TODO(johnniwinther): Clean-up like [checkDuplicateLibraryName].
Element existing =
prefixElement.imported.putIfAbsent(element.name, () => element);
@@ -326,7 +405,7 @@
} else {
importedLibrary.forEachExport((Element element) {
compiler.withCurrentElement(element, () {
- // TODO(johnniwinther): Handle show and hide combinators.
+ if (combinatorFilter.exclude(element)) return;
importingLibrary.addImport(element, compiler);
});
});
@@ -335,6 +414,29 @@
}
/**
+ * The combinator filter computed from an export tag and the library dependency
+ * node for the library that declared the export tag. This represents an edge in
+ * the library dependency graph.
+ */
+class ExportLink {
+ final CombinatorFilter combinatorFilter;
+ final LibraryDependencyNode exportNode;
+
+ ExportLink(Export export, LibraryDependencyNode this.exportNode)
+ : this.combinatorFilter = new CombinatorFilter.fromTag(export);
+
+ /**
+ * Exports [element] to the dependent library unless [element] is filtered by
+ * the export combinators. Returns [:true:] if the set pending exports of the
+ * dependent library was modified.
+ */
+ bool exportElement(Element element) {
+ if (combinatorFilter.exclude(element)) return false;
+ return exportNode.addElementToPendingExports(element);
+ }
+}
+
+/**
* A node in the library dependency graph.
*
* This class is used to collect the library dependencies expressed through
@@ -349,15 +451,13 @@
* corresponding libraries. This is used to propagate exports into imports
* after the export scopes have been computed.
*/
- Link<ImportLink> imports = const EmptyLink<ImportLink>();
+ Link<ImportLink> imports = const Link<ImportLink>();
/**
- * The export tags that export [library] mapped to the nodes for the libraries
- * that declared each export tag. This is used to propagete exports during the
- * computation of export scopes.
+ * A linked list of the export tags the dependent upon this node library.
+ * This is used to propagate exports during the computation of export scopes.
*/
- Map<Export, LibraryDependencyNode> dependencyMap =
- new Map<Export, LibraryDependencyNode>();
+ Link<ExportLink> dependencies = const Link<ExportLink>();
/**
* The export scope for [library] which is gradually computed by the work-list
@@ -389,7 +489,8 @@
*/
void registerExportDependency(Export export,
LibraryDependencyNode exportingLibraryNode) {
- dependencyMap[export] = exportingLibraryNode;
+ dependencies =
+ dependencies.prepend(new ExportLink(export, exportingLibraryNode));
}
/**
@@ -433,7 +534,7 @@
/**
* Adds [element] to the export scope for this node. If the [element] name
- * is a duplicate, an error element is inserted into the exscope.
+ * is a duplicate, an error element is inserted into the export scope.
*/
Element addElementToExportScope(Compiler compiler, Element element) {
SourceString name = element.name;
@@ -457,11 +558,11 @@
*/
bool propagateElement(Element element) {
bool change = false;
- dependencyMap.forEach((Export export, LibraryDependencyNode exportNode) {
- if (exportNode.addElementToPendingExports(export, element)) {
+ for (ExportLink link in dependencies) {
+ if (link.exportElement(element)) {
change = true;
}
- });
+ }
return change;
}
@@ -470,8 +571,7 @@
* the pending export set was modified. The combinators of [export] are used
* to filter the element.
*/
- bool addElementToPendingExports(Export export, Element element) {
- // TODO(johnniwinther): Use [export] to handle show and hide combinators.
+ bool addElementToPendingExports(Element element) {
if (exportScope[element.name] !== element) {
if (!pendingExportSet.contains(element)) {
pendingExportSet.add(element);
diff --git a/lib/compiler/implementation/resolver.dart b/lib/compiler/implementation/resolver.dart
index 6292087..17c9d56 100644
--- a/lib/compiler/implementation/resolver.dart
+++ b/lib/compiler/implementation/resolver.dart
@@ -365,7 +365,7 @@
MessageKind.CYCLIC_CLASS_HIERARCHY.error([cls.name]),
api.Diagnostic.ERROR);
cls.supertypeLoadState = STATE_DONE;
- cls.allSupertypes = const EmptyLink<DartType>().prepend(
+ cls.allSupertypes = const Link<DartType>().prepend(
compiler.objectClass.computeType(compiler));
// TODO(ahe): We should also set cls.supertype here to avoid
// creating a malformed class hierarchy.
@@ -788,7 +788,7 @@
});
if (functionNode.initializers === null) {
- initializers = const EmptyLink<Node>();
+ initializers = const Link<Node>();
} else {
initializers = functionNode.initializers.nodes;
}
@@ -918,8 +918,8 @@
StatementScope()
: labels = const EmptyLabelScope(),
- breakTargetStack = const EmptyLink<TargetElement>(),
- continueTargetStack = const EmptyLink<TargetElement>();
+ breakTargetStack = const Link<TargetElement>(),
+ continueTargetStack = const Link<TargetElement>();
LabelElement lookupLabel(String label) {
return labels.lookup(label);
@@ -1086,7 +1086,7 @@
Link<DartType> typeVariables,
Scope scope, onFailure, whenResolved) {
if (node.typeArguments == null) {
- return const EmptyLink<DartType>();
+ return const Link<DartType>();
}
var arguments = new LinkBuilder<DartType>();
for (Link<Node> typeArguments = node.typeArguments.nodes;
@@ -1279,7 +1279,7 @@
FunctionSignature functionParameters =
function.computeSignature(compiler);
Link<Node> parameterNodes = (node.parameters === null)
- ? const EmptyLink<Node>() : node.parameters.nodes;
+ ? const Link<Node>() : node.parameters.nodes;
functionParameters.forEachParameter((Element element) {
if (element == functionParameters.optionalParameters.head) {
NodeList nodes = parameterNodes.head;
@@ -1375,9 +1375,20 @@
} else {
name = node.name.asIdentifier().source;
}
+ // TODO(ahe): we shouldn't use the scope to get the enclosing element. This
+ // is currently needed so that nested functions get their correct enclosing
+ // element.
+ Element functionEnclosing = scope.element;
+ if (functionEnclosing.kind == ElementKind.VARIABLE_LIST) {
+ compiler.internalError("Bad enclosing element", node: node);
+ }
+ if (functionEnclosing.isLibrary()) {
+ // We are in a static initializers.
+ functionEnclosing = enclosingElement;
+ }
FunctionElement enclosing = new FunctionElement.node(
name, node, ElementKind.FUNCTION, Modifiers.EMPTY,
- scope.element);
+ functionEnclosing);
setupFunction(node, enclosing);
defineElement(node, enclosing, doAddToScope: node.name !== null);
@@ -1847,7 +1858,7 @@
// Resolve the type arguments. We cannot create a type and check the
// number of type arguments for this annotation, because we do not know
// the element.
- Link arguments = const EmptyLink<Node>();
+ Link arguments = const Link<Node>();
if (annotation.typeArguments != null) {
arguments = annotation.typeArguments.nodes;
}
@@ -2338,7 +2349,7 @@
element.supertype = new InterfaceType(objectElement);
}
assert(element.interfaces === null);
- Link<DartType> interfaces = const EmptyLink<DartType>();
+ Link<DartType> interfaces = const Link<DartType>();
for (Link<Node> link = node.interfaces.nodes;
!link.isEmpty();
link = link.tail) {
@@ -2419,8 +2430,7 @@
ClassElement superElement = supertype.element;
Link<DartType> superSupertypes = superElement.allSupertypes;
assert(superSupertypes !== null);
- Link<DartType> supertypes =
- new Link<DartType>(supertype, superSupertypes);
+ Link<DartType> supertypes = superSupertypes.prepend(supertype);
for (Link<DartType> interfaces = cls.interfaces;
!interfaces.isEmpty();
interfaces = interfaces.tail) {
@@ -2433,7 +2443,7 @@
cls.allSupertypes = supertypes;
} else {
assert(cls === compiler.objectClass);
- cls.allSupertypes = const EmptyLink<DartType>();
+ cls.allSupertypes = const Link<DartType>();
}
}
@@ -2447,7 +2457,7 @@
new SynthesizedConstructorElement(element);
element.addToScope(constructor, compiler);
DartType returnType = compiler.types.voidType;
- constructor.type = new FunctionType(returnType, const EmptyLink<DartType>(),
+ constructor.type = new FunctionType(returnType, const Link<DartType>(),
constructor);
constructor.cachedNode =
new FunctionExpression(new Identifier(element.position()),
@@ -2582,7 +2592,7 @@
*/
class SignatureResolver extends CommonResolverVisitor<Element> {
final Element enclosingElement;
- Link<Element> optionalParameters = const EmptyLink<Element>();
+ Link<Element> optionalParameters = const Link<Element>();
int optionalParameterCount = 0;
bool optionalParametersAreNamed = false;
VariableDefinitions currentDefinitions;
@@ -2725,7 +2735,7 @@
Node returnNode,
Element element) {
SignatureResolver visitor = new SignatureResolver(compiler, element);
- Link<Element> parameters = const EmptyLink<Element>();
+ Link<Element> parameters = const Link<Element>();
int requiredParameterCount = 0;
if (formalParameters === null) {
if (!element.isGetter()) {
diff --git a/lib/compiler/implementation/runtime_types.dart b/lib/compiler/implementation/runtime_types.dart
index cd7f49a..9f51ec4 100644
--- a/lib/compiler/implementation/runtime_types.dart
+++ b/lib/compiler/implementation/runtime_types.dart
@@ -11,6 +11,25 @@
#import('util/util.dart');
class RuntimeTypeInformation {
+ /**
+ * Names used for elements in runtime type information. This map is kept to
+ * detect elements with the same name and use a different name instead.
+ */
+ final Map<String, Element> usedNames = new Map<String, Element>();
+
+ /** Get a unique name for the element. */
+ String getName(Element element) {
+ String guess = element.name.slowToString();
+ String name = guess;
+ int id = 0;
+ while (usedNames.containsKey(name) && usedNames[name] != element) {
+ name = '$guess@$id';
+ id++;
+ }
+ usedNames[name] = element;
+ return name;
+ }
+
bool hasTypeArguments(DartType type) {
if (type is InterfaceType) {
InterfaceType interfaceType = type;
@@ -48,9 +67,8 @@
* variables than [numberOfInputs], 'Dynamic' is used as the value for these
* arguments.
*/
- static String generateRuntimeTypeString(ClassElement element,
- int numberOfInputs) {
- String elementName = element.name.slowToString();
+ String generateRuntimeTypeString(ClassElement element, int numberOfInputs) {
+ String elementName = getName(element);
if (element.typeVariables.isEmpty()) return "'$elementName'";
String stringify(_, bool hasValue) => hasValue ? "' + # + '" : "Dynamic";
String arguments = stringifyTypeVariables(element.typeVariables,
diff --git a/lib/compiler/implementation/scanner/array_based_scanner.dart b/lib/compiler/implementation/scanner/array_based_scanner.dart
index c15c166..3b6cff2 100644
--- a/lib/compiler/implementation/scanner/array_based_scanner.dart
+++ b/lib/compiler/implementation/scanner/array_based_scanner.dart
@@ -14,7 +14,7 @@
/** Since the input is UTF8, some characters are represented by more
* than one byte. [extraCharOffset] tracks the difference. */
int extraCharOffset;
- Link<BeginGroupToken> groupingStack = const EmptyLink<BeginGroupToken>();
+ Link<BeginGroupToken> groupingStack = const Link<BeginGroupToken>();
ArrayBasedScanner(this.includeComments)
: this.extraCharOffset = 0,
diff --git a/lib/compiler/implementation/scanner/class_element_parser.dart b/lib/compiler/implementation/scanner/class_element_parser.dart
index 70655d4..b2a4b03 100644
--- a/lib/compiler/implementation/scanner/class_element_parser.dart
+++ b/lib/compiler/implementation/scanner/class_element_parser.dart
@@ -11,7 +11,7 @@
class PartialClassElement extends ClassElement {
final Token beginToken;
final Token endToken;
- Node cachedNode;
+ ClassNode cachedNode;
PartialClassElement(SourceString name,
Token this.beginToken,
@@ -56,37 +56,11 @@
Token position() => beginToken;
+ // TODO(johnniwinther): Ensure that modifiers are always available.
+ Modifiers get modifiers =>
+ cachedNode != null ? cachedNode.modifiers : Modifiers.EMPTY;
+
bool isInterface() => beginToken.stringValue === "interface";
-
- PartialClassElement cloneTo(Element enclosing, DiagnosticListener listener) {
- parseNode(listener);
- // TODO(lrn): Is copying id acceptable?
- // TODO(ahe): No.
- PartialClassElement result =
- new PartialClassElement(name, beginToken, endToken, enclosing, id);
-
- assert(this.supertypeLoadState == STATE_NOT_STARTED);
- assert(this.resolutionState == STATE_NOT_STARTED);
- assert(this.type === null);
- assert(this.supertype === null);
- assert(this.defaultClass === null);
- assert(this.interfaces === null);
- assert(this.allSupertypes === null);
- assert(this.backendMembers.isEmpty());
-
- // Native is only used in DOM/HTML library for which we don't
- // support patching.
- assert(this.nativeName === null);
-
- Link<Element> elementList = this.localMembers;
- while (!elementList.isEmpty()) {
- result.addMember(elementList.head.cloneTo(result, listener), listener);
- elementList = elementList.tail;
- }
-
- result.cachedNode = cachedNode;
- return result;
- }
}
class MemberListener extends NodeListener {
@@ -194,7 +168,7 @@
for (Link link = metadata; !link.isEmpty(); link = link.tail) {
memberElement.addMetadata(link.head);
}
- metadata = const EmptyLink<MetadataAnnotation>();
+ metadata = const Link<MetadataAnnotation>();
enclosingElement.addMember(memberElement, listener);
}
}
diff --git a/lib/compiler/implementation/scanner/listener.dart b/lib/compiler/implementation/scanner/listener.dart
index 2c74e0c..86d088c 100644
--- a/lib/compiler/implementation/scanner/listener.dart
+++ b/lib/compiler/implementation/scanner/listener.dart
@@ -567,7 +567,7 @@
Link<Token> expectedDeclaration(Token token) {
error("expected a declaration, but got '${token.slowToString()}'", token);
- return const EmptyLink<Token>();
+ return const Link<Token>();
}
Token unmatched(Token token) {
@@ -613,9 +613,9 @@
final StringValidator stringValidator;
Link<StringQuoting> interpolationScope;
- Link<Node> nodes = const EmptyLink<Node>();
+ Link<Node> nodes = const Link<Node>();
- Link<MetadataAnnotation> metadata = const EmptyLink<MetadataAnnotation>();
+ Link<MetadataAnnotation> metadata = const Link<MetadataAnnotation>();
ElementListener(DiagnosticListener listener,
CompilationUnitElement this.compilationUnitElement,
@@ -623,7 +623,7 @@
: this.listener = listener,
this.idGenerator = idGenerator,
stringValidator = new StringValidator(listener),
- interpolationScope = const EmptyLink<StringQuoting>();
+ interpolationScope = const Link<StringQuoting>();
void pushQuoting(StringQuoting quoting) {
interpolationScope = interpolationScope.prepend(quoting);
@@ -974,7 +974,7 @@
Link<Token> expectedDeclaration(Token token) {
listener.cancel("expected a declaration, but got '${token.slowToString()}'",
token: token);
- return const EmptyLink<Token>();
+ return const Link<Token>();
}
Token unmatched(Token token) {
@@ -990,7 +990,7 @@
for (Link link = metadata; !link.isEmpty(); link = link.tail) {
element.addMetadata(link.head);
}
- metadata = const EmptyLink<MetadataAnnotation>();
+ metadata = const Link<MetadataAnnotation>();
compilationUnitElement.addMember(element, listener);
}
@@ -1036,7 +1036,7 @@
NodeList makeNodeList(int count, Token beginToken, Token endToken,
String delimiter) {
- Link<Node> poppedNodes = const EmptyLink<Node>();
+ Link<Node> poppedNodes = const Link<Node>();
for (; count > 0; --count) {
// This effectively reverses the order of nodes so they end up
// in correct (source) order.
@@ -1066,7 +1066,7 @@
StringQuoting quoting = popQuoting();
Link<StringInterpolationPart> parts =
- const EmptyLink<StringInterpolationPart>();
+ const Link<StringInterpolationPart>();
// Parts of the string interpolation are popped in reverse order,
// starting with the last literal string part.
bool isLast = true;
@@ -1137,8 +1137,10 @@
TypeAnnotation supertype = popNode();
NodeList typeParameters = popNode();
Identifier name = popNode();
- pushNode(new ClassNode(name, typeParameters, supertype, interfaces, null,
- beginToken, extendsKeyword, body, endToken));
+ Modifiers modifiers = popNode();
+ pushNode(new ClassNode(modifiers, name, typeParameters, supertype,
+ interfaces, null, beginToken, extendsKeyword, body,
+ endToken));
}
void endCompilationUnit(int count, Token token) {
@@ -1162,9 +1164,9 @@
null, ',');
NodeList typeParameters = popNode();
Identifier name = popNode();
- pushNode(new ClassNode(name, typeParameters, null, supertypes,
- defaultClause, interfaceKeyword, null, body,
- endToken));
+ pushNode(new ClassNode(Modifiers.EMPTY, name, typeParameters, null,
+ supertypes, defaultClause, interfaceKeyword, null,
+ body, endToken));
}
void endClassBody(int memberCount, Token beginToken, Token endToken) {
@@ -1329,7 +1331,7 @@
if (send.asSendSet() !== null) internalError(node: send);
NodeList arguments;
if (send.isIndex) {
- Link<Node> link = new Link<Node>(arg);
+ Link<Node> link = const Link<Node>().prepend(arg);
link = link.prepend(send.arguments.head);
arguments = new NodeList(null, link);
} else {
@@ -1613,7 +1615,7 @@
}
void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
- Link<Node> caseNodes = const EmptyLink<Node>();
+ Link<Node> caseNodes = const Link<Node>();
while (caseCount > 0) {
SwitchCase switchCase = popNode();
caseNodes = caseNodes.prepend(switchCase);
diff --git a/lib/compiler/implementation/scanner/parser.dart b/lib/compiler/implementation/scanner/parser.dart
index 72fd63b..b2faf1a 100644
--- a/lib/compiler/implementation/scanner/parser.dart
+++ b/lib/compiler/implementation/scanner/parser.dart
@@ -433,10 +433,13 @@
Token parseClass(Token token) {
Token begin = token;
listener.beginClassDeclaration(token);
+ int modifierCount = 0;
if (optional('abstract', token)) {
- // TODO(ahe): Notify listener about abstract modifier.
+ listener.handleModifier(token);
+ modifierCount++;
token = token.next;
}
+ listener.handleModifiers(modifierCount);
token = parseIdentifier(token.next);
token = parseTypeVariablesOpt(token);
Token extendsKeyword;
@@ -649,7 +652,7 @@
Link<Token> findMemberName(Token token) {
Token start = token;
- Link<Token> identifiers = const EmptyLink<Token>();
+ Link<Token> identifiers = const Link<Token>();
while (token.kind !== EOF_TOKEN) {
String value = token.stringValue;
if ((value === '(') || (value === '{') || (value === '=>')) {
diff --git a/lib/compiler/implementation/ssa/builder.dart b/lib/compiler/implementation/ssa/builder.dart
index d9995d5..5cf3d37 100644
--- a/lib/compiler/implementation/ssa/builder.dart
+++ b/lib/compiler/implementation/ssa/builder.dart
@@ -367,21 +367,25 @@
*
* Invariant: [function] must be an implementation element.
*/
- void startFunction(FunctionElement function,
- FunctionExpression node) {
- assert(invariant(node, function.isImplementation));
+ void startFunction(Element element, Expression node) {
+ assert(invariant(node, element.isImplementation));
Compiler compiler = builder.compiler;
closureData = compiler.closureToClassMapper.computeClosureToClassMapping(
- node, builder.elements);
- FunctionSignature signature = function.computeSignature(compiler);
- signature.orderedForEachParameter((Element element) {
- HInstruction parameter = new HParameterValue(element);
- builder.add(parameter);
- builder.parameters[element] = parameter;
- directLocals[element] = parameter;
- parameter.guaranteedType =
- builder.mapInferredType(typesTask.getGuaranteedTypeOfElement(element));
- });
+ element, node, builder.elements);
+
+ if (element is FunctionElement) {
+ FunctionElement functionElement = element;
+ FunctionSignature params = functionElement.computeSignature(compiler);
+ params.orderedForEachParameter((Element parameterElement) {
+ HInstruction parameter = new HParameterValue(parameterElement);
+ builder.add(parameter);
+ builder.parameters[parameterElement] = parameter;
+ directLocals[parameterElement] = parameter;
+ parameter.guaranteedType =
+ builder.mapInferredType(
+ typesTask.getGuaranteedTypeOfElement(parameterElement));
+ });
+ }
enterScope(node);
@@ -396,12 +400,12 @@
HInstruction thisInstruction = new HThis();
builder.add(thisInstruction);
updateLocal(closureData.closureElement, thisInstruction);
- } else if (function.isInstanceMember()
- || function.isGenerativeConstructor()) {
+ } else if (element.isInstanceMember()
+ || element.isGenerativeConstructor()) {
// Once closures have been mapped to classes their instance members might
// not have any thisElement if the closure was created inside a static
// context.
- ClassElement cls = function.getEnclosingClass();
+ ClassElement cls = element.getEnclosingClass();
DartType type = cls.computeType(builder.compiler);
HInstruction thisInstruction = new HThis(new HBoundedType.nonNull(type));
builder.add(thisInstruction);
@@ -853,6 +857,7 @@
LocalsHandler localsHandler;
HInstruction rethrowableException;
Map<Element, HParameterValue> parameters;
+ final RuntimeTypeInformation rti;
Map<TargetElement, JumpHandler> jumpTargets;
@@ -894,6 +899,7 @@
parameters = new Map<Element, HParameterValue>(),
sourceElementStack = <Element>[work.element],
inliningStack = <InliningState>[],
+ rti = builder.compiler.codegenWorld.rti,
super(work.resolutionTree) {
localsHandler = new LocalsHandler(this);
}
@@ -930,19 +936,15 @@
}
HGraph buildLazyInitializer(VariableElement variable) {
- HBasicBlock block = graph.addNewBlock();
- open(graph.entry);
- close(new HGoto()).addSuccessor(block);
- open(block);
SendSet node = variable.parseNode(compiler);
+ openFunction(variable, node);
Link<Node> link = node.arguments;
assert(!link.isEmpty() && link.tail.isEmpty());
visit(link.head);
HInstruction value = pop();
value = potentiallyCheckType(value, variable);
close(new HReturn(value)).addSuccessor(graph.exit);
- graph.finalize();
- return graph;
+ return closeFunction();
}
/**
@@ -1219,7 +1221,7 @@
}
inlineSuperOrRedirect(target.implementation,
selector,
- const EmptyLink<Node>(),
+ const Link<Node>(),
constructors,
fieldValues);
}
@@ -1411,38 +1413,43 @@
*
* Invariant: [functionElement] must be the implementation element.
*/
- void openFunction(FunctionElement functionElement,
- FunctionExpression node) {
- assert(invariant(functionElement, functionElement.isImplementation));
+ void openFunction(Element element, Expression node) {
+ assert(invariant(element, element.isImplementation));
HBasicBlock block = graph.addNewBlock();
open(graph.entry);
- localsHandler.startFunction(functionElement, node);
+ localsHandler.startFunction(element, node);
close(new HGoto()).addSuccessor(block);
open(block);
- FunctionSignature params = functionElement.computeSignature(compiler);
- params.orderedForEachParameter((Element element) {
- if (elements.isParameterChecked(element)) {
- addParameterCheckInstruction(element);
- }
- });
+ if (element is FunctionElement) {
+ FunctionElement functionElement = element;
+ FunctionSignature params = functionElement.computeSignature(compiler);
+ params.orderedForEachParameter((Element parameterElement) {
+ if (elements.isParameterChecked(parameterElement)) {
+ addParameterCheckInstruction(parameterElement);
+ }
+ });
- // Put the type checks in the first successor of the entry,
- // because that is where the type guards will also be inserted.
- // This way we ensure that a type guard will dominate the type
- // check.
- params.orderedForEachParameter((Element element) {
- HInstruction newParameter = potentiallyCheckType(
- localsHandler.directLocals[element], element);
- localsHandler.directLocals[element] = newParameter;
- });
+ // Put the type checks in the first successor of the entry,
+ // because that is where the type guards will also be inserted.
+ // This way we ensure that a type guard will dominate the type
+ // check.
+ params.orderedForEachParameter((Element element) {
+ HInstruction newParameter = potentiallyCheckType(
+ localsHandler.directLocals[element], element);
+ localsHandler.directLocals[element] = newParameter;
+ });
+ } else {
+ // Otherwise it is a lazy initializer which does not have parameters.
+ assert(element is VariableElement);
+ }
// Add the type parameters of the class as parameters of this
// method.
- var enclosing = functionElement.enclosingElement;
- if (functionElement.isConstructor() && compiler.world.needsRti(enclosing)) {
+ var enclosing = element.enclosingElement;
+ if (element.isConstructor() && compiler.world.needsRti(enclosing)) {
enclosing.typeVariables.forEach((TypeVariableType typeVariable) {
HParameterValue param = new HParameterValue(typeVariable.element);
add(param);
@@ -2182,7 +2189,7 @@
// An erroneous element indicates an unresolved static getter.
generateThrowNoSuchMethod(send,
getTargetName(element, 'get'),
- const EmptyLink<Node>());
+ const Link<Node>());
} else {
stack.add(localsHandler.readLocal(element));
}
@@ -2792,7 +2799,7 @@
InterfaceType interfaceType = type;
bool hasTypeArguments = !interfaceType.arguments.isEmpty();
if (!isInQuotes) template.add("'");
- template.add("${type.element.name.slowToString()}");
+ template.add(rti.getName(type.element));
if (hasTypeArguments) {
template.add("<");
for (DartType argument in interfaceType.arguments) {
@@ -2809,7 +2816,7 @@
} else {
assert(type is TypedefType);
if (!isInQuotes) template.add("'");
- template.add(argument.toString());
+ template.add(rti.getName(argument.element));
if (!isInQuotes) template.add("'");
}
}
@@ -2854,8 +2861,7 @@
List<HInstruction> runtimeCodeInputs = <HInstruction>[];
if (runtimeTypeIsUsed) {
String runtimeTypeString =
- RuntimeTypeInformation.generateRuntimeTypeString(element,
- rtiInputs.length);
+ rti.generateRuntimeTypeString(element, rtiInputs.length);
HInstruction runtimeType = createForeign(runtimeTypeString, rtiInputs);
add(runtimeType);
runtimeCodeInputs.add(runtimeType);
@@ -4059,13 +4065,16 @@
compiler.internalError('SsaBuilder.visitTypeVariable');
}
- HType mapInferredType(Element element) {
- if (element === builder.compiler.boolClass) return HType.BOOLEAN;
- if (element === builder.compiler.doubleClass) return HType.DOUBLE;
- if (element === builder.compiler.intClass) return HType.INTEGER;
- if (element === builder.compiler.listClass) return HType.READABLE_ARRAY;
- if (element === builder.compiler.nullClass) return HType.NULL;
- if (element === builder.compiler.stringClass) return HType.STRING;
+ HType mapInferredType(ConcreteType concreteType) {
+ if (concreteType == null) return HType.UNKNOWN;
+ ClassElement element = concreteType.getUniqueType();
+ if (element == null) return HType.UNKNOWN;
+ if (element == builder.compiler.boolClass) return HType.BOOLEAN;
+ if (element == builder.compiler.doubleClass) return HType.DOUBLE;
+ if (element == builder.compiler.intClass) return HType.INTEGER;
+ if (element == builder.compiler.listClass) return HType.READABLE_ARRAY;
+ if (element == builder.compiler.nullClass) return HType.NULL;
+ if (element == builder.compiler.stringClass) return HType.STRING;
return HType.UNKNOWN;
}
diff --git a/lib/compiler/implementation/ssa/codegen.dart b/lib/compiler/implementation/ssa/codegen.dart
index 5afc86f..27e1b23 100644
--- a/lib/compiler/implementation/ssa/codegen.dart
+++ b/lib/compiler/implementation/ssa/codegen.dart
@@ -78,7 +78,7 @@
// the declaration.
FunctionElement function = work.element;
function.computeSignature(compiler).forEachParameter((element) {
- compiler.enqueuer.codegen.addToWorkList(element);
+ compiler.enqueuer.codegen.addToWorkList(element, work.resolutionTree);
});
List<js.Parameter> parameters = <js.Parameter>[];
parameterNames.forEach((element, name) {
@@ -952,7 +952,7 @@
bool visitLabeledBlockInfo(HLabeledBlockInformation labeledBlockInfo) {
preLabeledBlock(labeledBlockInfo);
- Link<Element> continueOverrides = const EmptyLink<Element>();
+ Link<Element> continueOverrides = const Link<Element>();
js.Block oldContainer = currentContainer;
js.Block body = new js.Block.empty();
diff --git a/lib/compiler/implementation/ssa/nodes.dart b/lib/compiler/implementation/ssa/nodes.dart
index e2da4ab..8d1f4c0 100644
--- a/lib/compiler/implementation/ssa/nodes.dart
+++ b/lib/compiler/implementation/ssa/nodes.dart
@@ -616,7 +616,7 @@
* information on [to], and that dominates the user.
*/
void rewriteWithBetterUser(HInstruction from, HInstruction to) {
- Link<HCheck> better = const EmptyLink<HCheck>();
+ Link<HCheck> better = const Link<HCheck>();
for (HInstruction user in to.usedBy) {
if (user is HCheck && (user as HCheck).checkedInput === to) {
better = better.prepend(user);
diff --git a/lib/compiler/implementation/ssa/ssa.dart b/lib/compiler/implementation/ssa/ssa.dart
index c5b4f1e..4a6ce7a 100644
--- a/lib/compiler/implementation/ssa/ssa.dart
+++ b/lib/compiler/implementation/ssa/ssa.dart
@@ -15,6 +15,7 @@
#import('../runtime_types.dart');
#import('../scanner/scannerlib.dart');
#import('../tree/tree.dart');
+#import('../types/types.dart');
#import('../universe/universe.dart');
#import('../util/util.dart');
#import('../util/characters.dart');
diff --git a/lib/compiler/implementation/tree/nodes.dart b/lib/compiler/implementation/tree/nodes.dart
index c87e893..d241628 100644
--- a/lib/compiler/implementation/tree/nodes.dart
+++ b/lib/compiler/implementation/tree/nodes.dart
@@ -202,6 +202,7 @@
}
class ClassNode extends Node {
+ final Modifiers modifiers;
final Identifier name;
final TypeAnnotation superclass;
final NodeList interfaces;
@@ -215,9 +216,9 @@
final Token extendsKeyword;
final Token endToken;
- ClassNode(this.name, this.typeParameters, this.superclass, this.interfaces,
- this.defaultClause, this.beginToken, this.extendsKeyword,
- this.body, this.endToken);
+ ClassNode(this.modifiers, this.name, this.typeParameters, this.superclass,
+ this.interfaces, this.defaultClause, this.beginToken,
+ this.extendsKeyword, this.body, this.endToken);
ClassNode asClassNode() => this;
@@ -356,12 +357,12 @@
}
class Postfix extends NodeList {
- Postfix() : super(nodes: const EmptyLink<Node>());
+ Postfix() : super(nodes: const Link<Node>());
Postfix.singleton(Node argument) : super.singleton(argument);
}
class Prefix extends NodeList {
- Prefix() : super(nodes: const EmptyLink<Node>());
+ Prefix() : super(nodes: const Link<Node>());
Prefix.singleton(Node argument) : super.singleton(argument);
}
@@ -439,8 +440,8 @@
Iterator<Node> iterator() => nodes.iterator();
- NodeList.singleton(Node node) : this(null, new Link<Node>(node));
- NodeList.empty() : this(null, const EmptyLink<Node>());
+ NodeList.singleton(Node node) : this(null, const Link<Node>().prepend(node));
+ NodeList.empty() : this(null, const Link<Node>());
NodeList asNodeList() => this;
diff --git a/lib/compiler/implementation/tree/prettyprint.dart b/lib/compiler/implementation/tree/prettyprint.dart
index 3132618..81886a8 100644
--- a/lib/compiler/implementation/tree/prettyprint.dart
+++ b/lib/compiler/implementation/tree/prettyprint.dart
@@ -18,7 +18,7 @@
PrettyPrinter() :
sb = new StringBuffer(),
- tagStack = new EmptyLink<String>();
+ tagStack = const Link<String>();
void pushTag(String tag) {
tagStack = tagStack.prepend(tag);
diff --git a/lib/compiler/implementation/typechecker.dart b/lib/compiler/implementation/typechecker.dart
index b57c1a8..fbba6f3 100644
--- a/lib/compiler/implementation/typechecker.dart
+++ b/lib/compiler/implementation/typechecker.dart
@@ -123,7 +123,7 @@
final Link<DartType> arguments;
const InterfaceType(this.element,
- [this.arguments = const EmptyLink<DartType>()]);
+ [this.arguments = const Link<DartType>()]);
SourceString get name => element.name;
@@ -216,7 +216,7 @@
final Link<DartType> typeArguments;
const TypedefType(this.element,
- [this.typeArguments = const EmptyLink<DartType>()]);
+ [this.typeArguments = const Link<DartType>()]);
SourceString get name => element.name;
@@ -331,7 +331,7 @@
DartType expectedReturnType;
ClassElement currentClass;
- Link<DartType> cascadeTypes = const EmptyLink<DartType>();
+ Link<DartType> cascadeTypes = const Link<DartType>();
DartType intType;
DartType doubleType;
diff --git a/lib/compiler/implementation/types/concrete_types_inferrer.dart b/lib/compiler/implementation/types/concrete_types_inferrer.dart
index 7f2b4ad..cd22a7a 100644
--- a/lib/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/lib/compiler/implementation/types/concrete_types_inferrer.dart
@@ -18,6 +18,7 @@
* - the unknown base type
*/
abstract class BaseType {
+ bool isClass();
bool isUnknown();
bool isNull();
}
@@ -36,6 +37,7 @@
}
int hashCode() => element.hashCode();
String toString() => element.name.slowToString();
+ bool isClass() => true;
bool isUnknown() => false;
bool isNull() => false;
}
@@ -47,6 +49,7 @@
const UnknownBaseType();
bool operator ==(BaseType other) => other is UnknownBaseType;
int hashCode() => 0;
+ bool isClass() => false;
bool isUnknown() => true;
bool isNull() => false;
toString() => "unknown";
@@ -59,6 +62,7 @@
const NullBaseType();
bool operator ==(BaseType other) => other is NullBaseType;
int hashCode() => 1;
+ bool isClass() => false;
bool isUnknown() => false;
bool isNull() => true;
toString() => "null";
@@ -89,6 +93,12 @@
abstract ConcreteType union(ConcreteType other);
abstract bool isUnkown();
abstract Set<BaseType> get baseTypes();
+
+ /**
+ * Returns the unique element of [: this :] if [: this :] is a singleton,
+ * null otherwise.
+ */
+ abstract ClassElement getUniqueType();
}
/**
@@ -102,6 +112,7 @@
new Set<BaseType>.from([const UnknownBaseType()]);
int hashCode() => 0;
ConcreteType union(ConcreteType other) => this;
+ ClassElement getUniqueType() => null;
toString() => "unknown";
}
@@ -143,6 +154,17 @@
return new UnionType(newBaseTypes);
}
+ ClassElement getUniqueType() {
+ if (baseTypes.length == 1) {
+ BaseType uniqueBaseType = baseTypes.iterator().next();
+ if (uniqueBaseType.isClass()) {
+ ClassBaseType uniqueClassType = uniqueBaseType;
+ return uniqueClassType.element;
+ }
+ }
+ return null;
+ }
+
String toString() => baseTypes.toString();
}
@@ -323,7 +345,6 @@
* of the program. The entry point is [analyzeMain].
*/
class ConcreteTypesInferrer {
-
static final bool LOG_FAILURES = true;
final String name = "Type inferrer";
diff --git a/lib/compiler/implementation/types/types.dart b/lib/compiler/implementation/types/types.dart
index 322ceed..dbbb11e 100644
--- a/lib/compiler/implementation/types/types.dart
+++ b/lib/compiler/implementation/types/types.dart
@@ -19,10 +19,13 @@
final String name = 'Type inference';
final Set<Element> untypedElements;
final Map<Element, Link<Element>> typedSends;
+ final ConcreteTypesInferrer concreteTypesInferrer;
- TypesTask(Compiler compiler)
+ TypesTask(Compiler compiler, bool enableConcreteTypeInference)
: untypedElements = new Set<Element>(),
typedSends = new Map<Element, Link<Element>>(),
+ concreteTypesInferrer = enableConcreteTypeInference
+ ? new ConcreteTypesInferrer(compiler) : null,
super(compiler);
/**
@@ -38,18 +41,25 @@
/**
* Called when resolution is complete.
*/
- void onResolutionComplete() {
+ void onResolutionComplete(Element mainElement) {
measure(() {
- // TODO(ahe): Do something here.
+ if (concreteTypesInferrer != null) {
+ concreteTypesInferrer.analyzeMain(mainElement);
+ }
});
}
/**
- * Return the (inferred) guaranteed type of [element].
+ * Return the (inferred) guaranteed concrete type of [element] or null.
*/
- Element getGuaranteedTypeOfElement(Element element) {
+ ConcreteType getGuaranteedTypeOfElement(Element element) {
return measure(() {
if (!element.isParameter()) return null;
+ if (concreteTypesInferrer != null) {
+ ConcreteType guaranteedType = concreteTypesInferrer
+ .getConcreteTypeOfParameter(element);
+ if (guaranteedType != null) return guaranteedType;
+ }
Element holder = element.enclosingElement;
Link<Element> types = typedSends[holder];
if (types === null) return null;
@@ -59,7 +69,9 @@
FunctionSignature signature = function.computeSignature(compiler);
for (Element parameter in signature.requiredParameters) {
if (types.isEmpty()) return null;
- if (element === parameter) return types.head;
+ if (element == parameter) {
+ return new ConcreteType.singleton(new ClassBaseType(types.head));
+ }
types = types.tail;
}
return null;
@@ -67,12 +79,14 @@
}
/**
- * Return the (inferred) guaranteed type of [node].
+ * Return the (inferred) guaranteed concrete type of [node] or null.
* [node] must be an AST node of [owner].
*/
- Element getGuaranteedTypeOfNode(Node node, Element owner) {
+ ConcreteType getGuaranteedTypeOfNode(Node node, Element owner) {
return measure(() {
- // TODO(ahe): Do something real here.
+ if (concreteTypesInferrer != null) {
+ return concreteTypesInferrer.getConcreteTypeOfNode(node);
+ }
return null;
});
}
@@ -151,7 +165,7 @@
Link<Element> computeConcreteSendArguments(Send node) {
if (node.argumentsNode === null) return null;
- if (node.arguments.isEmpty()) return const EmptyLink<Element>();
+ if (node.arguments.isEmpty()) return const Link<Element>();
if (node.receiver !== null && concreteTypes[node.receiver] === null) {
return null;
}
diff --git a/lib/compiler/implementation/universe/partial_type_tree.dart b/lib/compiler/implementation/universe/partial_type_tree.dart
index 1e80361..7cc1512 100644
--- a/lib/compiler/implementation/universe/partial_type_tree.dart
+++ b/lib/compiler/implementation/universe/partial_type_tree.dart
@@ -85,7 +85,7 @@
// the subtypes so we can move them from being children of the
// current node to being children of a new node if we need
// to insert that.
- Link<PartialTypeTreeNode> subtypes = const EmptyLink();
+ Link<PartialTypeTreeNode> subtypes = const Link();
for (Link link = current.children; !link.isEmpty(); link = link.tail) {
PartialTypeTreeNode child = link.head;
ClassElement childType = child.type;
@@ -107,7 +107,7 @@
PartialTypeTreeNode newNode = newNode(type);
if (!subtypes.isEmpty()) {
newNode.children = subtypes;
- Link<PartialTypeTreeNode> remaining = const EmptyLink();
+ Link<PartialTypeTreeNode> remaining = const Link();
for (Link link = current.children; !link.isEmpty(); link = link.tail) {
PartialTypeTreeNode child = link.head;
if (!child.type.isSubclassOf(type)) {
@@ -159,7 +159,7 @@
final ClassElement type;
Link<PartialTypeTreeNode> children;
- PartialTypeTreeNode(this.type) : children = const EmptyLink();
+ PartialTypeTreeNode(this.type) : children = const Link();
/**
* Visits this node and its children recursively. If the visit
@@ -174,4 +174,4 @@
return true;
}
-}
\ No newline at end of file
+}
diff --git a/lib/compiler/implementation/universe/selector_map.dart b/lib/compiler/implementation/universe/selector_map.dart
index 532acf8..148c86b 100644
--- a/lib/compiler/implementation/universe/selector_map.dart
+++ b/lib/compiler/implementation/universe/selector_map.dart
@@ -28,7 +28,8 @@
// No existing selectors with the given name. Create a new
// linked list.
SelectorValue<T> head = new SelectorValue<T>(selector, value);
- node.selectorsByName[selector.name] = new Link<SelectorValue<T>>(head);
+ node.selectorsByName[selector.name] =
+ new Link<SelectorValue<T>>().prepend(head);
} else {
// Run through the linked list of selectors with the same name. If
// we find one that matches, we update the value in the mapping.
diff --git a/lib/compiler/implementation/util/link.dart b/lib/compiler/implementation/util/link.dart
index cffc7e7..1029363 100644
--- a/lib/compiler/implementation/util/link.dart
+++ b/lib/compiler/implementation/util/link.dart
@@ -2,28 +2,60 @@
// 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.
-interface Link<T> extends Iterable<T> default LinkFactory<T> {
- final T head;
- final Link<T> tail;
+class Link<T> implements Iterable<T> {
+ T get head => null;
+ Link<T> get tail => null;
- Link(T head, [Link<T> tail]);
- Link.fromList(List<T> list);
+ factory Link.fromList(List<T> list) {
+ switch (list.length) {
+ case 0:
+ return new Link<T>();
+ case 1:
+ return new LinkEntry<T>(list[0]);
+ case 2:
+ return new LinkEntry<T>(list[0], new LinkEntry<T>(list[1]));
+ case 3:
+ return new LinkEntry<T>(
+ list[0], new LinkEntry<T>(list[1], new LinkEntry<T>(list[2])));
+ }
+ Link link = new Link<T>();
+ for (int i = list.length ; i > 0; i--) {
+ link = link.prepend(list[i - 1]);
+ }
+ return link;
+ }
- Link<T> prepend(T element);
- List<T> toList();
- bool isEmpty();
- Link<T> reverse();
- Link<T> reversePrependAll(Link<T> from);
+ const Link();
- void printOn(StringBuffer buffer, [separatedBy]);
+ Link<T> prepend(T element) {
+ // TODO(ahe): Use new Link<T>, but this cost 8% performance on VM.
+ return new LinkEntry<T>(element, this);
+ }
- void forEach(void f(T element));
+ Iterator<T> iterator() => new LinkIterator<T>(this);
- bool operator ==(other);
-}
+ void printOn(StringBuffer buffer, [separatedBy]) {
+ }
-interface EmptyLink<T> extends Link<T> default LinkTail<T> {
- const EmptyLink();
+ List toList() => new List<T>(0);
+
+ bool isEmpty() => true;
+
+ Link<T> reverse() => this;
+
+ Link<T> reversePrependAll(Link<T> from) {
+ if (from.isEmpty()) return this;
+ return this.prepend(from.head).reversePrependAll(from.tail);
+ }
+
+ void forEach(void f(T element)) {}
+
+ bool operator ==(other) {
+ if (other is !Link<T>) return false;
+ return other.isEmpty();
+ }
+
+ String toString() => "[]";
}
interface LinkBuilder<T> default LinkBuilderImplementation<T> {
diff --git a/lib/compiler/implementation/util/link_implementation.dart b/lib/compiler/implementation/util/link_implementation.dart
index a1f8492..82a8988 100644
--- a/lib/compiler/implementation/util/link_implementation.dart
+++ b/lib/compiler/implementation/util/link_implementation.dart
@@ -13,83 +13,18 @@
}
}
-class LinkFactory<T> {
- factory Link(T head, [Link<T> tail]) {
- if (tail === null) {
- tail = new LinkTail<T>();
- }
- return new LinkEntry<T>(head, tail);
- }
-
- factory Link.fromList(List<T> list) {
- switch (list.length) {
- case 0:
- return new LinkTail<T>();
- case 1:
- return new Link<T>(list[0]);
- case 2:
- return new Link<T>(list[0], new Link<T>(list[1]));
- case 3:
- return new Link<T>(list[0], new Link<T>(list[1], new Link<T>(list[2])));
- }
- Link link = new Link<T>(list.last());
- for (int i = list.length - 1; i > 0; i--) {
- link = link.prepend(list[i - 1]);
- }
- return link;
- }
-}
-
-class LinkTail<T> implements EmptyLink<T> {
- T get head => null;
- Link<T> get tail => null;
-
- const LinkTail();
-
- Link<T> prepend(T element) {
- // TODO(ahe): Use new Link<T>, but this cost 8% performance on VM.
- return new LinkEntry<T>(element, this);
- }
-
- Iterator<T> iterator() => new LinkIterator<T>(this);
-
- void printOn(StringBuffer buffer, [separatedBy]) {
- }
-
- String toString() => "[]";
-
- Link<T> reverse() => this;
-
- Link<T> reversePrependAll(Link<T> from) {
- if (from.isEmpty()) return this;
- return this.prepend(from.head).reversePrependAll(from.tail);
- }
-
- List toList() => const [];
-
- bool isEmpty() => true;
-
- void forEach(void f(T element)) {}
-
- bool operator ==(other) {
- if (other is !Link<T>) return false;
- return other.isEmpty();
- }
-}
-
-class LinkEntry<T> implements Link<T> {
+class LinkEntry<T> extends Link<T> {
final T head;
Link<T> tail;
- LinkEntry(T this.head, Link<T> this.tail);
+ LinkEntry(T this.head, [Link<T> tail])
+ : this.tail = ((tail == null) ? new Link<T>() : tail);
Link<T> prepend(T element) {
// TODO(ahe): Use new Link<T>, but this cost 8% performance on VM.
return new LinkEntry<T>(element, this);
}
- Iterator<T> iterator() => new LinkIterator<T>(this);
-
void printOn(StringBuffer buffer, [separatedBy]) {
buffer.add(head);
if (separatedBy === null) separatedBy = '';
@@ -108,7 +43,7 @@
}
Link<T> reverse() {
- Link<T> result = const LinkTail();
+ Link<T> result = const Link();
for (Link<T> link = this; !link.isEmpty(); link = link.tail) {
result = result.prepend(link.head);
}
@@ -162,8 +97,8 @@
LinkBuilderImplementation();
Link<T> toLink() {
- if (head === null) return const LinkTail();
- lastLink.tail = const LinkTail();
+ if (head === null) return const Link();
+ lastLink.tail = const Link();
Link<T> link = head;
lastLink = null;
head = null;
diff --git a/lib/html/scripts/generator.py b/lib/html/scripts/generator.py
index 937e345..da62d88 100644
--- a/lib/html/scripts/generator.py
+++ b/lib/html/scripts/generator.py
@@ -636,6 +636,12 @@
def has_generated_interface(self):
raise NotImplementedError()
+ def merged_interface(self):
+ return None
+
+ def merged_into(self):
+ return None
+
def native_type(self):
return self._data.native_type or self._idl_type
@@ -742,6 +748,26 @@
def has_generated_interface(self):
return True
+ def merged_interface(self):
+ # All constants, attributes, and operations of merged interface should be
+ # added to this interface. Merged idl interface does not have corresponding
+ # Dart generated interface, and all references to merged idl interface
+ # (e.g. parameter types, return types, parent interfaces) should be replaced
+ # with this interface. There are two important restrictions:
+ # 1) Merged and target interfaces shouldn't have common members, otherwise
+ # there would be duplicated declarations in generated Dart code.
+ # 2) Merged interface should be direct child of target interface, so the
+ # children of merged interface are not affected by the merge.
+ # As a consequence, target interface implementation and its direct children
+ # interface implementations should implement merged attribute accessors and
+ # operations. For example, SVGElement and Element implementation classes
+ # should implement HTMLElement.insertAdjacentElement(),
+ # HTMLElement.innerHTML, etc.
+ return self._data.merged_interface
+
+ def merged_into(self):
+ return self._data.merged_into
+
class CallbackIDLTypeInfo(IDLTypeInfo):
def __init__(self, idl_type, data):
@@ -904,6 +930,7 @@
class TypeData(object):
def __init__(self, clazz, dart_type=None, native_type=None,
+ merged_interface=None, merged_into=None,
custom_to_dart=None, custom_to_native=None,
conversion_includes=None,
webcore_getter_name='getAttribute',
@@ -913,6 +940,8 @@
self.clazz = clazz
self.dart_type = dart_type
self.native_type = native_type
+ self.merged_interface = merged_interface
+ self.merged_into = merged_into
self.custom_to_dart = custom_to_dart
self.custom_to_native = custom_to_native
self.conversion_includes = conversion_includes
@@ -978,10 +1007,14 @@
'DOMStringList': TypeData(clazz='Interface', dart_type='List<String>', custom_to_native=True),
'DOMStringMap': TypeData(clazz='Interface', dart_type='Map<String, String>'),
'DOMWindow': TypeData(clazz='Interface', custom_to_dart=True),
- 'Element': TypeData(clazz='Interface', custom_to_dart=True),
+ 'Document': TypeData(clazz='Interface', merged_interface='HTMLDocument'),
+ 'Element': TypeData(clazz='Interface', merged_interface='HTMLElement',
+ custom_to_dart=True),
'EventListener': TypeData(clazz='Interface', custom_to_native=True),
'EventTarget': TypeData(clazz='Interface', custom_to_native=True),
- 'HTMLElement': TypeData(clazz='Interface', custom_to_dart=True),
+ 'HTMLDocument': TypeData(clazz='Interface', merged_into='Document'),
+ 'HTMLElement': TypeData(clazz='Interface', merged_into='Element',
+ custom_to_dart=True),
'IDBAny': TypeData(clazz='Interface', dart_type='Dynamic', custom_to_native=True),
'IDBKey': TypeData(clazz='Interface', dart_type='Dynamic', custom_to_native=True),
'MutationRecordArray': TypeData(clazz='Interface', # C++ pass by pointer.
diff --git a/lib/html/scripts/systemhtml.py b/lib/html/scripts/systemhtml.py
index bedffc4..26fd788 100644
--- a/lib/html/scripts/systemhtml.py
+++ b/lib/html/scripts/systemhtml.py
@@ -35,23 +35,6 @@
'WheelEvent.wheelDeltaY',
])
-# This map controls merging of interfaces in dart:html library.
-# All constants, attributes, and operations of merged interface (key) are
-# added to target interface (value). All references to the merged interface
-# (e.g. parameter types, return types, parent interfaces) are replaced with
-# target interface. There are two important restrictions:
-# 1) Merged and target interfaces shouldn't have common members, otherwise there
-# would be duplicated declarations in generated Dart code.
-# 2) Merged interface should be direct child of target interface, so the
-# children of merged interface are not affected by the merge.
-# As a consequence, target interface implementation and its direct children
-# interface implementations should implement merged attribute accessors and
-# operations. For example, SVGElement and Element implementation classes should
-# implement HTMLElement.insertAdjacentElement(), HTMLElement.innerHTML, etc.
-_merged_html_interfaces = {
- 'HTMLDocument': 'Document',
- 'HTMLElement': 'Element'
-}
# Types that are accessible cross-frame in a limited fashion.
# In these cases, the base type (e.g., Window) provides restricted access
@@ -221,6 +204,7 @@
self._event_generator = event_generator
self._interface = interface
self._backend = backend
+ self._interface_type_info = self._type_registry.TypeInfo(self._interface.id)
self._html_interface_name = options.renamer.RenameInterface(self._interface)
def Generate(self):
@@ -243,9 +227,8 @@
self._backend.GenerateCallback(info)
def GenerateInterface(self):
- interface_type_info = self._type_registry.TypeInfo(self._interface.id)
- if (not self._interface.id in _merged_html_interfaces and
- interface_type_info.has_generated_interface()):
+ if (self._interface_type_info.has_generated_interface() and
+ not self._interface_type_info.merged_into()):
interface_emitter = self._library_emitter.FileEmitter(
self._html_interface_name)
else:
@@ -330,16 +313,7 @@
self._type_comment_emitter.Emit("/// @domName $DOMNAME",
DOMNAME=self._interface.doc_js_name)
- if self._backend.HasImplementation():
- if not self._interface.id in _merged_html_interfaces:
- name = self._html_interface_name
- basename = '%sImpl' % name
- else:
- basename = '%sImpl_Merged' % self._html_interface_name
- implementation_emitter = self._library_emitter.FileEmitter(basename)
- else:
- implementation_emitter = emitter.Emitter()
-
+ implementation_emitter = self._ImplementationEmitter()
base_class = self._backend.BaseClassName()
interface_type_info = self._type_registry.TypeInfo(self._interface.id)
implemented_interfaces = [interface_type_info.interface_name()] +\
@@ -383,10 +357,9 @@
old_backend = self._backend
if not self._backend.ImplementsMergedMembers():
self._backend = HtmlGeneratorDummyBackend()
- for merged_interface in _merged_html_interfaces:
- if _merged_html_interfaces[merged_interface] == self._interface.id:
- merged_interface = self._database.GetInterface(merged_interface)
- self.AddMembers(merged_interface)
+ merged_interface = self._interface_type_info.merged_interface()
+ if merged_interface:
+ self.AddMembers(self._database.GetInterface(merged_interface))
self._backend = old_backend
self.AddMembers(self._interface)
@@ -534,6 +507,20 @@
TYPE=type,
VALUE=constant.value)
+ def _ImplementationEmitter(self):
+ if IsPureInterface(self._interface.id):
+ return emitter.Emitter()
+
+ if not self._interface_type_info.merged_into():
+ name = self._html_interface_name
+ basename = '%sImpl' % name
+ else:
+ if self._backend.ImplementsMergedMembers():
+ # Merged members are implemented in target interface implementation.
+ return emitter.Emitter()
+ basename = '%sImpl_Merged' % self._html_interface_name
+ return self._library_emitter.FileEmitter(basename)
+
def _EmitEventGetter(self, events_interface, events_class):
self._members_emitter.Emit(
'\n /**'
@@ -599,13 +586,10 @@
self._database = options.database
self._template_loader = options.templates
self._type_registry = options.type_registry
+ self._interface_type_info = self._type_registry.TypeInfo(self._interface.id)
self._html_interface_name = options.renamer.RenameInterface(self._interface)
self._current_secondary_parent = None
- def HasImplementation(self):
- return not (IsPureInterface(self._interface.id) or
- self._interface.id in _merged_html_interfaces)
-
def ImplementationClassName(self):
return self._ImplClassName(self._html_interface_name)
@@ -737,7 +721,7 @@
# html_name. Two attributes with the same IDL name might not match if one
# is renamed.
(super_attribute, super_attribute_interface) = self._FindShadowedAttribute(
- attribute, _merged_html_interfaces)
+ attribute)
if super_attribute:
if read_only:
if attribute.type.id == super_attribute.type.id:
@@ -1059,7 +1043,7 @@
secure_name = SecureOutputType(self, type_name, True)
return self._NarrowToImplementationType(secure_name)
- def _FindShadowedAttribute(self, attr, merged_interfaces={}):
+ def _FindShadowedAttribute(self, attr):
"""Returns (attribute, superinterface) or (None, None)."""
def FindInParent(interface):
"""Returns matching attribute in parent, or None."""
@@ -1071,20 +1055,18 @@
return (None, None)
if self._database.HasInterface(parent.type.id):
interfaces_to_search_in = []
- if parent.type.id in merged_interfaces:
+ parent_interface_name = parent.type.id
+ interfaces_to_search_in.append(parent_interface_name)
+ parent_type_info = self._type_registry.TypeInfo(parent_interface_name)
+ if parent_type_info.merged_into():
# IDL parent was merged into another interface, which became a
# parent interface in Dart.
- interfaces_to_search_in.append(parent.type.id)
- parent_interface_name = merged_interfaces[parent.type.id]
- else:
- parent_interface_name = parent.type.id
+ parent_interface_name = parent_type_info.merged_into()
+ interfaces_to_search_in.append(parent_interface_name)
+ elif parent_type_info.merged_interface():
+ # IDL parent has another interface that was merged into it.
+ interfaces_to_search_in.append(parent_type_info.merged_interface())
- for interface_name in merged_interfaces:
- if merged_interfaces[interface_name] == parent_interface_name:
- # IDL parent has another interface that was merged into it.
- interfaces_to_search_in.append(interface_name)
-
- interfaces_to_search_in.append(parent_interface_name)
for interface_name in interfaces_to_search_in:
interface = self._database.GetInterface(interface_name)
attr2 = FindMatchingAttribute(interface, attr)
diff --git a/lib/html/scripts/systemnative.py b/lib/html/scripts/systemnative.py
index 0eeffb5..187a272 100644
--- a/lib/html/scripts/systemnative.py
+++ b/lib/html/scripts/systemnative.py
@@ -22,9 +22,6 @@
self._type_registry = options.type_registry
self._html_interface_name = options.renamer.RenameInterface(self._interface)
- def HasImplementation(self):
- return not IsPureInterface(self._interface.id)
-
def ImplementationClassName(self):
return self._ImplClassName(self._interface.id)
@@ -114,7 +111,7 @@
def StartInterface(self, memebers_emitter):
# Create emitters for c++ implementation.
- if self.HasImplementation():
+ if not IsPureInterface(self._interface.id):
self._cpp_header_emitter = self._cpp_library_emitter.CreateHeaderEmitter(self._interface.id)
self._cpp_impl_emitter = self._cpp_library_emitter.CreateSourceEmitter(self._interface.id)
else:
diff --git a/lib/isolate/timer.dart b/lib/isolate/timer.dart
index 76f98a1..a90c2d0 100644
--- a/lib/isolate/timer.dart
+++ b/lib/isolate/timer.dart
@@ -2,23 +2,35 @@
// 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.
-interface Timer default _TimerFactory {
+abstract class Timer {
/**
* Creates a new timer. The [callback] callback is invoked after
* [milliSeconds] milliseconds.
*/
- Timer(int milliSeconds, void callback(Timer timer));
+ factory Timer(int milliSeconds, void callback(Timer timer)) {
+ if (_factory == null) {
+ throw new UnsupportedOperationException("Timer interface not supported.");
+ }
+ return _factory(milliSeconds, callback, false);
+ }
/**
* Creates a new repeating timer. The [callback] is invoked every
* [milliSeconds] millisecond until cancelled.
*/
- Timer.repeating(int milliSeconds, void callback(Timer timer));
+ factory Timer.repeating(int milliSeconds, void callback(Timer timer)) {
+ if (_factory == null) {
+ throw new UnsupportedOperationException("Timer interface not supported.");
+ }
+ return _factory(milliSeconds, callback, true);
+ }
/**
* Cancels the timer.
*/
void cancel();
+
+ static _TimerFactoryClosure _factory;
}
// TODO(ajohnsen): Patch timer once we have support for patching named
@@ -28,26 +40,6 @@
void callback(Timer timer),
bool repeating);
-// _TimerFactory provides a hook which allows various implementations of this
-// library to provide a concrete class for the Timer interface.
-class _TimerFactory {
- factory Timer(int milliSeconds, void callback(Timer timer)) {
- if (_factory == null) {
- throw new UnsupportedOperationException("Timer interface not supported.");
- }
- return _factory(milliSeconds, callback, false);
- }
-
- factory Timer.repeating(int milliSeconds, void callback(Timer timer)) {
- if (_factory == null) {
- throw new UnsupportedOperationException("Timer interface not supported.");
- }
- return _factory(milliSeconds, callback, true);
- }
-
- static _TimerFactoryClosure _factory;
-}
-
void _setTimerFactoryClosure(_TimerFactoryClosure closure) {
- _TimerFactory._factory = closure;
+ Timer._factory = closure;
}
diff --git a/lib/scalarlist/byte_arrays.dart b/lib/scalarlist/byte_arrays.dart
index 81e3f24..cb3dd12 100644
--- a/lib/scalarlist/byte_arrays.dart
+++ b/lib/scalarlist/byte_arrays.dart
@@ -25,6 +25,7 @@
*/
int lengthInBytes();
+ // TODO(lrn): Change the signature to match String.substring.
/**
* Returns a [ByteArray] _view_ of a portion of this byte array.
* The returned byte array consists of [length] bytes starting
@@ -33,8 +34,8 @@
* changes to the returned byte array are visible in this byte array
* and vice-versa.
*
- * Throws [IndexOutOfRangeException] if [start] is negative, or if
- * `start + length` is greater than the length of this byte array.
+ * Throws [IndexOutOfRangeException] if [start] or [length] are negative, or
+ * if `start + length` is greater than the length of this byte array.
*
* Throws [ArgumentError] if [length] is negative.
*/
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index 45d808c..4aff04b 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -275,6 +275,7 @@
'libdart_vm',
'libjscre',
'libdouble_conversion',
+ 'generate_version_cc_file',
],
'include_dirs': [
'..',
@@ -284,6 +285,7 @@
'../include/dart_debugger_api.h',
'../vm/dart_api_impl.cc',
'../vm/debugger_api_impl.cc',
+ '<(version_cc_file)',
],
},
{
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 864fb6a..d4fe179 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -40,11 +40,6 @@
static bool use_script_snapshot = false;
static File* snapshot_file = NULL;
-
-// Global state that stores a file name for flow graph debugging output.
-// NULL if no output is generated.
-static File* flow_graph_file = NULL;
-
// Global state that indicates whether there is a debug breakpoint.
// This pointer points into an argv buffer and does not need to be
// free'd.
@@ -80,6 +75,16 @@
}
+static bool has_version_option = false;
+static bool ProcessVersionOption(const char* arg) {
+ if (*arg != '\0') {
+ return false;
+ }
+ has_version_option = true;
+ return true;
+}
+
+
static bool has_help_option = false;
static bool ProcessHelpOption(const char* arg) {
if (*arg != '\0') {
@@ -183,19 +188,12 @@
}
-static bool ProcessFlowGraphOption(const char* flowgraph_option) {
- ASSERT(flowgraph_option != NULL);
- flow_graph_file = File::Open("flowgraph.cfg", File::kWriteTruncate);
- ASSERT(flow_graph_file != NULL);
- return true;
-}
-
-
static struct {
const char* option_name;
bool (*process)(const char* option);
} main_options[] = {
// Standard options shared with dart2js.
+ { "--version", ProcessVersionOption },
{ "--help", ProcessHelpOption },
{ "-h", ProcessHelpOption },
{ "--verbose", ProcessVerboseOption },
@@ -206,7 +204,6 @@
{ "--break_at=", ProcessBreakpointOption },
{ "--compile_all", ProcessCompileAllOption },
{ "--debug", ProcessDebugOption },
- { "--generate_flow_graph", ProcessFlowGraphOption },
{ "--generate_perf_events_symbols", ProcessPerfEventsOption },
{ "--generate_pprof_symbols=", ProcessPprofOption },
{ "--use_script_snapshot=", ProcessScriptSnapshotOption },
@@ -235,12 +232,6 @@
}
-static void WriteToFlowGraphFile(const char* buffer, int64_t num_bytes) {
- ASSERT(flow_graph_file != NULL);
- flow_graph_file->WriteFully(buffer, num_bytes);
-}
-
-
// Parse out the command line arguments. Returns -1 if the arguments
// are incorrect, 0 otherwise.
static int ParseArguments(int argc,
@@ -287,10 +278,6 @@
Dart_InitPprofSupport();
}
- if (flow_graph_file != NULL) {
- Dart_InitFlowGraphPrinting(&WriteToFlowGraphFile);
- }
-
// Get the script name.
if (i < argc) {
*script_name = argv[i];
@@ -508,6 +495,11 @@
}
+static void PrintVersion() {
+ fprintf(stderr, "Dart VM version: %s\n", Dart_VersionString());
+}
+
+
static void PrintUsage() {
fprintf(stderr,
"Usage: dart [<vm-flags>] <dart-script-file> [<dart-options>]\n"
@@ -518,14 +510,18 @@
fprintf(stderr,
"Common options:\n"
"--checked Insert runtime type checks and enable assertions (checked mode).\n"
+"--version Print the VM version.\n"
"--help Display this message (add --verbose for information about all\n"
" VM options).\n");
} else {
fprintf(stderr,
"Supported options:\n"
-"--checked \n"
+"--checked\n"
" Insert runtime type checks and enable assertions (checked mode).\n"
"\n"
+"--version\n"
+" Print the VM version.\n"
+"\n"
"--help\n"
" Display this message (add --verbose for information about all VM options).\n"
"\n"
@@ -648,7 +644,13 @@
&script_name,
&dart_options,
&print_flags_seen) < 0) {
- if (print_flags_seen) {
+ if (has_help_option) {
+ PrintUsage();
+ return 0;
+ } else if (has_version_option) {
+ PrintVersion();
+ return 0;
+ } else if (print_flags_seen) {
// Will set the VM flags, print them out and then we exit as no
// script was specified on the command line.
Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
@@ -659,11 +661,6 @@
}
}
- if (has_help_option) {
- PrintUsage();
- return 0;
- }
-
Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
// Initialize the Dart VM.
diff --git a/runtime/dart-runtime.gyp b/runtime/dart-runtime.gyp
index a2d79e0..45548de 100644
--- a/runtime/dart-runtime.gyp
+++ b/runtime/dart-runtime.gyp
@@ -11,6 +11,10 @@
'tools/gyp/runtime-configurations.gypi',
'../tools/gyp/source_filter.gypi',
],
+ 'variables': {
+ 'version_in_cc_file': 'vm/version_in.cc',
+ 'version_cc_file': '<(SHARED_INTERMEDIATE_DIR)/version.cc',
+ },
'targets': [
{
'target_name': 'libdart',
@@ -20,6 +24,7 @@
'libdart_vm',
'libjscre',
'libdouble_conversion',
+ 'generate_version_cc_file',
],
'include_dirs': [
'.',
@@ -29,6 +34,8 @@
'include/dart_debugger_api.h',
'vm/dart_api_impl.cc',
'vm/debugger_api_impl.cc',
+ 'vm/version.h',
+ '<(version_cc_file)',
],
'direct_dependent_settings': {
'include_dirs': [
@@ -46,6 +53,7 @@
'libdart_vm',
'libjscre',
'libdouble_conversion',
+ 'generate_version_cc_file',
],
'include_dirs': [
'.',
@@ -55,6 +63,8 @@
'include/dart_debugger_api.h',
'vm/dart_api_impl.cc',
'vm/debugger_api_impl.cc',
+ 'vm/version.h',
+ '<(version_cc_file)',
],
'defines': [
'DART_SHARED_LIB',
@@ -65,5 +75,29 @@
],
},
},
+ {
+ 'target_name': 'generate_version_cc_file',
+ 'type': 'none',
+ 'actions': [
+ {
+ 'action_name': 'generate_version_cc',
+ 'inputs': [
+ 'tools/make_version.py',
+ '../tools/VERSION',
+ '<(version_in_cc_file)',
+ ],
+ 'outputs': [
+ '<(version_cc_file)',
+ ],
+ 'action': [
+ 'python',
+ 'tools/make_version.py',
+ '--output', '<(version_cc_file)',
+ '--input', '<(version_in_cc_file)',
+ '--version', '../tools/VERSION',
+ ],
+ },
+ ],
+ },
],
}
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index bf087c3..5490dfa 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -557,6 +557,15 @@
// --- Initialization and Globals ---
/**
+ * Gets the version string for the Dart VM.
+ *
+ * The version of the Dart VM can be accessed without initializing the VM.
+ *
+ * \return The version string for the embedded Dart VM.
+ */
+DART_EXPORT const char* Dart_VersionString();
+
+/**
* An isolate creation and initialization callback function.
*
* This callback, provided by the embedder, is called when the vm
@@ -1970,12 +1979,6 @@
int number_of_arguments,
Dart_Handle* arguments);
-// DEPRECATED: The API below is a temporary hack.
-DART_EXPORT int64_t Dart_ClosureSmrck(Dart_Handle object);
-
-// DEPRECATED: The API below is a temporary hack.
-DART_EXPORT void Dart_ClosureSetSmrck(Dart_Handle object, int64_t value);
-
// --- Classes and Interfaces ---
/**
@@ -2726,9 +2729,6 @@
// Support for generating symbol maps for use by the Linux perf tool.
DART_EXPORT void Dart_InitPerfEventsSupport(Dart_FileWriterFunction function);
-// Support for generating flow graph compiler debugging output into a file.
-DART_EXPORT void Dart_InitFlowGraphPrinting(Dart_FileWriterFunction function);
-
// --- Peers ---
/**
diff --git a/runtime/lib/byte_array.dart b/runtime/lib/byte_array.dart
index a6efae2..feadf0e 100644
--- a/runtime/lib/byte_array.dart
+++ b/runtime/lib/byte_array.dart
@@ -1513,8 +1513,11 @@
}
ByteArray subByteArray([int start = 0, int length]) {
+ if (start is! int) throw new ArgumentError("start is not an int");
if (length === null) {
- length = this.lengthInBytes();
+ length = this.lengthInBytes() - start;
+ } else if (length is! int) {
+ throw new ArgumentError("length is not an int");
}
return new _ByteArrayView(_array, _offset + start, length);
}
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 921368a..3c59c5c 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -398,10 +398,19 @@
DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 1) {
- GET_NATIVE_ARGUMENT(Closure, closure, arguments->At(0));
- const Function& func = Function::Handle(closure.function());
- const Class& cls = Class::Handle(func.Owner());
- if (!func.IsClosureFunction() || !func.is_static() || !cls.IsTopLevel()) {
+ GET_NATIVE_ARGUMENT(Instance, closure, arguments->At(0));
+ bool throw_exception = false;
+ Function& func = Function::Handle();
+ if (closure.IsClosure()) {
+ func ^= Closure::function(closure);
+ const Class& cls = Class::Handle(func.Owner());
+ if (!func.IsClosureFunction() || !func.is_static() || !cls.IsTopLevel()) {
+ throw_exception = true;
+ }
+ } else {
+ throw_exception = true;
+ }
+ if (throw_exception) {
const String& msg = String::Handle(String::New(
"spawnFunction expects to be passed a closure to a top-level static "
"function"));
@@ -409,7 +418,7 @@
}
#if defined(DEBUG)
- const Context& ctx = Context::Handle(closure.context());
+ const Context& ctx = Context::Handle(Closure::context(closure));
ASSERT(ctx.num_variables() == 0);
#endif
diff --git a/runtime/tools/make_version.py b/runtime/tools/make_version.py
new file mode 100644
index 0000000..73cfbe1
--- /dev/null
+++ b/runtime/tools/make_version.py
@@ -0,0 +1,100 @@
+# Copyright (c) 2011, 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.
+#
+# This python script creates a version string in a C++ file.
+
+import os
+import sys
+import subprocess
+import platform
+import getpass
+from os.path import join
+import time
+from optparse import OptionParser
+
+def getVersionPart(version_file, part):
+ proc = subprocess.Popen(['awk',
+ '$1 == "%s" {print $2}' % (part),
+ version_file],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ return proc.communicate()[0].split('\n')[0]
+
+def getRevision():
+ is_svn = True
+ if os.path.exists('.svn'):
+ cmd = ['svn', 'info']
+ else:
+ cmd = ['git', 'svn', 'info']
+ try:
+ proc = subprocess.Popen(cmd,
+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ return proc.communicate()[0].split('\n')[4].split(' ')[1]
+ except Exception:
+ # If we can't get any revision info (due to lack of tooling) return ''.
+ return ''
+
+
+def makeVersionString(version_file):
+ id = platform.system()
+ if id == 'Windows' or id == 'Microsoft':
+ return '0.0.0.0'
+ major = getVersionPart(version_file, 'MAJOR')
+ minor = getVersionPart(version_file, 'MINOR')
+ build = getVersionPart(version_file, 'BUILD')
+ patch = getVersionPart(version_file, 'PATCH')
+ revision = getRevision()
+ user = getpass.getuser()
+ return '%s.%s.%s.%s_%s_%s' % (major, minor, build, patch, revision, user)
+
+def makeFile(output_file, input_file, version_file):
+ version_cc_text = open(input_file).read()
+ version_cc_text = version_cc_text.replace("{{VERSION_STR}}",
+ makeVersionString(version_file))
+ version_cc_text = version_cc_text.replace("{{BUILD_TIME}}",
+ time.ctime(time.time()))
+ open(output_file, 'w').write(version_cc_text)
+ return True
+
+
+def main(args):
+ try:
+ # Parse input.
+ parser = OptionParser()
+ parser.add_option("--output",
+ action="store", type="string",
+ help="output file name")
+ parser.add_option("--input",
+ action="store", type="string",
+ help="input template file")
+ parser.add_option("--version",
+ action="store", type="string",
+ help="version file")
+
+ (options, args) = parser.parse_args()
+ if not options.output:
+ sys.stderr.write('--output not specified\n')
+ return -1
+ if not len(options.input):
+ sys.stderr.write('--input not specified\n')
+ return -1
+
+ files = [ ]
+ for arg in args:
+ files.append(arg)
+
+ if not makeFile(options.output,
+ options.input,
+ options.version):
+ return -1
+
+ return 0
+ except Exception, inst:
+ sys.stderr.write('make_version.py exception\n')
+ sys.stderr.write(str(inst))
+ sys.stderr.write('\n')
+ return -1
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/runtime/vm/assembler_macros_ia32.cc b/runtime/vm/assembler_macros_ia32.cc
index 58cf709..38ebf3e 100644
--- a/runtime/vm/assembler_macros_ia32.cc
+++ b/runtime/vm/assembler_macros_ia32.cc
@@ -64,20 +64,6 @@
}
-void AssemblerMacros::EnterDartLeafFrame(Assembler* assembler,
- intptr_t frame_size) {
- __ EnterFrame(0);
- Label dart_entry;
- // Leave room for the saved PC, it will be filled in lazily, leave
- // uninitialized.
- __ subl(ESP, Immediate(frame_size + kWordSize));
-#if defined(DEBUG)
- // Store an invalid object in saved PC slot.
- __ movl(Address(EBP, -kWordSize), Immediate(kHeapObjectTag));
-#endif
-}
-
-
void AssemblerMacros::EnterStubFrame(Assembler* assembler) {
__ EnterFrame(0);
__ pushl(Immediate(0)); // Push 0 in the saved PC area for stub frames.
diff --git a/runtime/vm/assembler_macros_ia32.h b/runtime/vm/assembler_macros_ia32.h
index ad3819b..4d185f9 100644
--- a/runtime/vm/assembler_macros_ia32.h
+++ b/runtime/vm/assembler_macros_ia32.h
@@ -50,8 +50,6 @@
// L: <code to adjust saved pc if there is any intrinsification code>
// .....
static void EnterDartFrame(Assembler* assembler, intptr_t frame_size);
- // Populates pc local slot lazily.
- static void EnterDartLeafFrame(Assembler* assembler, intptr_t frame_size);
// Set up a stub frame so that the stack traversal code can easily identify
// a stub frame.
diff --git a/runtime/vm/assembler_macros_x64.cc b/runtime/vm/assembler_macros_x64.cc
index fc01baf..0731cb5 100644
--- a/runtime/vm/assembler_macros_x64.cc
+++ b/runtime/vm/assembler_macros_x64.cc
@@ -67,20 +67,6 @@
}
-void AssemblerMacros::EnterDartLeafFrame(Assembler* assembler,
- intptr_t frame_size) {
- __ EnterFrame(0);
- Label dart_entry;
- // Leave room for the saved PC, it will be filled in lazily, leave
- // uninitialized.
- __ subq(RSP, Immediate(frame_size + kWordSize));
-#if defined(DEBUG)
- // Store an invalid object in saved PC slot.
- __ movq(Address(RBP, -kWordSize), Immediate(kHeapObjectTag));
-#endif
-}
-
-
void AssemblerMacros::EnterStubFrame(Assembler* assembler) {
__ EnterFrame(0);
__ pushq(Immediate(0)); // Push 0 in the saved PC area for stub frames.
diff --git a/runtime/vm/assembler_macros_x64.h b/runtime/vm/assembler_macros_x64.h
index acf5f71..a6912cf 100644
--- a/runtime/vm/assembler_macros_x64.h
+++ b/runtime/vm/assembler_macros_x64.h
@@ -50,8 +50,6 @@
// L: <code to adjust saved pc if there is any intrinsification code>
// .....
static void EnterDartFrame(Assembler* assembler, intptr_t frame_size);
- // Populates pc local slot lazily.
- static void EnterDartLeafFrame(Assembler* assembler, intptr_t frame_size);
// Set up a stub frame so that the stack traversal code can easily identify
// a stub frame.
diff --git a/runtime/vm/ast.cc b/runtime/vm/ast.cc
index 58f6935..b70119d 100644
--- a/runtime/vm/ast.cc
+++ b/runtime/vm/ast.cc
@@ -286,8 +286,8 @@
const Instance* ClosureNode::EvalConstExpr() const {
if (function().IsImplicitStaticClosureFunction()) {
- // Return a value that represents a closure. Only the type is relevant.
- return &Closure::Handle();
+ // Return a value that represents an instance. Only the type is relevant.
+ return &Instance::Handle();
}
return NULL;
}
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 7c2dd36..aace6ca 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -57,12 +57,14 @@
for (intptr_t i = 0; i < class_array.Length(); i++) {
cls ^= class_array.At(i);
if (FLAG_trace_class_finalization) {
- OS::Print("Resolving super and default: %s\n", cls.ToCString());
+ OS::Print("Resolving super and interfaces: %s\n", cls.ToCString());
}
ResolveSuperType(cls);
if (cls.is_interface()) {
ResolveFactoryClass(cls);
}
+ GrowableArray<intptr_t> visited_interfaces;
+ ResolveInterfaces(cls, &visited_interfaces);
}
// Finalize all classes.
for (intptr_t i = 0; i < class_array.Length(); i++) {
@@ -621,8 +623,6 @@
FinalizationKind finalization) {
ASSERT(arguments.Length() >= cls.NumTypeArguments());
if (!cls.is_finalized()) {
- GrowableArray<intptr_t> visited_interfaces;
- ResolveInterfaces(cls, &visited_interfaces);
FinalizeTypeParameters(cls);
}
Type& super_type = Type::Handle(cls.super_type());
@@ -730,8 +730,6 @@
// parameters of the type class must be finalized.
Class& type_class = Class::Handle(parameterized_type.type_class());
if (!type_class.is_finalized()) {
- GrowableArray<intptr_t> visited_interfaces;
- ResolveInterfaces(type_class, &visited_interfaces);
FinalizeTypeParameters(type_class);
}
@@ -1186,8 +1184,6 @@
"class '%s' has a cycle in its superclass relationship",
name.ToCString());
}
- GrowableArray<intptr_t> visited_interfaces;
- ResolveInterfaces(cls, &visited_interfaces);
// Finalize super class.
const Class& super_class = Class::Handle(cls.SuperClass());
if (!super_class.IsNull()) {
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index f8e7c37..61fc71b 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -279,8 +279,8 @@
// runtime.
const Context& context = Context::Handle(isolate->top_context());
ASSERT(!context.IsNull());
- const Closure& closure = Closure::Handle(Closure::New(function, context));
- closure.SetTypeArguments(type_arguments);
+ const Instance& closure = Instance::Handle(Closure::New(function, context));
+ Closure::SetTypeArguments(closure, type_arguments);
arguments.SetReturn(closure);
}
@@ -297,7 +297,7 @@
ASSERT(!function.IsNull());
ASSERT(function.IsImplicitStaticClosureFunction());
const Context& context = Context::Handle(object_store->empty_context());
- arguments.SetReturn(Closure::Handle(Closure::New(function, context)));
+ arguments.SetReturn(Instance::Handle(Closure::New(function, context)));
}
@@ -318,8 +318,8 @@
Context& context = Context::Handle();
context = Context::New(1);
context.SetAt(0, receiver);
- const Closure& closure = Closure::Handle(Closure::New(function, context));
- closure.SetTypeArguments(type_arguments);
+ const Instance& closure = Instance::Handle(Closure::New(function, context));
+ Closure::SetTypeArguments(closure, type_arguments);
arguments.SetReturn(closure);
}
@@ -1057,7 +1057,7 @@
const Instance& receiver = Instance::CheckedHandle(arguments.At(0));
const ICData& ic_data = ICData::CheckedHandle(arguments.At(1));
const String& original_function_name = String::Handle(ic_data.target_name());
- Closure& closure = Closure::Handle();
+ Instance& closure = Instance::Handle();
if (!Field::IsGetterName(original_function_name)) {
// This is not a getter so can't be the case where we are trying to
// create an implicit closure of an instance function.
@@ -1155,10 +1155,10 @@
DEFINE_RUNTIME_ENTRY(InvokeImplicitClosureFunction, 3) {
ASSERT(arguments.Count() ==
kInvokeImplicitClosureFunctionRuntimeEntry.argument_count());
- const Closure& closure = Closure::CheckedHandle(arguments.At(0));
+ const Instance& closure = Instance::CheckedHandle(arguments.At(0));
const Array& arg_descriptor = Array::CheckedHandle(arguments.At(1));
const Array& func_arguments = Array::CheckedHandle(arguments.At(2));
- const Function& function = Function::Handle(closure.function());
+ const Function& function = Function::Handle(Closure::function(closure));
ASSERT(!function.IsNull());
if (!function.HasCode()) {
const Error& error = Error::Handle(Compiler::CompileFunction(function));
@@ -1166,7 +1166,7 @@
Exceptions::PropagateError(error);
}
}
- const Context& context = Context::Handle(closure.context());
+ const Context& context = Context::Handle(Closure::context(closure));
const Code& code = Code::Handle(function.CurrentCode());
ASSERT(!code.IsNull());
const Instructions& instrs = Instructions::Handle(code.instructions());
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 188b16b..91bb459 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -165,11 +165,6 @@
FlowGraphPrinter printer(*flow_graph);
printer.PrintBlocks();
}
- if (Dart::flow_graph_writer() != NULL) {
- // Write flow graph to file.
- FlowGraphVisualizer printer(*flow_graph);
- printer.PrintFunction();
- }
if (optimized) {
flow_graph->ComputeUseLists();
@@ -244,17 +239,10 @@
}
}
- bool is_leaf = false;
- if (optimized) {
- FlowGraphAnalyzer analyzer(*flow_graph);
- analyzer.Analyze();
- is_leaf = analyzer.is_leaf();
- }
Assembler assembler;
FlowGraphCompiler graph_compiler(&assembler,
*flow_graph,
- optimized,
- is_leaf);
+ optimized);
{
TimerScope timer(FLAG_compiler_stats,
&CompilerStats::graphcompiler_timer,
@@ -266,7 +254,8 @@
&CompilerStats::codefinalizer_timer,
isolate);
const Function& function = parsed_function.function();
- const Code& code = Code::Handle(Code::FinalizeCode(function, &assembler));
+ const Code& code = Code::Handle(
+ Code::FinalizeCode(function, &assembler, optimized));
code.set_is_optimized(optimized);
graph_compiler.FinalizePcDescriptors(code);
graph_compiler.FinalizeDeoptInfo(code);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 332a3c6..0b8cdd4 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -28,6 +28,7 @@
#include "vm/timer.h"
#include "vm/unicode.h"
#include "vm/verifier.h"
+#include "vm/version.h"
namespace dart {
@@ -729,6 +730,9 @@
// --- Initialization and Globals ---
+DART_EXPORT const char* Dart_VersionString() {
+ return Version::String();
+}
DART_EXPORT bool Dart_Initialize(Dart_IsolateCreateCallback create,
Dart_IsolateInterruptCallback interrupt,
@@ -2380,21 +2384,22 @@
// different signature classes for closures.
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
- const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object));
- return obj.IsClosure();
+ const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, object);
+ return (!closure_obj.IsNull() && closure_obj.IsClosure());
}
DART_EXPORT Dart_Handle Dart_ClosureFunction(Dart_Handle closure) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
- const Closure& closure_obj = Api::UnwrapClosureHandle(isolate, closure);
- if (closure_obj.IsNull()) {
- RETURN_TYPE_ERROR(isolate, closure, Closure);
+ const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, closure);
+ if (closure_obj.IsNull() || !closure_obj.IsClosure()) {
+ RETURN_TYPE_ERROR(isolate, closure, Instance);
}
+
ASSERT(ClassFinalizer::AllClassesFinalized());
- RawFunction* rf = closure_obj.function();
+ RawFunction* rf = Closure::function(closure_obj);
return Api::NewHandle(isolate, rf);
}
@@ -2404,9 +2409,9 @@
Dart_Handle* arguments) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
- const Closure& closure_obj = Api::UnwrapClosureHandle(isolate, closure);
- if (closure_obj.IsNull()) {
- RETURN_TYPE_ERROR(isolate, closure, Closure);
+ const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, closure);
+ if (closure_obj.IsNull() || !closure_obj.IsClosure()) {
+ RETURN_TYPE_ERROR(isolate, closure, Instance);
}
if (number_of_arguments < 0) {
return Api::NewError(
@@ -2432,26 +2437,6 @@
}
-DART_EXPORT int64_t Dart_ClosureSmrck(Dart_Handle object) {
- Isolate* isolate = Isolate::Current();
- DARTSCOPE(isolate);
- const Closure& obj =
- Closure::CheckedHandle(isolate, Api::UnwrapHandle(object));
- const Integer& smrck = Integer::Handle(isolate, obj.smrck());
- return smrck.IsNull() ? 0 : smrck.AsInt64Value();
-}
-
-
-DART_EXPORT void Dart_ClosureSetSmrck(Dart_Handle object, int64_t value) {
- Isolate* isolate = Isolate::Current();
- DARTSCOPE(isolate);
- const Closure& obj =
- Closure::CheckedHandle(isolate, Api::UnwrapHandle(object));
- const Integer& smrck = Integer::Handle(isolate, Integer::New(value));
- obj.set_smrck(smrck);
-}
-
-
// --- Classes and Interfaces ---
@@ -4457,11 +4442,6 @@
}
-DART_EXPORT void Dart_InitFlowGraphPrinting(Dart_FileWriterFunction function) {
- Dart::set_flow_graph_writer(function);
-}
-
-
// --- Peer support ---
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index bc0a96a..476dd8c 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -83,15 +83,15 @@
RawObject* DartEntry::InvokeClosure(
- const Closure& closure,
+ const Instance& closure,
const GrowableArray<const Object*>& arguments,
const Array& optional_arguments_names) {
// Get the entrypoint corresponding to the closure specified, this
// will result in a compilation of the closure if it is not already
// compiled.
ASSERT(Class::Handle(closure.clazz()).signature_function() != Object::null());
- const Function& function = Function::Handle(closure.function());
- const Context& context = Context::Handle(closure.context());
+ const Function& function = Function::Handle(Closure::function(closure));
+ const Context& context = Context::Handle(Closure::context(closure));
ASSERT(!function.IsNull());
if (!function.HasCode()) {
const Error& error = Error::Handle(Compiler::CompileFunction(function));
diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h
index 2d26fe8..8e130dd 100644
--- a/runtime/vm/dart_entry.h
+++ b/runtime/vm/dart_entry.h
@@ -51,7 +51,7 @@
// Invoke the specified closure object.
// On success, returns a RawInstance. On failure, a RawError.
static RawObject* InvokeClosure(
- const Closure& closure,
+ const Instance& closure,
const GrowableArray<const Object*>& arguments,
const Array& optional_arguments_names);
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index c84d824..ad81e2f 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -139,8 +139,7 @@
FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler,
const FlowGraph& flow_graph,
- bool is_optimizing,
- bool is_leaf)
+ bool is_optimizing)
: assembler_(assembler),
parsed_function_(flow_graph.parsed_function()),
block_order_(flow_graph.reverse_postorder()),
@@ -153,7 +152,6 @@
deopt_infos_(),
object_table_(GrowableObjectArray::Handle(GrowableObjectArray::New())),
is_optimizing_(is_optimizing),
- is_dart_leaf_(is_leaf),
bool_true_(Bool::ZoneHandle(Bool::True())),
bool_false_(Bool::ZoneHandle(Bool::False())),
double_class_(Class::ZoneHandle(
@@ -173,13 +171,6 @@
}
-bool FlowGraphCompiler::IsLeaf() const {
- return is_dart_leaf_ &&
- !parsed_function_.function().IsClosureFunction() &&
- (parsed_function().num_copied_params() == 0);
-}
-
-
bool FlowGraphCompiler::HasFinally() const {
return parsed_function().function().has_finally();
}
@@ -482,7 +473,6 @@
const Array& argument_names,
intptr_t checked_argument_count,
LocationSummary* locs) {
- ASSERT(!IsLeaf());
ICData& ic_data =
ICData::ZoneHandle(ICData::New(parsed_function().function(),
function_name,
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index e4b3663..b5ce752 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -44,18 +44,6 @@
ASSERT(deoptimization_env() != NULL);
- if (compiler->IsLeaf()) {
- Label L;
- __ pushl(EAX); // Preserve EAX.
- __ call(&L);
- const intptr_t offset = assem->CodeSize();
- __ Bind(&L);
- __ popl(EAX);
- __ subl(EAX,
- Immediate(offset - AssemblerMacros::kOffsetOfSavedPCfromEntrypoint));
- __ movl(Address(EBP, -kWordSize), EAX);
- __ popl(EAX);
- }
__ call(&StubCode::DeoptimizeLabel());
set_pc_offset(assem->CodeSize());
#undef __
@@ -825,7 +813,6 @@
Isolate::kNoDeoptId,
0); // No token position.
} else {
- ASSERT(!IsLeaf());
// Invoke noSuchMethod function.
const int kNumArgsChecked = 1;
ICData& ic_data = ICData::ZoneHandle();
@@ -933,11 +920,7 @@
const int num_copied_params = parsed_function().num_copied_params();
const int num_locals = parsed_function().num_stack_locals();
__ Comment("Enter frame");
- if (IsLeaf()) {
- AssemblerMacros::EnterDartLeafFrame(assembler(), (StackSize() * kWordSize));
- } else {
- AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize));
- }
+ AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize));
// For optimized code, keep a bitmap of the frame in order to build
// stackmaps for GC safepoints in the prologue.
@@ -1041,7 +1024,6 @@
const ExternalLabel* label,
PcDescriptors::Kind kind,
LocationSummary* locs) {
- ASSERT(!IsLeaf());
__ call(label);
AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos);
RecordSafepoint(locs);
@@ -1053,7 +1035,6 @@
const ExternalLabel* label,
PcDescriptors::Kind kind,
LocationSummary* locs) {
- ASSERT(!IsLeaf());
__ call(label);
AddCurrentDescriptor(kind, deopt_id, token_pos);
RecordSafepoint(locs);
@@ -1074,7 +1055,6 @@
void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos,
const RuntimeEntry& entry,
LocationSummary* locs) {
- ASSERT(!IsLeaf());
__ CallRuntime(entry);
AddCurrentDescriptor(PcDescriptors::kOther, Isolate::kNoDeoptId, token_pos);
RecordSafepoint(locs);
@@ -1088,7 +1068,6 @@
intptr_t deopt_id,
intptr_t token_pos,
LocationSummary* locs) {
- ASSERT(!IsLeaf());
__ LoadObject(ECX, ic_data);
__ LoadObject(EDX, arguments_descriptor);
GenerateDartCall(deopt_id,
@@ -1106,7 +1085,6 @@
intptr_t deopt_id,
intptr_t token_pos,
LocationSummary* locs) {
- ASSERT(!IsLeaf());
__ LoadObject(ECX, function);
__ LoadObject(EDX, arguments_descriptor);
if (function.HasCode()) {
diff --git a/runtime/vm/flow_graph_compiler_ia32.h b/runtime/vm/flow_graph_compiler_ia32.h
index 57c3f55..b5d3043 100644
--- a/runtime/vm/flow_graph_compiler_ia32.h
+++ b/runtime/vm/flow_graph_compiler_ia32.h
@@ -27,8 +27,7 @@
public:
FlowGraphCompiler(Assembler* assembler,
const FlowGraph& flow_graph,
- bool is_optimizing,
- bool is_leaf);
+ bool is_optimizing);
~FlowGraphCompiler();
@@ -207,10 +206,6 @@
static const int kLocalsOffsetFromFP = (-1 * kWordSize);
- // Returns true if the generated code does not call other Dart code or
- // runtime. Only deoptimization is allowed to occur. Closures are not leaf.
- bool IsLeaf() const;
-
static Condition FlipCondition(Condition condition);
static bool EvaluateCondition(Condition condition, intptr_t l, intptr_t r);
@@ -311,7 +306,6 @@
GrowableArray<SlowPathCode*> slow_path_code_;
const GrowableObjectArray& object_table_;
const bool is_optimizing_;
- const bool is_dart_leaf_;
const Bool& bool_true_;
const Bool& bool_false_;
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index fea44cc..0c9e1aa 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -43,21 +43,6 @@
ASSERT(deoptimization_env() != NULL);
- if (compiler->IsLeaf()) {
- __ Comment("Leaf method, lazy PC marker setup");
- // TODO(srdjan): Can we use TMP instead of RAX? We must guarantee that
- // TMP is never part of deoptimization environment.
- __ pushq(RAX); // Preserve RAX.
- Label L;
- __ call(&L);
- const intptr_t offset = assem->CodeSize();
- __ Bind(&L);
- __ popq(RAX);
- __ subq(RAX,
- Immediate(offset - AssemblerMacros::kOffsetOfSavedPCfromEntrypoint));
- __ movq(Address(RBP, -kWordSize), RAX);
- __ popq(RAX); // Restore RAX.
- }
__ call(&StubCode::DeoptimizeLabel());
set_pc_offset(assem->CodeSize());
__ int3();
@@ -831,7 +816,6 @@
Isolate::kNoDeoptId,
0); // No token position.
} else {
- ASSERT(!IsLeaf());
// Invoke noSuchMethod function.
const int kNumArgsChecked = 1;
ICData& ic_data = ICData::ZoneHandle();
@@ -940,11 +924,7 @@
const int num_copied_params = parsed_function().num_copied_params();
const int num_locals = parsed_function().num_stack_locals();
__ Comment("Enter frame");
- if (IsLeaf()) {
- AssemblerMacros::EnterDartLeafFrame(assembler(), (StackSize() * kWordSize));
- } else {
- AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize));
- }
+ AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize));
// For optimized code, keep a bitmap of the frame in order to build
// stackmaps for GC safepoints in the prologue.
@@ -1049,7 +1029,6 @@
const ExternalLabel* label,
PcDescriptors::Kind kind,
LocationSummary* locs) {
- ASSERT(!IsLeaf());
__ call(label);
AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos);
RecordSafepoint(locs);
@@ -1061,7 +1040,6 @@
const ExternalLabel* label,
PcDescriptors::Kind kind,
LocationSummary* locs) {
- ASSERT(!IsLeaf());
__ call(label);
AddCurrentDescriptor(kind, deopt_id, token_pos);
RecordSafepoint(locs);
@@ -1082,7 +1060,6 @@
void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos,
const RuntimeEntry& entry,
LocationSummary* locs) {
- ASSERT(!IsLeaf());
__ CallRuntime(entry);
AddCurrentDescriptor(PcDescriptors::kOther, Isolate::kNoDeoptId, token_pos);
RecordSafepoint(locs);
@@ -1096,7 +1073,6 @@
intptr_t deopt_id,
intptr_t token_pos,
LocationSummary* locs) {
- ASSERT(!IsLeaf());
__ LoadObject(RBX, ic_data);
__ LoadObject(R10, arguments_descriptor);
GenerateDartCall(deopt_id,
@@ -1114,7 +1090,6 @@
intptr_t deopt_id,
intptr_t token_pos,
LocationSummary* locs) {
- ASSERT(!IsLeaf());
__ LoadObject(RBX, function);
__ LoadObject(R10, arguments_descriptor);
if (function.HasCode()) {
diff --git a/runtime/vm/flow_graph_compiler_x64.h b/runtime/vm/flow_graph_compiler_x64.h
index 3ae6bb6..d652a4e 100644
--- a/runtime/vm/flow_graph_compiler_x64.h
+++ b/runtime/vm/flow_graph_compiler_x64.h
@@ -27,8 +27,7 @@
public:
FlowGraphCompiler(Assembler* assembler,
const FlowGraph& flow_graph,
- bool is_optimizing,
- bool is_leaf);
+ bool is_optimizing);
~FlowGraphCompiler();
@@ -207,10 +206,6 @@
return current_block_->try_index();
}
- // Returns true if the generated code does not call other Dart code or
- // runtime. Only deoptimization is allowed to occur. Closures are not leaf.
- bool IsLeaf() const;
-
static Condition FlipCondition(Condition condition);
static bool EvaluateCondition(Condition condition, intptr_t l, intptr_t r);
@@ -311,7 +306,6 @@
GrowableArray<SlowPathCode*> slow_path_code_;
const GrowableObjectArray& object_table_;
const bool is_optimizing_;
- const bool is_dart_leaf_;
const Bool& bool_true_;
const Bool& bool_false_;
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index f48127b..5850c8d 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -1334,7 +1334,7 @@
for (Value* use = phi->input_use_list();
use != NULL;
use = use->next_use()) {
- PhiInstr* phi_use = use->definition()->AsPhi();
+ PhiInstr* phi_use = use->instruction()->AsPhi();
if ((phi_use != NULL) &&
(phi_use->GetPropagatedCid() == kDynamicCid) &&
IsPossiblySmiPhi(phi_use)) {
@@ -1353,7 +1353,7 @@
for (Value* use = phi->input_use_list();
use != NULL;
use = use->next_use()) {
- PhiInstr* phi_use = use->definition()->AsPhi();
+ PhiInstr* phi_use = use->instruction()->AsPhi();
if ((phi_use != NULL) && (phi_use->GetPropagatedCid() == kSmiCid)) {
AddToWorklist(phi_use);
}
@@ -2164,21 +2164,6 @@
}
-void FlowGraphAnalyzer::Analyze() {
- is_leaf_ = true;
- for (intptr_t i = 0; i < blocks_.length(); ++i) {
- BlockEntryInstr* entry = blocks_[i];
- for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
- LocationSummary* locs = it.Current()->locs();
- if ((locs != NULL) && locs->can_call()) {
- is_leaf_ = false;
- return;
- }
- }
- }
-}
-
-
static BlockEntryInstr* FindPreHeader(BlockEntryInstr* header) {
for (intptr_t j = 0; j < header->PredecessorCount(); ++j) {
BlockEntryInstr* candidate = header->PredecessorAt(j);
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index a6a32d2..1d5afe2 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -85,26 +85,6 @@
};
-// Analyze the generated flow graph. Currently only if it is a leaf
-// method, i.e., does not contain any calls to runtime or other Dart code.
-class FlowGraphAnalyzer : public ValueObject {
- public:
- explicit FlowGraphAnalyzer(const FlowGraph& flow_graph)
- : blocks_(flow_graph.reverse_postorder()), is_leaf_(false) {}
- virtual ~FlowGraphAnalyzer() {}
-
- void Analyze();
-
- bool is_leaf() const { return is_leaf_; }
-
- private:
- const GrowableArray<BlockEntryInstr*>& blocks_;
- bool is_leaf_;
-
- DISALLOW_COPY_AND_ASSIGN(FlowGraphAnalyzer);
-};
-
-
class ParsedFunction;
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index f41dba6..c847c2e 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -169,11 +169,6 @@
}
-void Instruction::PrintToVisualizer(BufferFormatter* f) const {
- PrintTo(f);
-}
-
-
void Definition::PrintTo(BufferFormatter* f) const {
PrintUse(f, *this);
if (is_used()) {
@@ -198,11 +193,6 @@
}
-void Definition::PrintToVisualizer(BufferFormatter* f) const {
- PrintTo(f);
-}
-
-
void Value::PrintTo(BufferFormatter* f) const {
PrintUse(f, *definition());
}
@@ -649,214 +639,6 @@
}
-void FlowGraphVisualizer::Print(const char* format, ...) {
- char str[1000];
- BufferFormatter f(str, sizeof(str));
- f.Print("%*s", static_cast<int>(2 * indent_), "");
- va_list args;
- va_start(args, format);
- f.VPrint(format, args);
- va_end(args);
- (*Dart::flow_graph_writer())(str, strlen(str));
-}
-
-
-void FlowGraphVisualizer::PrintInstruction(Instruction* instr) {
- char str[1000];
- BufferFormatter f(str, sizeof(str));
- instr->PrintToVisualizer(&f);
- if (FLAG_print_environments && (instr->env() != NULL)) {
- instr->env()->PrintTo(&f);
- }
- f.Print(" <|@\n");
- (*Dart::flow_graph_writer())(str, strlen(str));
-}
-
-
-void FlowGraphVisualizer::PrintFunction() {
-#define BEGIN(name) \
- Print("begin_%s\n", name); \
- indent_++;
-#define END(name) \
- Print("end_%s\n", name); \
- indent_--;
-
- {
- BEGIN("compilation");
- const char* name = function_.ToFullyQualifiedCString();
- Print("%s \"%s\"\n", "name", name);
- Print("%s \"%s\"\n", "method", name);
- Print("%s %d\n", "date", 0); // Required field. Unused.
- END("compilation");
- }
-
- {
- BEGIN("cfg");
- Print("%s \"%s\"\n", "name", "Flow graph builder");
-
- for (intptr_t i = 0; i < block_order_.length(); ++i) {
- BEGIN("block");
- BlockEntryInstr* entry = block_order_[i];
- Print("%s \"B%"Pd"\"\n", "name", entry->block_id());
- Print("%s %d\n", "from_bci", -1); // Required field. Unused.
- Print("%s %d\n", "to_bci", -1); // Required field. Unused.
-
- Print("predecessors");
- for (intptr_t j = 0; j < entry->PredecessorCount(); ++j) {
- BlockEntryInstr* pred = entry->PredecessorAt(j);
- Print(" \"B%"Pd"\"", pred->block_id());
- }
- Print("\n");
-
- Print("successors");
- Instruction* last = entry->last_instruction();
- for (intptr_t j = 0; j < last->SuccessorCount(); ++j) {
- intptr_t next_id = last->SuccessorAt(j)->block_id();
- Print(" \"B%"Pd"\"", next_id);
- }
- Print("\n");
-
- // TODO(fschneider): Use this for exception handlers.
- Print("xhandlers\n");
-
- // Can be freely used to mark blocks
- Print("flags\n");
-
- if (entry->dominator() != NULL) {
- Print("%s \"B%"Pd"\"\n", "dominator", entry->dominator()->block_id());
- }
-
- // TODO(fschneider): Mark blocks with loop nesting level.
- Print("%s %d\n", "loop_depth", 0);
-
- {
- BEGIN("states"); // Required section.
- {
- BEGIN("locals"); // Required section.
- JoinEntryInstr* join = entry->AsJoinEntry();
- intptr_t num_phis = (join != NULL && join->phi_count())
- ? join->phis()->length()
- : 0;
- Print("%s %"Pd"\n", "size", num_phis);
- for (intptr_t j = 0; j < num_phis; ++j) {
- PhiInstr* phi = (*join->phis())[j];
- if (phi != NULL) {
- Print("%"Pd" ", j); // Print variable index.
- char buffer[120];
- BufferFormatter formatter(buffer, sizeof(buffer));
- phi->PrintToVisualizer(&formatter);
- Print("%s\n", buffer);
- }
- }
- END("locals");
- }
- END("states");
- }
-
- {
- BEGIN("HIR");
- // Print the block entry.
- Print("0 0 "); // Required fields "bci" and "use". Unused.
- PrintInstruction(block_order_[i]);
- // And all the successors until an exit, branch, or a block entry.
- BlockEntryInstr* entry = block_order_[i];
- Instruction* current = entry;
- for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
- current = it.Current();
- Print("0 0 ");
- PrintInstruction(current);
- }
- if (current->next() != NULL) {
- ASSERT(current->next()->IsBlockEntry());
- Print("0 0 _ Goto B%"Pd" <|@\n",
- current->next()->AsBlockEntry()->block_id());
- }
- END("HIR");
- }
- END("block");
- }
- END("cfg");
- }
-#undef BEGIN
-#undef END
-}
-
-
-// === Printing instructions in a visualizer-understandable format:
-// "result instruction(op1, op2)" where result is a temporary name
-// or _ for instruction without result.
-void GraphEntryInstr::PrintToVisualizer(BufferFormatter* f) const {
- const GrowableArray<Definition*>& defns = initial_definitions_;
- f->Print("_ [graph]");
- if (defns.length() > 0) {
- f->Print(" init={ ");
- for (intptr_t i = 0; i < defns.length(); ++i) {
- if (i > 0) f->Print(", ");
- defns[i]->PrintTo(f);
- }
- f->Print(" }");
- }
-}
-
-
-void JoinEntryInstr::PrintToVisualizer(BufferFormatter* f) const {
- f->Print("_ [join]");
-}
-
-
-void PhiInstr::PrintToVisualizer(BufferFormatter* f) const {
- f->Print("v%"Pd" [", ssa_temp_index());
- for (intptr_t i = 0; i < InputCount(); ++i) {
- if (i > 0) f->Print(" ");
- InputAt(i)->PrintTo(f);
- }
- f->Print("]");
-}
-
-
-void ParameterInstr::PrintToVisualizer(BufferFormatter* f) const {
- ASSERT(HasSSATemp());
- ASSERT(temp_index() == -1);
- f->Print("v%"Pd" Parameter(%"Pd")", ssa_temp_index(), index());
-}
-
-
-void TargetEntryInstr::PrintToVisualizer(BufferFormatter* f) const {
- f->Print("_ [target");
- if (IsCatchEntry()) {
- f->Print(" catch %"Pd"]", catch_try_index());
- } else {
- f->Print("]");
- }
-}
-
-
-void PushArgumentInstr::PrintToVisualizer(BufferFormatter* f) const {
- f->Print("_ %s ", DebugName());
- value()->PrintTo(f);
-}
-
-
-void GotoInstr::PrintToVisualizer(BufferFormatter* f) const {
- f->Print("_ goto B%"Pd"", successor()->block_id());
-}
-
-
-void BranchInstr::PrintToVisualizer(BufferFormatter* f) const {
- f->Print("_ %s ", DebugName());
- f->Print("if ");
- comparison()->PrintTo(f);
- f->Print(" goto (B%"Pd", B%"Pd")",
- true_successor()->block_id(),
- false_successor()->block_id());
-}
-
-
-void ParallelMoveInstr::PrintToVisualizer(BufferFormatter* f) const {
- UNIMPLEMENTED();
-}
-
-
void Environment::PrintTo(BufferFormatter* f) const {
f->Print(" env={ ");
int arg_count = 0;
diff --git a/runtime/vm/il_printer.h b/runtime/vm/il_printer.h
index 2c62490..3da0191 100644
--- a/runtime/vm/il_printer.h
+++ b/runtime/vm/il_printer.h
@@ -60,28 +60,6 @@
const bool print_locations_;
};
-
-class FlowGraphVisualizer : public ValueObject {
- public:
- explicit FlowGraphVisualizer(const FlowGraph& flow_graph)
- : function_(flow_graph.parsed_function().function()),
- block_order_(flow_graph.reverse_postorder()),
- indent_(0) { }
-
- void PrintFunction();
-
- private:
- // Helpers for printing.
- void PrintInstruction(Instruction* instr);
- void Print(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
-
- const Function& function_;
- const GrowableArray<BlockEntryInstr*>& block_order_;
- intptr_t indent_;
-
- DISALLOW_COPY_AND_ASSIGN(FlowGraphVisualizer);
-};
-
} // namespace dart
#endif // VM_IL_PRINTER_H_
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index f4d8da7..c846045 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -409,7 +409,6 @@
// Printing support.
virtual void PrintTo(BufferFormatter* f) const;
virtual void PrintOperandsTo(BufferFormatter* f) const;
- virtual void PrintToVisualizer(BufferFormatter* f) const;
#define INSTRUCTION_TYPE_CHECK(type) \
bool Is##type() { return (As##type() != NULL); } \
@@ -651,7 +650,6 @@
intptr_t NumMoves() const { return moves_.length(); }
virtual void PrintTo(BufferFormatter* f) const;
- virtual void PrintToVisualizer(BufferFormatter* f) const;
private:
GrowableArray<MoveOperands*> moves_; // Elements cannot be null.
@@ -885,7 +883,6 @@
TargetEntryInstr* normal_entry() const { return normal_entry_; }
virtual void PrintTo(BufferFormatter* f) const;
- virtual void PrintToVisualizer(BufferFormatter* f) const;
private:
virtual void ClearPredecessors() { UNREACHABLE(); }
@@ -928,7 +925,6 @@
intptr_t phi_count() const { return phi_count_; }
virtual void PrintTo(BufferFormatter* f) const;
- virtual void PrintToVisualizer(BufferFormatter* f) const;
private:
friend class FlowGraph; // Access to predecessors_ when inlining.
@@ -1004,7 +1000,6 @@
virtual void PrepareEntry(FlowGraphCompiler* compiler);
virtual void PrintTo(BufferFormatter* f) const;
- virtual void PrintToVisualizer(BufferFormatter* f) const;
private:
virtual void ClearPredecessors() { predecessor_ = NULL; }
@@ -1107,7 +1102,6 @@
// formatting. Otherwise, it prints in the format "opcode(op1, op2, op3)".
virtual void PrintTo(BufferFormatter* f) const;
virtual void PrintOperandsTo(BufferFormatter* f) const;
- virtual void PrintToVisualizer(BufferFormatter* f) const;
// A value in the constant propagation lattice.
// - non-constant sentinel
@@ -1210,7 +1204,6 @@
DECLARE_INSTRUCTION(Phi)
virtual void PrintTo(BufferFormatter* f) const;
- virtual void PrintToVisualizer(BufferFormatter* f) const;
virtual bool InferRange(RangeOperator op);
@@ -1272,7 +1265,6 @@
}
virtual void PrintOperandsTo(BufferFormatter* f) const;
- virtual void PrintToVisualizer(BufferFormatter* f) const;
private:
const intptr_t index_;
@@ -1329,7 +1321,6 @@
virtual bool HasSideEffect() const { return false; }
virtual void PrintOperandsTo(BufferFormatter* f) const;
- virtual void PrintToVisualizer(BufferFormatter* f) const;
private:
Value* value_;
@@ -1442,7 +1433,6 @@
}
virtual void PrintTo(BufferFormatter* f) const;
- virtual void PrintToVisualizer(BufferFormatter* f) const;
private:
JoinEntryInstr* successor_;
@@ -1520,7 +1510,6 @@
}
virtual void PrintTo(BufferFormatter* f) const;
- virtual void PrintToVisualizer(BufferFormatter* f) const;
private:
ComparisonInstr* comparison_;
diff --git a/runtime/vm/intrinsifier.h b/runtime/vm/intrinsifier.h
index 3924bfd..9b4bc5b 100644
--- a/runtime/vm/intrinsifier.h
+++ b/runtime/vm/intrinsifier.h
@@ -87,6 +87,8 @@
V(_Uint32Array, [], Uint32Array_getIndexed) \
V(_Float32Array, [], Float32Array_getIndexed) \
V(_Float32Array, []=, Float32Array_setIndexed) \
+ V(_Float64Array, [], Float64Array_getIndexed) \
+ V(_Float64Array, []=, Float64Array_setIndexed) \
// Forward declarations.
class Assembler;
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index 6f4eb81..2c2e8d3 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -627,6 +627,54 @@
}
+bool Intrinsifier::Float64Array_getIndexed(Assembler* assembler) {
+ Label fall_through;
+ TestByteArrayIndex(assembler, &fall_through);
+ // After TestByteArrayIndex:
+ // * EAX has the base address of the byte array.
+ // * EBX has the index into the array.
+ // EBX contains the SMI index which is shifted left by 1.
+ // This shift means we only multiply the index by 4 not 8 (sizeof double).
+ // Load double precision float into XMM7.
+ __ movsd(XMM7, FieldAddress(EAX, EBX, TIMES_4,
+ Float64Array::data_offset()));
+ // Allocate a double instance.
+ const Class& double_class = Class::Handle(
+ Isolate::Current()->object_store()->double_class());
+ AssemblerMacros::TryAllocate(assembler,
+ double_class,
+ &fall_through,
+ Assembler::kNearJump, EAX);
+ // Store XMM7 into double instance.
+ __ movsd(FieldAddress(EAX, Double::value_offset()), XMM7);
+ __ ret();
+ __ Bind(&fall_through);
+ return false;
+}
+
+
+bool Intrinsifier::Float64Array_setIndexed(Assembler* assembler) {
+ Label fall_through;
+ __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Value.
+ // If EAX is not an instance of double, jump to fall through.
+ __ CompareClassId(EAX, kDoubleCid, EDI);
+ __ j(NOT_EQUAL, &fall_through);
+ // Load double value into XMM7.
+ __ movsd(XMM7, FieldAddress(EAX, Double::value_offset()));
+ TestByteArraySetIndex(assembler, &fall_through);
+ // After TestByteArraySetIndex:
+ // * EAX has the base address of the byte array.
+ // * EBX has the index into the array.
+ // EBX contains the SMI index which is shifted by 1.
+ // This shift means we only multiply the index by 4 not 8 (sizeof float).
+ // Store into array.
+ __ movsd(FieldAddress(EAX, EBX, TIMES_4, Float64Array::data_offset()), XMM7);
+ __ ret();
+ __ Bind(&fall_through);
+ return false;
+}
+
+
// Tests if two top most arguments are smis, jumps to label not_smi if not.
// Topmost argument is in EAX.
static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index 781cf4a..b3f7be7 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -585,6 +585,54 @@
}
+bool Intrinsifier::Float64Array_getIndexed(Assembler* assembler) {
+ Label fall_through;
+ TestByteArrayIndex(assembler, &fall_through);
+ // After TestByteArrayIndex:
+ // * RAX has the base address of the byte array.
+ // * R12 has the index into the array.
+ // R12 contains the SMI index which is shifted left by 1.
+ // This shift means we only multiply the index by 4 not 8 (sizeof double).
+ // Load double precision float into XMM7.
+ __ movsd(XMM7, FieldAddress(RAX, R12, TIMES_4,
+ Float64Array::data_offset()));
+ // Allocate a double instance.
+ const Class& double_class = Class::Handle(
+ Isolate::Current()->object_store()->double_class());
+ AssemblerMacros::TryAllocate(assembler,
+ double_class,
+ &fall_through,
+ Assembler::kNearJump, RAX);
+ // Store XMM7 into double instance.
+ __ movsd(FieldAddress(RAX, Double::value_offset()), XMM7);
+ __ ret();
+ __ Bind(&fall_through);
+ return false;
+}
+
+
+bool Intrinsifier::Float64Array_setIndexed(Assembler* assembler) {
+ Label fall_through;
+ TestByteArraySetIndex(assembler, &fall_through);
+ // After TestByteArraySetIndex:
+ // * RAX has the base address of the byte array.
+ // * R12 has the index into the array.
+ // R12 contains the SMI index which is shifted by 1.
+ // This shift means we only multiply the index by 4 not 8 (sizeof double).
+ __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value.
+ // If RDX is not an instance of double, jump to fall through.
+ __ CompareClassId(RDX, kDoubleCid);
+ __ j(NOT_EQUAL, &fall_through);
+ // Load double value into XMM7.
+ __ movsd(XMM7, FieldAddress(RDX, Double::value_offset()));
+ // Store into array.
+ __ movsd(FieldAddress(RAX, R12, TIMES_4, Float64Array::data_offset()), XMM7);
+ __ ret();
+ __ Bind(&fall_through);
+ return false;
+}
+
+
// Tests if two top most arguments are smis, jumps to label not_smi if not.
// Topmost argument is in RAX.
static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index adf5d90..bf300c7 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1345,8 +1345,7 @@
result.set_handle_vtable(fake.vtable());
result.set_instance_size(FakeObject::InstanceSize());
result.set_next_field_offset(FakeObject::InstanceSize());
- ASSERT((FakeObject::kClassId != kInstanceCid) &&
- (FakeObject::kClassId != kClosureCid));
+ ASSERT((FakeObject::kClassId != kInstanceCid));
result.set_id(FakeObject::kClassId);
result.raw_ptr()->state_bits_ = 0;
// VM backed classes are almost ready: run checks and resolve class
@@ -1778,10 +1777,6 @@
}
-// Force instantiation of template version to work around ld problems.
-template RawClass* Class::New<Closure>(intptr_t index);
-
-
template <class FakeInstance>
RawClass* Class::New(const String& name,
const Script& script,
@@ -1827,10 +1822,12 @@
type_parameters = owner_class.type_parameters();
}
const intptr_t token_pos = signature_function.token_pos();
- Class& result = Class::Handle(New<Closure>(name, script, token_pos));
+ Class& result = Class::Handle(New<Instance>(name, script, token_pos));
const Type& super_type = Type::Handle(Type::ObjectType());
const Array& empty_array = Array::Handle(Object::empty_array());
ASSERT(!super_type.IsNull());
+ result.set_instance_size(Closure::InstanceSize());
+ result.set_next_field_offset(Closure::InstanceSize());
result.set_super_type(super_type);
result.set_signature_function(signature_function);
result.set_type_parameters(type_parameters);
@@ -3142,7 +3139,7 @@
if (!IsFactory() || (raw_ptr()->data_ == Object::null())) {
return false;
}
- ASSERT(!IsClosure()); // A factory cannot also be a closure.
+ ASSERT(!IsClosureFunction()); // A factory cannot also be a closure.
return true;
}
@@ -6980,7 +6977,9 @@
}
-RawCode* Code::FinalizeCode(const char* name, Assembler* assembler) {
+RawCode* Code::FinalizeCode(const char* name,
+ Assembler* assembler,
+ bool optimized) {
ASSERT(assembler != NULL);
// Allocate the Instructions object.
@@ -6994,12 +6993,13 @@
assembler->FinalizeInstructions(region);
Dart_FileWriterFunction perf_events_writer = Dart::perf_events_writer();
if (perf_events_writer != NULL) {
- const char* format = "%"Px" %"Px" %s\n";
+ const char* format = "%"Px" %"Px" %s%s\n";
uword addr = instrs.EntryPoint();
uword size = instrs.size();
- intptr_t len = OS::SNPrint(NULL, 0, format, addr, size, name);
+ const char* marker = optimized ? "*" : "";
+ intptr_t len = OS::SNPrint(NULL, 0, format, addr, size, marker, name);
char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
- OS::SNPrint(buffer, len + 1, format, addr, size, name);
+ OS::SNPrint(buffer, len + 1, format, addr, size, marker, name);
(*perf_events_writer)(buffer, len);
}
DebugInfo* pprof_symbol_generator = Dart::pprof_symbol_generator();
@@ -7058,12 +7058,16 @@
}
-RawCode* Code::FinalizeCode(const Function& function, Assembler* assembler) {
+RawCode* Code::FinalizeCode(const Function& function,
+ Assembler* assembler,
+ bool optimized) {
// Calling ToFullyQualifiedCString is very expensive, try to avoid it.
if (FLAG_generate_gdb_symbols ||
Dart::perf_events_writer() != NULL ||
Dart::pprof_symbol_generator() != NULL) {
- return FinalizeCode(function.ToFullyQualifiedCString(), assembler);
+ return FinalizeCode(function.ToFullyQualifiedCString(),
+ assembler,
+ optimized);
} else {
return FinalizeCode("", assembler);
}
@@ -8113,6 +8117,12 @@
}
+bool Instance::IsClosure() const {
+ const Class& cls = Class::Handle(clazz());
+ return cls.IsSignatureClass();
+}
+
+
RawInstance* Instance::New(const Class& cls, Heap::Space space) {
Instance& result = Instance::Handle();
{
@@ -8151,8 +8161,11 @@
// Can occur when running disassembler.
return "Instance";
} else {
+ if (IsClosure()) {
+ return Closure::ToCString(*this);
+ }
const char* kFormat = "Instance of '%s'";
- Class& cls = Class::Handle(clazz());
+ const Class& cls = Class::Handle(clazz());
AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle();
const intptr_t num_type_arguments = cls.NumTypeArguments();
if (num_type_arguments > 0) {
@@ -11887,43 +11900,8 @@
}
-
-RawClosure* Closure::New(const Function& function,
- const Context& context,
- Heap::Space space) {
- Isolate* isolate = Isolate::Current();
- ASSERT(context.isolate() == isolate);
-
- const Class& cls = Class::Handle(function.signature_class());
- Closure& result = Closure::Handle();
- {
- RawObject* raw = Object::Allocate(cls.id(), Closure::InstanceSize(), space);
- NoGCScope no_gc;
- result ^= raw;
- }
- result.set_function(function);
- result.set_context(context);
- return result.raw();
-}
-
-
-void Closure::set_context(const Context& value) const {
- StorePointer(&raw_ptr()->context_, value.raw());
-}
-
-
-void Closure::set_function(const Function& value) const {
- StorePointer(&raw_ptr()->function_, value.raw());
-}
-
-
-const char* DartFunction::ToCString() const {
- return "Function type class";
-}
-
-
-const char* Closure::ToCString() const {
- const Function& fun = Function::Handle(function());
+const char* Closure::ToCString(const Instance& closure) {
+ const Function& fun = Function::Handle(Closure::function(closure));
const bool is_implicit_closure = fun.IsImplicitClosureFunction();
const char* fun_sig = String::Handle(fun.Signature()).ToCString();
const char* from = is_implicit_closure ? " from " : "";
@@ -11936,6 +11914,31 @@
}
+RawInstance* Closure::New(const Function& function,
+ const Context& context,
+ Heap::Space space) {
+ Isolate* isolate = Isolate::Current();
+ ASSERT(context.isolate() == isolate);
+
+ const Class& cls = Class::Handle(function.signature_class());
+ ASSERT(cls.instance_size() == Closure::InstanceSize());
+ Instance& result = Instance::Handle();
+ {
+ RawObject* raw = Object::Allocate(cls.id(), Closure::InstanceSize(), space);
+ NoGCScope no_gc;
+ result ^= raw;
+ }
+ Closure::set_function(result, function);
+ Closure::set_context(result, context);
+ return result.raw();
+}
+
+
+const char* DartFunction::ToCString() const {
+ return "Function type class";
+}
+
+
intptr_t Stacktrace::Length() const {
const Array& code_array = Array::Handle(raw_ptr()->code_array_);
return code_array.Length();
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 1fbca5a..8413fc6 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -27,6 +27,7 @@
#undef DEFINE_FORWARD_DECLARATION
class Api;
class Assembler;
+class Closure;
class Code;
class LocalScope;
class Symbols;
@@ -421,6 +422,7 @@
friend void ClassTable::Register(const Class& cls);
friend void RawObject::Validate(Isolate* isolate) const;
+ friend class Closure;
friend class SnapshotReader;
// Disallow allocation.
@@ -2495,8 +2497,12 @@
ASSERT(0 <= len && len <= kMaxElements);
return RoundedAllocationSize(sizeof(RawCode) + (len * kBytesPerElement));
}
- static RawCode* FinalizeCode(const Function& function, Assembler* assembler);
- static RawCode* FinalizeCode(const char* name, Assembler* assembler);
+ static RawCode* FinalizeCode(const Function& function,
+ Assembler* assembler,
+ bool optimized = false);
+ static RawCode* FinalizeCode(const char* name,
+ Assembler* assembler,
+ bool optimized = false);
static RawCode* LookupCode(uword pc);
int32_t GetPointerOffsetAt(int index) const {
@@ -3005,6 +3011,9 @@
*NativeFieldAddr(index) = value;
}
+ // Returns true if the instance is a closure object.
+ bool IsClosure() const;
+
static intptr_t InstanceSize() {
return RoundedAllocationSize(sizeof(RawInstance));
}
@@ -3033,6 +3042,7 @@
// TODO(iposva): Determine if this gets in the way of Smi.
HEAP_OBJECT_IMPLEMENTATION(Instance, Object);
friend class Class;
+ friend class Closure;
};
@@ -5451,46 +5461,75 @@
};
-class Closure : public Instance {
+class Closure : public AllStatic {
public:
- RawFunction* function() const { return raw_ptr()->function_; }
+ static RawFunction* function(const Instance& closure) {
+ return *FunctionAddr(closure);
+ }
static intptr_t function_offset() {
- return OFFSET_OF(RawClosure, function_);
+ return static_cast<intptr_t>(kFunctionOffset * kWordSize);
}
- RawContext* context() const { return raw_ptr()->context_; }
- static intptr_t context_offset() { return OFFSET_OF(RawClosure, context_); }
-
- virtual RawAbstractTypeArguments* GetTypeArguments() const {
- return raw_ptr()->type_arguments_;
+ static RawContext* context(const Instance& closure) {
+ return *ContextAddr(closure);
}
- virtual void SetTypeArguments(const AbstractTypeArguments& value) const {
- StorePointer(&raw_ptr()->type_arguments_, value.raw());
+ static intptr_t context_offset() {
+ return static_cast<intptr_t>(kContextOffset * kWordSize);
+ }
+
+ static RawAbstractTypeArguments* GetTypeArguments(const Instance& closure) {
+ return *TypeArgumentsAddr(closure);
+ }
+ static void SetTypeArguments(const Instance& closure,
+ const AbstractTypeArguments& value) {
+ closure.StorePointer(TypeArgumentsAddr(closure), value.raw());
}
static intptr_t type_arguments_offset() {
- return OFFSET_OF(RawClosure, type_arguments_);
+ return static_cast<intptr_t>(kTypeArgumentsOffset * kWordSize);
}
- // TODO(iposva): Remove smrck support once mapping to arbitrary is available.
- RawInteger* smrck() const { return raw_ptr()->smrck_; }
- void set_smrck(const Integer& smrck) const {
- StorePointer(&raw_ptr()->smrck_, smrck.raw());
- }
- static intptr_t smrck_offset() { return OFFSET_OF(RawClosure, smrck_); }
+ static const char* ToCString(const Instance& closure);
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawClosure));
+ intptr_t size = sizeof(RawInstance) + (kNumFields * kWordSize);
+ ASSERT(size == Object::RoundedAllocationSize(size));
+ return size;
}
- static RawClosure* New(const Function& function,
- const Context& context,
- Heap::Space space = Heap::kNew);
+ static RawInstance* New(const Function& function,
+ const Context& context,
+ Heap::Space space = Heap::kNew);
private:
- void set_function(const Function& value) const;
- void set_context(const Context& value) const;
+ static const int kTypeArgumentsOffset = 1;
+ static const int kFunctionOffset = 2;
+ static const int kContextOffset = 3;
+ static const int kNumFields = 3;
- HEAP_OBJECT_IMPLEMENTATION(Closure, Instance);
+ static RawAbstractTypeArguments** TypeArgumentsAddr(const Instance& obj) {
+ ASSERT(obj.IsClosure());
+ return reinterpret_cast<RawAbstractTypeArguments**>(
+ reinterpret_cast<intptr_t>(obj.raw_ptr()) + type_arguments_offset());
+ }
+ static RawFunction** FunctionAddr(const Instance& obj) {
+ ASSERT(obj.IsClosure());
+ return reinterpret_cast<RawFunction**>(
+ reinterpret_cast<intptr_t>(obj.raw_ptr()) + function_offset());
+ }
+ static RawContext** ContextAddr(const Instance& obj) {
+ ASSERT(obj.IsClosure());
+ return reinterpret_cast<RawContext**>(
+ reinterpret_cast<intptr_t>(obj.raw_ptr()) + context_offset());
+ }
+ static void set_function(const Instance& closure,
+ const Function& value) {
+ closure.StorePointer(FunctionAddr(closure), value.raw());
+ }
+ static void set_context(const Instance& closure,
+ const Context& value) {
+ closure.StorePointer(ContextAddr(closure), value.raw());
+ }
+
friend class Class;
};
@@ -5681,11 +5720,7 @@
#endif
set_vtable(builtin_vtables_[cid]);
} else {
-#if !defined(DEBUG)
- Isolate* isolate = Isolate::Current();
-#endif
- RawClass* raw_class = isolate->class_table()->At(cid);
- set_vtable(raw_class->ptr()->handle_vtable_);
+ set_vtable(builtin_vtables_[kInstanceCid]);
}
}
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index e63c0bd..6bcf17c 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -2338,7 +2338,7 @@
function = Function::NewClosureFunction(function_name, parent, 0);
const Class& signature_class = Class::Handle(
Class::NewSignatureClass(function_name, function, script));
- const Closure& closure = Closure::Handle(Closure::New(function, context));
+ const Instance& closure = Instance::Handle(Closure::New(function, context));
const Class& closure_class = Class::Handle(closure.clazz());
EXPECT(closure_class.IsSignatureClass());
EXPECT(closure_class.IsCanonicalSignatureClass());
@@ -2346,7 +2346,7 @@
const Function& signature_function =
Function::Handle(signature_class.signature_function());
EXPECT_EQ(signature_function.raw(), function.raw());
- const Context& closure_context = Context::Handle(closure.context());
+ const Context& closure_context = Context::Handle(Closure::context(closure));
EXPECT_EQ(closure_context.raw(), closure_context.raw());
}
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 57ac4d9..2d41d74 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -286,14 +286,8 @@
break;
}
} else {
- RawClass* raw_class = visitor->isolate()->class_table()->At(class_id);
- if (Class::IsSignatureClass(raw_class)) {
- RawClosure* raw_obj = reinterpret_cast<RawClosure*>(this);
- size = RawClosure::VisitClosurePointers(raw_obj, visitor);
- } else {
- RawInstance* raw_obj = reinterpret_cast<RawInstance*>(this);
- size = RawInstance::VisitInstancePointers(raw_obj, visitor);
- }
+ RawInstance* raw_obj = reinterpret_cast<RawInstance*>(this);
+ size = RawInstance::VisitInstancePointers(raw_obj, visitor);
}
ASSERT(size != 0);
@@ -964,15 +958,6 @@
}
-intptr_t RawClosure::VisitClosurePointers(RawClosure* raw_obj,
- ObjectPointerVisitor* visitor) {
- // Make sure that we got here with the tagged pointer as this.
- ASSERT(raw_obj->IsHeapObject());
- visitor->VisitPointers(raw_obj->from(), raw_obj->to());
- return Closure::InstanceSize();
-}
-
-
intptr_t RawStacktrace::VisitStacktracePointers(RawStacktrace* raw_obj,
ObjectPointerVisitor* visitor) {
// Make sure that we got here with the tagged pointer as this.
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 8dffb94..89f3c7b 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -92,7 +92,6 @@
V(JSRegExp) \
V(WeakProperty) \
V(DartFunction) \
- V(Closure) \
#define CLASS_LIST(V) \
V(Object) \
@@ -1433,21 +1432,6 @@
};
-class RawClosure : public RawInstance {
- RAW_HEAP_OBJECT_IMPLEMENTATION(Closure);
-
- RawObject** from() {
- return reinterpret_cast<RawObject**>(&ptr()->type_arguments_);
- }
- RawAbstractTypeArguments* type_arguments_;
- RawFunction* function_;
- RawContext* context_;
- // TODO(iposva): Remove this temporary hack.
- RawInteger* smrck_;
- RawObject** to() { return reinterpret_cast<RawObject**>(&ptr()->smrck_); }
-};
-
-
// VM type for capturing stacktraces when exceptions are thrown,
// Currently we don't have any interface that this object is supposed
// to implement so we just support the 'toString' method which
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 0f4c529..55a8e97 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -39,21 +39,16 @@
(kind == Snapshot::kScript && !RawObject::IsCreatedFromSnapshot(tags))) {
// Read in the base information.
intptr_t class_id = reader->ReadIntptrValue();
- bool is_signature_class = reader->Read<bool>();
// Allocate class object of specified kind.
if (kind == Snapshot::kFull) {
- cls = reader->NewClass(class_id, is_signature_class);
+ cls = reader->NewClass(class_id);
} else {
if (class_id < kNumPredefinedCids) {
ASSERT((class_id >= kInstanceCid) && (class_id <= kDartFunctionCid));
cls = reader->isolate()->class_table()->At(class_id);
} else {
- if (is_signature_class) {
- cls = New<Closure>(kIllegalCid);
- } else {
- cls = New<Instance>(kIllegalCid);
- }
+ cls = New<Instance>(kIllegalCid);
}
}
reader->AddBackRef(object_id, &cls, kIsDeserialized);
@@ -101,7 +96,6 @@
// Write out all the non object pointer fields.
// NOTE: cpp_vtable_ is not written.
writer->WriteIntptrValue(ptr()->id_);
- writer->Write<bool>(Class::IsSignatureClass(this) ? true : false);
writer->WriteIntptrValue(ptr()->instance_size_);
writer->WriteIntptrValue(ptr()->type_arguments_instance_field_offset_);
writer->WriteIntptrValue(ptr()->next_field_offset_);
@@ -2206,22 +2200,6 @@
}
-RawClosure* Closure::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind) {
- UNIMPLEMENTED();
- return Closure::null();
-}
-
-
-void RawClosure::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind) {
- UNIMPLEMENTED();
-}
-
-
RawStacktrace* Stacktrace::ReadFrom(SnapshotReader* reader,
intptr_t object_id,
intptr_t tags,
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 5f6f4b7..12aad9e 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -434,7 +434,7 @@
}
-RawClass* SnapshotReader::NewClass(intptr_t class_id, bool is_signature_class) {
+RawClass* SnapshotReader::NewClass(intptr_t class_id) {
ASSERT(kind_ == Snapshot::kFull);
ASSERT(isolate()->no_gc_scope_depth() != 0);
if (class_id < kNumPredefinedCids) {
@@ -444,13 +444,8 @@
cls_ = Object::class_class();
RawClass* obj = reinterpret_cast<RawClass*>(
AllocateUninitialized(cls_, Class::InstanceSize()));
- if (is_signature_class) {
- Closure fake;
- obj->ptr()->handle_vtable_ = fake.vtable();
- } else {
- Instance fake;
- obj->ptr()->handle_vtable_ = fake.vtable();
- }
+ Instance fake;
+ obj->ptr()->handle_vtable_ = fake.vtable();
cls_ = obj;
cls_.set_id(kIllegalCid);
isolate()->class_table()->Register(cls_);
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 205824d..44c19fe 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -243,7 +243,7 @@
RawTypeArguments* NewTypeArguments(intptr_t len);
RawTokenStream* NewTokenStream(intptr_t len);
RawContext* NewContext(intptr_t num_variables);
- RawClass* NewClass(intptr_t class_id, bool is_signature_class);
+ RawClass* NewClass(intptr_t class_id);
RawMint* NewMint(int64_t value);
RawBigint* NewBigint(const char* hex_string);
RawDouble* NewDouble(double value);
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 56f8c02..6f59c3e 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1376,7 +1376,7 @@
uword tags = 0;
tags = RawObject::SizeTag::update(closure_size, tags);
tags = RawObject::ClassIdTag::update(cls.id(), tags);
- __ movl(Address(EAX, Closure::tags_offset()), Immediate(tags));
+ __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags));
// Initialize the function field in the object.
// EAX: new closure object.
@@ -1427,8 +1427,6 @@
__ movl(EDX, Address(ESP, kTypeArgumentsOffset));
__ movl(Address(EAX, Closure::type_arguments_offset()), EDX);
- __ movl(Address(EAX, Closure::smrck_offset()), raw_null);
-
// Done allocating and initializing the instance.
// EAX: new object.
__ addl(EAX, Immediate(kHeapObjectTag));
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 6d21c43..1e81cfe 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -1358,7 +1358,7 @@
uword tags = 0;
tags = RawObject::SizeTag::update(closure_size, tags);
tags = RawObject::ClassIdTag::update(cls.id(), tags);
- __ movq(Address(RAX, Closure::tags_offset()), Immediate(tags));
+ __ movq(Address(RAX, Instance::tags_offset()), Immediate(tags));
// Initialize the function field in the object.
// RAX: new closure object.
@@ -1410,8 +1410,6 @@
__ movq(R10, Address(RSP, kTypeArgumentsOffset));
__ movq(Address(RAX, Closure::type_arguments_offset()), R10);
- __ movq(Address(RAX, Closure::smrck_offset()), raw_null);
-
// Done allocating and initializing the instance.
// RAX: new object.
__ addq(RAX, Immediate(kHeapObjectTag));
diff --git a/runtime/vm/version.h b/runtime/vm/version.h
new file mode 100644
index 0000000..dee350b
--- /dev/null
+++ b/runtime/vm/version.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2012, 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 VM_VERSION_H_
+#define VM_VERSION_H_
+
+#include "vm/allocation.h"
+
+namespace dart {
+
+class Version : public AllStatic {
+ public:
+ static const char* String() { return str_; }
+
+ private:
+ static const char* str_;
+};
+
+} // namespace dart
+
+#endif // VM_VERSION_H_
diff --git a/runtime/vm/version_in.cc b/runtime/vm/version_in.cc
new file mode 100644
index 0000000..d479d9f
--- /dev/null
+++ b/runtime/vm/version_in.cc
@@ -0,0 +1,11 @@
+// Copyright (c) 2012, 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.
+
+#include "vm/version.h"
+
+namespace dart {
+
+const char* Version::str_ = "{{VERSION_STR}} ({{BUILD_TIME}})";
+
+} // namespace dart
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index e649ec4..a15d037 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -5,79 +5,7 @@
[ $compiler == dart2dart ]
LibTest/isolate/isolate_api/port_A01_t01: Skip # Times out.
-Language/10_Expressions/01_Constants_A05_t03: Fail # TRIAGE
-Language/10_Expressions/05_Strings/1_String_Interpolation_A01_t04: Fail # TRIAGE
-Language/10_Expressions/05_Strings/1_String_Interpolation_A01_t05: Fail # TRIAGE
-Language/10_Expressions/05_Strings/1_String_Interpolation_A01_t06: Fail # TRIAGE
-Language/10_Expressions/11_Instance_Creation/1_New_A06_t06: Fail # TRIAGE
-Language/10_Expressions/11_Instance_Creation/1_New_A07_t01: Fail # TRIAGE
-Language/10_Expressions/11_Instance_Creation/1_New_A11_t01: Fail # TRIAGE
-Language/10_Expressions/11_Instance_Creation/1_New_A12_t01: Fail # TRIAGE
-Language/10_Expressions/11_Instance_Creation/1_New_A12_t02: Fail # TRIAGE
Language/10_Expressions/11_Instance_Creation/1_New_A13_t02: Fail # TRIAGE
-Language/10_Expressions/11_Instance_Creation/1_New_A13_t04: Fail # TRIAGE
-Language/10_Expressions/11_Instance_Creation/1_New_A14_t01: Fail # TRIAGE
-Language/10_Expressions/13_Property_Extraction_A01_t01: Fail # TRIAGE
-Language/10_Expressions/19_Conditional_A01_t10: Fail # TRIAGE
-Language/10_Expressions/19_Conditional_A01_t11: Fail # TRIAGE
-Language/10_Expressions/19_Conditional_A01_t12: Fail # TRIAGE
-Language/10_Expressions/19_Conditional_A01_t13: Fail # TRIAGE
-Language/10_Expressions/19_Conditional_A01_t14: Fail # TRIAGE
-Language/10_Expressions/19_Conditional_A01_t15: Fail # TRIAGE
-Language/10_Expressions/20_Logical_Boolean_Expressions_A01_t11: Fail # TRIAGE
-Language/10_Expressions/20_Logical_Boolean_Expressions_A01_t13: Fail # TRIAGE
-Language/10_Expressions/20_Logical_Boolean_Expressions_A01_t14: Fail # TRIAGE
-Language/10_Expressions/21_Bitwise_Expressions_A01_t13: Fail # TRIAGE
-Language/10_Expressions/21_Bitwise_Expressions_A01_t15: Fail # TRIAGE
-Language/10_Expressions/21_Bitwise_Expressions_A01_t16: Fail # TRIAGE
-Language/10_Expressions/21_Bitwise_Expressions_A01_t17: Fail # TRIAGE
-Language/10_Expressions/21_Relational_Expressions_A01_t19: Fail # TRIAGE
-Language/10_Expressions/21_Relational_Expressions_A01_t21: Fail # TRIAGE
-Language/10_Expressions/21_Relational_Expressions_A01_t22: Fail # TRIAGE
-Language/10_Expressions/21_Relational_Expressions_A01_t23: Fail # TRIAGE
-Language/10_Expressions/22_Equality_A01_t23: Fail # TRIAGE
-Language/10_Expressions/22_Equality_A01_t24: Fail # TRIAGE
-Language/10_Expressions/22_Equality_A03_t02: Fail # TRIAGE
-Language/10_Expressions/22_Shift_A01_t10: Fail # TRIAGE
-Language/10_Expressions/22_Shift_A01_t12: Fail # TRIAGE
-Language/10_Expressions/22_Shift_A01_t13: Fail # TRIAGE
-Language/10_Expressions/22_Shift_A01_t14: Fail # TRIAGE
-Language/10_Expressions/23_Additive_Expressions_A01_t08: Fail # TRIAGE
-Language/10_Expressions/23_Additive_Expressions_A01_t11: Fail # TRIAGE
-Language/10_Expressions/23_Additive_Expressions_A01_t12: Fail # TRIAGE
-Language/10_Expressions/23_Additive_Expressions_A01_t13: Fail # TRIAGE
-Language/10_Expressions/23_Additive_Expressions_A01_t14: Fail # TRIAGE
-Language/10_Expressions/24_Multiplicative_Expressions_A01_t11: Fail # TRIAGE
-Language/10_Expressions/24_Multiplicative_Expressions_A01_t14: Fail # TRIAGE
-Language/10_Expressions/24_Multiplicative_Expressions_A01_t15: Fail # TRIAGE
-Language/10_Expressions/24_Multiplicative_Expressions_A01_t16: Fail # TRIAGE
-Language/10_Expressions/24_Multiplicative_Expressions_A01_t17: Fail # TRIAGE
-Language/10_Expressions/25_Unary_Expressions_A01_t02: Fail # TRIAGE
-Language/10_Expressions/25_Unary_Expressions_A01_t04: Fail # TRIAGE
-Language/10_Expressions/25_Unary_Expressions_A01_t05: Fail # TRIAGE
-Language/10_Expressions/25_Unary_Expressions_A01_t17: Fail # TRIAGE
-Language/10_Expressions/25_Unary_Expressions_A01_t18: Fail # TRIAGE
-Language/10_Expressions/25_Unary_Expressions_A01_t19: Fail # TRIAGE
-Language/10_Expressions/25_Unary_Expressions_A01_t20: Fail # TRIAGE
-Language/10_Expressions/25_Unary_Expressions_A01_t21: Fail # TRIAGE
-Language/10_Expressions/25_Unary_Expressions_A01_t22: Fail # TRIAGE
-Language/10_Expressions/26_Postfix_Expressions_A01_t02: Fail # TRIAGE
-Language/10_Expressions/26_Postfix_Expressions_A01_t03: Fail # TRIAGE
-Language/10_Expressions/26_Postfix_Expressions_A01_t05: Fail # TRIAGE
-Language/10_Expressions/27_Assignable_Expressions_A01_t06: Fail # TRIAGE
-Language/10_Expressions/27_Assignable_Expressions_A01_t08: Fail # TRIAGE
-Language/10_Expressions/27_Assignable_Expressions_A01_t09: Fail # TRIAGE
-Language/10_Expressions/28_Identifier_Reference_A04_t01: Fail # TRIAGE
-Language/10_Expressions/28_Identifier_Reference_A04_t03: Fail # TRIAGE
-Language/10_Expressions/28_Identifier_Reference_A04_t06: Fail # TRIAGE
-Language/10_Expressions/29_Type_Test_A01_t04: Fail # TRIAGE
-Language/13_Libraries_and_Scripts/2_Imports_A01_t49: Fail # TRIAGE
-Language/13_Libraries_and_Scripts/2_Imports_A02_t12: Fail # TRIAGE
-Language/13_Libraries_and_Scripts/2_Imports_A02_t13: Fail # TRIAGE
-Language/13_Libraries_and_Scripts/2_Imports_A02_t15: Fail # TRIAGE
-Language/13_Libraries_and_Scripts/2_Imports_A02_t19: Fail # TRIAGE
-
-Language/10_Expressions/05_Strings_A12_t01: Fail # TRIAGE
Language/03_Overview/1_Scoping_A01_t39: Fail # http://dartbug.com/5519
Language/03_Overview/1_Scoping_A01_t40: Fail # http://dartbug.com/5519
@@ -257,6 +185,7 @@
Language/10_Expressions/01_Constants_A03_t05: Fail # http://dartbug.com/5519
Language/10_Expressions/01_Constants_A05_t01: Fail # inherited from VM
Language/10_Expressions/01_Constants_A05_t02: Fail # http://dartbug.com/5519
+Language/10_Expressions/01_Constants_A05_t03: Fail # http://dartbug.com/5810
Language/10_Expressions/01_Constants_A05_t04: Fail # http://dartbug.com/5519
Language/10_Expressions/01_Constants_A06_t01: Fail # inherited from VM
Language/10_Expressions/01_Constants_A08_t02: Fail # http://dartbug.com/5519
@@ -301,6 +230,9 @@
Language/10_Expressions/01_Constants_A19_t02: Fail # inherited from VM
Language/10_Expressions/01_Constants_A19_t03: Fail # inherited from VM
Language/10_Expressions/01_Constants_A19_t04: Fail # http://dartbug.com/5519
+Language/10_Expressions/05_Strings/1_String_Interpolation_A01_t04: Fail # Inherited from dart2js
+Language/10_Expressions/05_Strings/1_String_Interpolation_A01_t05: Fail # Inherited from dart2js
+Language/10_Expressions/05_Strings/1_String_Interpolation_A01_t06: Fail # Inherited from dart2js
Language/10_Expressions/05_Strings/1_String_Interpolation_A01_t09: Fail, OK # co19 issue 210
Language/10_Expressions/05_Strings/1_String_Interpolation_A03_t02: Fail # inherited from VM
Language/10_Expressions/05_Strings/1_String_Interpolation_A04_t02: Fail # inherited from VM
@@ -314,6 +246,7 @@
Language/10_Expressions/05_Strings_A02_t47: Fail # inherited from VM
Language/10_Expressions/05_Strings_A02_t48: Fail # inherited from VM
Language/10_Expressions/05_Strings_A02_t49: Fail # inherited from VM
+Language/10_Expressions/05_Strings_A12_t01: Fail # Inherited from dart2js
Language/10_Expressions/05_Strings_A20_t01: Fail # inherited from VM
Language/10_Expressions/06_Lists_A03_t01: Fail # http://dartbug.com/5519
Language/10_Expressions/06_Lists_A03_t02: Fail # http://dartbug.com/5519
@@ -335,11 +268,19 @@
Language/10_Expressions/11_Instance_Creation/1_New_A02_t05: Fail # inherited from dart2js
Language/10_Expressions/11_Instance_Creation/1_New_A02_t06: Fail # inherited from dart2js
Language/10_Expressions/11_Instance_Creation/1_New_A02_t07: Fail # inherited from dart2js
+Language/10_Expressions/11_Instance_Creation/1_New_A06_t06: Fail # Inherited from dart2js
+Language/10_Expressions/11_Instance_Creation/1_New_A07_t01: Fail # Inherited from dart2js
Language/10_Expressions/11_Instance_Creation/1_New_A09_t09: Fail # inherited from VM
+Language/10_Expressions/11_Instance_Creation/1_New_A11_t01: Fail # Inherited from VM
+Language/10_Expressions/11_Instance_Creation/1_New_A12_t01: Fail # co19 issue 255: unmatched bracket (same behavior in dart2js)
+Language/10_Expressions/11_Instance_Creation/1_New_A12_t02: Fail # Inherited from VM
+Language/10_Expressions/11_Instance_Creation/1_New_A13_t04: Fail # Inherited from VM
+Language/10_Expressions/11_Instance_Creation/1_New_A14_t01: Fail # Inherited from dart2js
Language/10_Expressions/11_Instance_Creation/2_Const_A01_t02: Fail # http://dartbug.com/5519
Language/10_Expressions/11_Instance_Creation/2_Const_A06_t01: Fail # http://dartbug.com/5519
Language/10_Expressions/11_Instance_Creation/2_Const_A06_t02: Fail # http://dartbug.com/5519
Language/10_Expressions/11_Instance_Creation/2_Const_A10_t01: Fail # inherited from VM
+Language/10_Expressions/13_Property_Extraction_A01_t01: Fail # co19 issue 255: unmatched bracket (same behavior in dart2js)
Language/10_Expressions/14_Function_Invocation/2_Binding_Actuals_to_Formals_A04_t01: Fail # http://dartbug.com/5519
Language/10_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t03: Fail # inherited from VM
Language/10_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t04: Fail # co19 issue 166
@@ -365,12 +306,12 @@
Language/10_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t04: Fail # co19 issue 251 or issue 5732
Language/10_Expressions/15_Method_Invocation/4_Super_Invocation_A03_t02: Fail # co19 issue 251 or issue 5732
Language/10_Expressions/15_Method_Invocation/4_Super_Invocation_A03_t03: Fail # co19 issue 251 or issue 5732
-Language/10_Expressions/15_Method_Invocation/4_Super_Invocation_A07_t01: Fail # co19 issue 251 or issue 5732
-Language/10_Expressions/15_Method_Invocation/4_Super_Invocation_A08_t02: Fail # co19 issue 251 or issue 5732
Language/10_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t01: Fail # inherited from VM
Language/10_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t02: Fail # inherited from VM
Language/10_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t03: Fail # inherited from VM
Language/10_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t04: Fail # inherited from VM
+Language/10_Expressions/15_Method_Invocation/4_Super_Invocation_A07_t01: Fail # co19 issue 251 or issue 5732
+Language/10_Expressions/15_Method_Invocation/4_Super_Invocation_A08_t02: Fail # co19 issue 251 or issue 5732
Language/10_Expressions/17_Getter_Invocation_A01_t03: Fail # inherited from VM
Language/10_Expressions/17_Getter_Invocation_A02_t01: Fail # inherited from VM
Language/10_Expressions/17_Getter_Invocation_A02_t02: Fail # inherited from VM
@@ -378,34 +319,86 @@
Language/10_Expressions/18_Assignment_A05_t04: Fail # inherited from VM
Language/10_Expressions/18_Assignment_A05_t05: Fail # inherited from VM
Language/10_Expressions/18_Assignment_A08_t04: Fail # inherited from VM
+Language/10_Expressions/19_Conditional_A01_t10: Fail # Inherited from dart2js
+Language/10_Expressions/19_Conditional_A01_t11: Fail # Inherited from dart2js
+Language/10_Expressions/19_Conditional_A01_t12: Fail # Inherited from dart2js
+Language/10_Expressions/19_Conditional_A01_t13: Fail # Inherited from dart2js
+Language/10_Expressions/19_Conditional_A01_t14: Fail # Inherited from dart2js
+Language/10_Expressions/19_Conditional_A01_t15: Fail # Inherited from dart2js
Language/10_Expressions/20_Logical_Boolean_Expressions_A01_t01: Fail # inherited from VM
+Language/10_Expressions/20_Logical_Boolean_Expressions_A01_t11: Fail # Inherited from dart2js
Language/10_Expressions/20_Logical_Boolean_Expressions_A01_t12: Fail # http://dartbug.com/5519
+Language/10_Expressions/20_Logical_Boolean_Expressions_A01_t13: Fail # Inherited from dart2js
+Language/10_Expressions/20_Logical_Boolean_Expressions_A01_t14: Fail # Inherited from dart2js
Language/10_Expressions/21_Bitwise_Expressions_A01_t01: Fail # inherited from VM
+Language/10_Expressions/21_Bitwise_Expressions_A01_t13: Fail # Inherited from dart2js
Language/10_Expressions/21_Bitwise_Expressions_A01_t14: Fail # http://dartbug.com/5519
-Language/10_Expressions/22_Equality_A01_t01: Fail # inherited from VM
-Language/10_Expressions/22_Equality_A01_t15: Fail # http://dartbug.com/5519
-Language/10_Expressions/22_Equality_A01_t16: Fail # http://dartbug.com/5519
-Language/10_Expressions/22_Equality_A01_t19: Fail # http://dartbug.com/5519
-Language/10_Expressions/22_Equality_A02_t03: Fail # inherited from VM
-Language/10_Expressions/22_Equality_A03_t01: Fail # inherited from VM
-Language/10_Expressions/22_Equality_A03_t03: Fail # inherited from VM
-Language/10_Expressions/22_Equality_A05_t01: Fail # inherited from VM
+Language/10_Expressions/21_Bitwise_Expressions_A01_t15: Fail # Inherited from dart2js
+Language/10_Expressions/21_Bitwise_Expressions_A01_t16: Fail # Inherited from dart2js
+Language/10_Expressions/21_Bitwise_Expressions_A01_t17: Fail # Inherited from dart2js
Language/10_Expressions/21_Relational_Expressions_A01_t01: Fail # inherited from VM
Language/10_Expressions/21_Relational_Expressions_A01_t10: Fail # http://dartbug.com/5519
Language/10_Expressions/21_Relational_Expressions_A01_t11: Fail # http://dartbug.com/5519
Language/10_Expressions/21_Relational_Expressions_A01_t12: Fail # http://dartbug.com/5519
Language/10_Expressions/21_Relational_Expressions_A01_t13: Fail # http://dartbug.com/5519
+Language/10_Expressions/21_Relational_Expressions_A01_t19: Fail # Inherited from dart2js
Language/10_Expressions/21_Relational_Expressions_A01_t20: Fail # http://dartbug.com/5519
+Language/10_Expressions/21_Relational_Expressions_A01_t21: Fail # Inherited from dart2js
+Language/10_Expressions/21_Relational_Expressions_A01_t22: Fail # Inherited from dart2js
+Language/10_Expressions/21_Relational_Expressions_A01_t23: Fail # Inherited from dart2js
+Language/10_Expressions/22_Equality_A01_t01: Fail # inherited from VM
+Language/10_Expressions/22_Equality_A01_t15: Fail # http://dartbug.com/5519
+Language/10_Expressions/22_Equality_A01_t16: Fail # http://dartbug.com/5519
+Language/10_Expressions/22_Equality_A01_t19: Fail # http://dartbug.com/5519
+Language/10_Expressions/22_Equality_A01_t23: Fail # Inherited from dart2js
+Language/10_Expressions/22_Equality_A01_t24: Fail # Inherited from dart2js
+Language/10_Expressions/22_Equality_A02_t03: Fail # inherited from VM
+Language/10_Expressions/22_Equality_A03_t01: Fail # inherited from VM
+Language/10_Expressions/22_Equality_A03_t02: Fail # Inherited from dart2js
+Language/10_Expressions/22_Equality_A03_t03: Fail # inherited from VM
+Language/10_Expressions/22_Equality_A05_t01: Fail # inherited from VM
Language/10_Expressions/22_Shift_A01_t01: Fail # inherited from VM
+Language/10_Expressions/22_Shift_A01_t10: Fail # Inherited from dart2js
Language/10_Expressions/22_Shift_A01_t11: Fail # http://dartbug.com/5519
+Language/10_Expressions/22_Shift_A01_t12: Fail # Inherited from dart2js
+Language/10_Expressions/22_Shift_A01_t13: Fail # Inherited from dart2js
+Language/10_Expressions/22_Shift_A01_t14: Fail # Inherited from dart2js
+Language/10_Expressions/23_Additive_Expressions_A01_t08: Fail # Inherited from dart2js
+Language/10_Expressions/23_Additive_Expressions_A01_t11: Fail # Inherited from dart2js
+Language/10_Expressions/23_Additive_Expressions_A01_t12: Fail # Inherited from dart2js
+Language/10_Expressions/23_Additive_Expressions_A01_t13: Fail # Inherited from dart2js
+Language/10_Expressions/23_Additive_Expressions_A01_t14: Fail # Inherited from dart2js
+Language/10_Expressions/24_Multiplicative_Expressions_A01_t11: Fail # Inherited from dart2js
+Language/10_Expressions/24_Multiplicative_Expressions_A01_t14: Fail # Inherited from dart2js
+Language/10_Expressions/24_Multiplicative_Expressions_A01_t15: Fail # Inherited from dart2js
+Language/10_Expressions/24_Multiplicative_Expressions_A01_t16: Fail # Inherited from dart2js
+Language/10_Expressions/24_Multiplicative_Expressions_A01_t17: Fail # Inherited from dart2js
Language/10_Expressions/25_Unary_Expressions_A01_t01: Fail # inherited from VM
+Language/10_Expressions/25_Unary_Expressions_A01_t02: Fail # Inherited from dart2js
+Language/10_Expressions/25_Unary_Expressions_A01_t04: Fail # Inherited from dart2js
+Language/10_Expressions/25_Unary_Expressions_A01_t05: Fail # Inherited from dart2js
Language/10_Expressions/25_Unary_Expressions_A01_t10: Fail # inherited from VM
+Language/10_Expressions/25_Unary_Expressions_A01_t17: Fail # Inherited from dart2js
+Language/10_Expressions/25_Unary_Expressions_A01_t18: Fail # Inherited from dart2js
+Language/10_Expressions/25_Unary_Expressions_A01_t19: Fail # Inherited from dart2js
+Language/10_Expressions/25_Unary_Expressions_A01_t20: Fail # Inherited from dart2js
+Language/10_Expressions/25_Unary_Expressions_A01_t21: Fail # Inherited from dart2js
+Language/10_Expressions/25_Unary_Expressions_A01_t22: Fail # Inherited from dart2js
Language/10_Expressions/25_Unary_Expressions_A06_t01: Fail # inherited from VM
Language/10_Expressions/25_Unary_Expressions_A08_t01: Fail # inherited from VM
Language/10_Expressions/26_Postfix_Expressions_A01_t01: Fail # inherited from VM
+Language/10_Expressions/26_Postfix_Expressions_A01_t02: Fail # Inherited from dart2js
+Language/10_Expressions/26_Postfix_Expressions_A01_t03: Fail # Inherited from dart2js
+Language/10_Expressions/26_Postfix_Expressions_A01_t05: Fail # Inherited from dart2js
+Language/10_Expressions/27_Assignable_Expressions_A01_t06: Fail # Inherited from dart2js
+Language/10_Expressions/27_Assignable_Expressions_A01_t08: Fail # Inherited from dart2js
+Language/10_Expressions/27_Assignable_Expressions_A01_t09: Fail # Inherited from dart2js
Language/10_Expressions/27_Assignable_Expressions_A01_t26: Fail # inherited from VM
Language/10_Expressions/27_Assignable_Expressions_A01_t27: Fail # inherited from VM
Language/10_Expressions/28_Identifier_Reference_A02_t01: Fail # Pseudo keyword "abstract".
+Language/10_Expressions/28_Identifier_Reference_A04_t01: Fail # Inherited from dart2js
+Language/10_Expressions/28_Identifier_Reference_A04_t03: Fail # Inherited from dart2js
+Language/10_Expressions/28_Identifier_Reference_A04_t06: Fail # Inherited from dart2js
Language/10_Expressions/28_Identifier_Reference_A04_t07: Fail, OK # co19 issue 184
Language/10_Expressions/28_Identifier_Reference_A05_t09: Fail # inherited from VM
Language/10_Expressions/28_Identifier_Reference_A06_t07: Fail # inherited from VM
@@ -421,6 +414,7 @@
Language/10_Expressions/28_Identifier_Reference_A08_t32: Fail # inherited from dart2js
Language/10_Expressions/28_Identifier_Reference_A08_t38: Fail, Pass # co19 issue 218
Language/10_Expressions/29_Type_Test_A01_t02: Fail # http://dartbug.com/5519
+Language/10_Expressions/29_Type_Test_A01_t04: Fail # Inherited from dart2js
Language/10_Expressions/29_Type_Test_A04_t01: Fail # inherited from dart2js
Language/10_Expressions/30_Type_Cast_A01_t04: Fail # http://dartbug.com/5519
Language/10_Expressions/30_Type_Cast_A03_t01: Fail # http://dartbug.com/5029
@@ -477,23 +471,18 @@
Language/11_Statements/15_Assert_A01_t05: Fail # http://dartbug.com/5519
Language/13_Libraries_and_Scripts/13_Libraries_and_Scripts_A05_t04: Fail # inherited from VM
Language/13_Libraries_and_Scripts/2_Imports_A01_t39: Fail # inherited from VM
-Language/13_Libraries_and_Scripts/2_Imports_A01_t40: Fail # inherited from VM
Language/13_Libraries_and_Scripts/2_Imports_A02_t01: Fail # inherited from VM
Language/13_Libraries_and_Scripts/2_Imports_A02_t02: Fail # inherited from VM
-Language/13_Libraries_and_Scripts/2_Imports_A02_t11: Fail # inherited from VM
-Language/13_Libraries_and_Scripts/2_Imports_A02_t14: Fail # inherited from VM
Language/13_Libraries_and_Scripts/2_Imports_A02_t16: Fail # inherited from VM
Language/13_Libraries_and_Scripts/2_Imports_A02_t17: Fail # inherited from VM
Language/13_Libraries_and_Scripts/2_Imports_A02_t18: Fail # inherited from VM
+Language/13_Libraries_and_Scripts/2_Imports_A02_t19: Fail # Inherited from VM
Language/13_Libraries_and_Scripts/2_Imports_A02_t28: Fail # inherited from dart2js
Language/13_Libraries_and_Scripts/2_Imports_A03_t02: Fail # inherited from VM
-Language/13_Libraries_and_Scripts/2_Imports_A03_t04: Fail # inherited from dart2js
Language/13_Libraries_and_Scripts/2_Imports_A03_t06: Fail # inherited from dart2js
Language/13_Libraries_and_Scripts/2_Imports_A03_t12: Fail # inherited from VM
-Language/13_Libraries_and_Scripts/2_Imports_A03_t14: Fail # inherited from VM
Language/13_Libraries_and_Scripts/2_Imports_A03_t16: Fail # co19 issue 226
Language/13_Libraries_and_Scripts/2_Imports_A03_t22: Fail # inherited from VM
-Language/13_Libraries_and_Scripts/2_Imports_A03_t24: Fail # inherited from VM
Language/13_Libraries_and_Scripts/2_Imports_A03_t26: Fail # co19 issue 226
Language/13_Libraries_and_Scripts/2_Imports_A06_t01: Fail # inherited from dart2js
Language/13_Libraries_and_Scripts/3_Includes_A01_t01: Fail # inherited from dart2js
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index a9b3884..d43d6e2 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -123,10 +123,6 @@
Language/10_Expressions/29_Type_Test_A01_t02: Fail # TODO(ahe): Please triage this failure.
Language/10_Expressions/29_Type_Test_A01_t04: Fail # TODO(ahe): Please triage this failure.
Language/11_Statements/09_Try_A01_t18: Fail # TODO(ahe): Please triage this failure.
-Language/13_Libraries_and_Scripts/2_Imports_A01_t49: Fail # TODO(ahe): Please triage this failure.
-Language/13_Libraries_and_Scripts/2_Imports_A02_t12: Fail # TODO(ahe): Please triage this failure.
-Language/13_Libraries_and_Scripts/2_Imports_A02_t13: Fail # TODO(ahe): Please triage this failure.
-Language/13_Libraries_and_Scripts/2_Imports_A02_t15: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/2_Imports_A02_t19: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/2_Imports_A02_t28: Fail # TODO(ahe): Please triage this failure.
Language/15_Reference/1_Lexical_Rules/1_Reserved_Words_A30_t05: Fail # TODO(ahe): Please triage this failure.
@@ -420,6 +416,7 @@
Language/13_Libraries_and_Scripts/2_Imports_A06_t01: Fail, OK # co19 issue 250
+Language/13_Libraries_and_Scripts/2_Imports_A01_t39: Fail # co19 issue 253: Show combinators are intersections.
[ $compiler == dart2js && $runtime == d8 ]
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: Fail, Pass # issue 3333
@@ -721,14 +718,7 @@
Language/14_Types/5_Function_Types_A01_t22: Fail # http://dartbug.com/5022
Language/14_Types/5_Function_Types_A01_t23: Fail # http://dartbug.com/5022
-Language/13_Libraries_and_Scripts/2_Imports_A01_t39: Fail # http://dartbug.com/4050. Combinators not implemented yet.
-Language/13_Libraries_and_Scripts/2_Imports_A01_t40: Fail # http://dartbug.com/4050. Combinators not implemented yet.
-Language/13_Libraries_and_Scripts/2_Imports_A02_t11: Fail # http://dartbug.com/4050. Combinators not implemented yet.
-Language/13_Libraries_and_Scripts/2_Imports_A02_t14: Fail # http://dartbug.com/4050. Combinators not implemented yet.
-Language/13_Libraries_and_Scripts/2_Imports_A02_t18: Fail # http://dartbug.com/4050. Combinators not implemented yet.
-Language/13_Libraries_and_Scripts/2_Imports_A03_t04: Fail # http://dartbug.com/4050. Combinators not implemented yet.
-Language/13_Libraries_and_Scripts/2_Imports_A03_t14: Fail # http://dartbug.com/4050. Combinators not implemented yet.
-Language/13_Libraries_and_Scripts/2_Imports_A03_t24: Fail # http://dartbug.com/4050. Combinators not implemented yet.
+Language/13_Libraries_and_Scripts/2_Imports_A02_t18: Fail # http://dartbug.com/3970. Redirecting factory constructors not implemented yet.
Language/13_Libraries_and_Scripts/4_Scripts_A03_t01: Fail # http://dartbug.com/5683
Language/13_Libraries_and_Scripts/4_Scripts_A03_t03: Fail # http://dartbug.com/5683
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/compiler_helper.dart
index 6bc228c..057a3aa 100644
--- a/tests/compiler/dart2js/compiler_helper.dart
+++ b/tests/compiler/dart2js/compiler_helper.dart
@@ -18,9 +18,11 @@
#import("parser_helper.dart");
String compile(String code, [String entry = 'main',
- bool enableTypeAssertions = false]) {
+ bool enableTypeAssertions = false,
+ bool minify = false]) {
MockCompiler compiler =
- new MockCompiler(enableTypeAssertions: enableTypeAssertions);
+ new MockCompiler(enableTypeAssertions: enableTypeAssertions,
+ enableMinification: minify);
compiler.parseScript(code);
lego.Element element = compiler.mainApp.find(buildSourceString(entry));
if (element === null) return null;
diff --git a/tests/compiler/dart2js/concrete_type_inference_test.dart b/tests/compiler/dart2js/concrete_type_inference_test.dart
index 99ad0f4..9c303165 100644
--- a/tests/compiler/dart2js/concrete_type_inference_test.dart
+++ b/tests/compiler/dart2js/concrete_type_inference_test.dart
@@ -50,22 +50,22 @@
void testBasicTypes() {
checkPrintType('true', (compiler, type) {
- Expect.identical(compiler.boolClass, type);
+ Expect.identical(compiler.boolClass, type.getUniqueType());
});
checkPrintType('1.0', (compiler, type) {
- Expect.identical(compiler.doubleClass, type);
+ Expect.identical(compiler.doubleClass, type.getUniqueType());
});
checkPrintType('1', (compiler, type) {
- Expect.identical(compiler.intClass, type);
+ Expect.identical(compiler.intClass, type.getUniqueType());
});
checkPrintType('[]', (compiler, type) {
- Expect.identical(compiler.listClass, type);
+ Expect.identical(compiler.listClass, type.getUniqueType());
});
checkPrintType('null', (compiler, type) {
- Expect.identical(compiler.nullClass, type);
+ Expect.identical(compiler.nullClass, type.getUniqueType());
});
checkPrintType('"foo"', (compiler, type) {
- Expect.identical(compiler.stringClass, type);
+ Expect.identical(compiler.stringClass, type.getUniqueType());
});
}
@@ -82,7 +82,8 @@
fiskElement.computeSignature(compiler).optionalParameters.tail.head;
Expect.identical(
compiler.intClass,
- compiler.typesTask.getGuaranteedTypeOfElement(firstParameter));
+ compiler.typesTask.getGuaranteedTypeOfElement(firstParameter)
+ .getUniqueType());
Expect.isNull(
compiler.typesTask.getGuaranteedTypeOfElement(secondParameter));
Expect.isNull(
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index 6aab1df..f63da2e 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -2,6 +2,8 @@
# 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.
+link_test: Fail # TODO(ahe): I'm fixing this.
+
constant_folding_string_test: Fail
redundant_phi_eliminator_test: Fail # Fails because of hack to allow aborting loops.
pretty_parameter_test: Fail # TODO(floitsch): investigate.
diff --git a/tests/compiler/dart2js/minify_many_locals_test.dart b/tests/compiler/dart2js/minify_many_locals_test.dart
new file mode 100644
index 0000000..e25b249
--- /dev/null
+++ b/tests/compiler/dart2js/minify_many_locals_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2011, 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.
+// Test that parameters keep their names in the output.
+
+#import("compiler_helper.dart");
+
+main() {
+ var buffer = new StringBuffer();
+ buffer.add("var foo(");
+ for (int i = 0; i < 2000; i++) {
+ buffer.add("x$i, ");
+ }
+ buffer.add("x) { int i = ");
+ for (int i = 0; i < 2000; i++) {
+ buffer.add("x$i+");
+ }
+ buffer.add("2000; return i; }");
+ var generated = compile(buffer.toString(), 'foo', minify: true);
+ RegExp re = const RegExp(r"\(a,b,c");
+ Expect.isTrue(re.hasMatch(generated));
+
+ re = const RegExp(r"x,y,z,A,B,C");
+ Expect.isTrue(re.hasMatch(generated));
+
+ re = const RegExp(r"Y,Z,a0,a1,a2,a3,a4,a5,a6");
+ Expect.isTrue(re.hasMatch(generated));
+
+ re = const RegExp(r"g8,g9,h0,h1");
+ Expect.isTrue(re.hasMatch(generated));
+
+ re = const RegExp(r"Z8,Z9,aa0,aa1,aa2");
+ Expect.isTrue(re.hasMatch(generated));
+
+ re = const RegExp(r"aa9,ab0,ab1");
+ Expect.isTrue(re.hasMatch(generated));
+
+ re = const RegExp(r"aZ9,ba0,ba1");
+ Expect.isTrue(re.hasMatch(generated));
+}
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 1ed2b03..a3aa2df 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -77,10 +77,12 @@
MockCompiler([String coreSource = DEFAULT_CORELIB,
String helperSource = DEFAULT_HELPERLIB,
String interceptorsSource = DEFAULT_INTERCEPTORSLIB,
- bool enableTypeAssertions = false])
+ bool enableTypeAssertions = false,
+ bool enableMinification = false])
: warnings = [], errors = [],
sourceFiles = new Map<String, SourceFile>(),
- super(enableTypeAssertions: enableTypeAssertions) {
+ super(enableTypeAssertions: enableTypeAssertions,
+ enableMinification: enableMinification) {
coreLibrary = createLibrary("core", coreSource);
// We need to set the assert method to avoid calls with a 'null'
// target being interpreted as a call to assert.
diff --git a/tests/compiler/dart2js/unparser_test.dart b/tests/compiler/dart2js/unparser_test.dart
index ddf2b6b..af53532 100644
--- a/tests/compiler/dart2js/unparser_test.dart
+++ b/tests/compiler/dart2js/unparser_test.dart
@@ -243,6 +243,11 @@
testUnparseMember("external const factory Foo() = prefix.Bar<T>.baz;");
}
+testClassDeclarations() {
+ testUnparseTopLevelWithMetadata('class Foo{}');
+ testUnparseTopLevelWithMetadata('abstract class Foo{}');
+}
+
main() {
testSignedConstants();
testGenericTypes();
@@ -261,4 +266,5 @@
testPartOf();
testCombinators();
testRedirectingFactoryConstructors();
+ testClassDeclarations();
}
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 28c4887..9d53c1c 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -10,6 +10,9 @@
inline_position_crash_test: Fail # http://www.dartbug.com/3905
constant_javascript_semantics3_test: Fail # http://www.dartbug.com/5581
+[ $compiler == dart2js && $runtime == ff && $system == windows ]
+regress/4740_test: Fail
+
[ $compiler == dart2js && $checked ]
parameter_bailout_test: Fail, OK
variable_type_test/03: Fail, OK
diff --git a/tests/language/abstract_runtime_error_test.dart b/tests/language/abstract_runtime_error_test.dart
new file mode 100644
index 0000000..ceb973c
--- /dev/null
+++ b/tests/language/abstract_runtime_error_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2012, 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.
+
+// Test various conditions around instantiating an abstract class.
+
+// From The Dart Programming Langauge Specification, 11.11.1 "New":
+// If q is a constructor of an abstract class then an
+// AbstractClassInstantiation- Error is thrown.
+
+
+abstract class Interface {
+ void foo();
+}
+
+abstract class AbstractClass {
+ toString() => 'AbstractClass';
+}
+
+class ConcreteSubclass extends AbstractClass {
+ toString() => 'ConcreteSubclass';
+}
+
+class NonAbstractClass implements Interface {
+ toString() => 'NonAbstractClass';
+}
+
+Interface interface() => new Interface();
+
+AbstractClass abstractClass() => new AbstractClass();
+
+bool isAbstractClassInstantiationError(e) {
+ return e is AbstractClassInstantiationError;
+}
+
+void main() {
+ Expect.throws(interface, isAbstractClassInstantiationError,
+ "expected AbstractClassInstantiationError");
+ Expect.throws(abstractClass, isAbstractClassInstantiationError,
+ "expected AbstractClassInstantiationError");
+ Expect.stringEquals('ConcreteSubclass', '${new ConcreteSubclass()}');
+ Expect.stringEquals('NonAbstractClass', '${new NonAbstractClass()}');
+}
diff --git a/tests/language/first_class_types_lib1.dart b/tests/language/first_class_types_lib1.dart
new file mode 100644
index 0000000..baadc66
--- /dev/null
+++ b/tests/language/first_class_types_lib1.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2012, 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 lib1;
+
+class A {}
diff --git a/tests/language/first_class_types_lib2.dart b/tests/language/first_class_types_lib2.dart
new file mode 100644
index 0000000..de943b7
--- /dev/null
+++ b/tests/language/first_class_types_lib2.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2012, 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 lib2;
+
+class A {}
diff --git a/tests/language/first_class_types_libraries_test.dart b/tests/language/first_class_types_libraries_test.dart
new file mode 100644
index 0000000..b04c572
--- /dev/null
+++ b/tests/language/first_class_types_libraries_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2012, 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.
+
+import 'first_class_types_lib1.dart' as lib1;
+import 'first_class_types_lib2.dart' as lib2;
+
+class C<X> {}
+
+sameType(a, b) {
+ Expect.identical(a.runtimeType, b.runtimeType);
+}
+
+differentType(a, b) {
+ print("a: ${a.runtimeType}");
+ print("b: ${b.runtimeType}");
+ Expect.isFalse(identical(a.runtimeType, b.runtimeType));
+}
+
+main() {
+ sameType(new lib1.A(), new lib1.A());
+ differentType(new lib1.A(), new lib2.A());
+ differentType(new C<lib1.A>(), new C<lib2.A>());
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index 70649bb..456875a 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -218,13 +218,13 @@
import_combinators_test: Fail
export_test: Fail # Issue 5785
export_cyclic_test: Fail # Issue 5785
-call_test: Fail # Issue 5797
+first_class_types_libraries_test: Fail # Issue 2264
[ $runtime == dartium ]
import_combinators_test: Fail
-[ $runtime == vm ]
+[ $runtime == vm || ($runtime == drt && $compiler == none) ]
call_test: Fail # Issue 1604
[ $runtime == chrome ]
@@ -308,7 +308,6 @@
static_field3_test/03: Fail # http://dartbug.com/5519
static_field3_test/04: Fail # http://dartbug.com/5519
-import_combinators_test: Fail
throw_expr_test: Fail
metadata_test: Fail
# Fails in conservative mode, issue 4935, passes in minifinying mode.
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 16ffb2c..cf021ae 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -58,6 +58,7 @@
compile_time_constant_checked3_test/06: Fail, OK
[ $compiler == dart2js ]
+abstract_runtime_error_test: Fail # http://dartbug.com/4737
bad_constructor_test/04: Fail # http://dartbug.com/5519
bad_constructor_test/05: Fail # http://dartbug.com/5519
bad_constructor_test/06: Fail # http://dartbug.com/5519
@@ -79,7 +80,6 @@
execute_finally8_test: Fail # http://dartbug.com/5643
-import_combinators_test: Fail
throw_expr_test: Fail
metadata_test: Fail # Metadata on type parameters not supported.
infinity_test: Fail # Issue 4984
@@ -153,7 +153,6 @@
get_set_syntax_test/15: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
get_set_syntax_test/16: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
implicit_scope_test: Fail # duplicate definition of a="bar"
-lazy_static2_test: Fail # Issue 3559: No support for closures in lazy initializers.
library_prefixes_test: Fail # other is not a type
local_function_test: Fail # TypeError: Object #<Closure> has no method '$call$2' (bad exception mapping).
many_generic_instanceof_test: Fail # cannot resolve type T
@@ -362,3 +361,5 @@
export_test: Fail # Issue 5785
export_cyclic_test: Fail # Issue 5785
generic_creation_test: Fail # Issue 5785l
+import_combinators_test: Fail # Issue 3454
+first_class_types_libraries_test: Fail
diff --git a/tests/language/lazy_static2_test.dart b/tests/language/lazy_static2_test.dart
index e422c30..b06db04 100644
--- a/tests/language/lazy_static2_test.dart
+++ b/tests/language/lazy_static2_test.dart
@@ -7,4 +7,4 @@
main() {
Expect.equals(499, x(498));
Expect.equals(42, x(41));
-}
\ No newline at end of file
+}
diff --git a/tests/language/lazy_static6_src.dart b/tests/language/lazy_static6_src.dart
new file mode 100644
index 0000000..779d3d8
--- /dev/null
+++ b/tests/language/lazy_static6_src.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2012, 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.
+
+/*
+ * A lot of comments to make sure that the lazy initialization code has a
+ * position that does not fit into lazy_static6_test.dart file.
+ ******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+ */
+
+final x = (t) => (u) => t + u;
+
+main() {
+ Expect.equals(499, x(498)(1));
+ Expect.equals(42, x(39)(3));
+}
diff --git a/tests/language/lazy_static6_test.dart b/tests/language/lazy_static6_test.dart
new file mode 100644
index 0000000..0dec5dc
--- /dev/null
+++ b/tests/language/lazy_static6_test.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2012, 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("lazy_static6_test");
+#source("lazy_static6_src.dart");
diff --git a/tests/standalone/byte_array_test.dart b/tests/standalone/byte_array_test.dart
index 2f60f29..1565488 100644
--- a/tests/standalone/byte_array_test.dart
+++ b/tests/standalone/byte_array_test.dart
@@ -78,11 +78,54 @@
Expect.equals(-1, list.indexOf(20.0));
}
+void testSubArray() {
+ var list = new Uint8List(10);
+ var array = list.asByteArray();
+ Expect.equals(0, array.subByteArray(0, 0).lengthInBytes());
+ Expect.equals(0, array.subByteArray(5, 0).lengthInBytes());
+ Expect.equals(0, array.subByteArray(10, 0).lengthInBytes());
+ Expect.equals(0, array.subByteArray(10).lengthInBytes());
+ Expect.equals(0, array.subByteArray(10, null).lengthInBytes());
+ Expect.equals(5, array.subByteArray(0, 5).lengthInBytes());
+ Expect.equals(5, array.subByteArray(5, 5).lengthInBytes());
+ Expect.equals(5, array.subByteArray(5).lengthInBytes());
+ Expect.equals(5, array.subByteArray(5, null).lengthInBytes());
+ Expect.equals(10, array.subByteArray(0, 10).lengthInBytes());
+ Expect.equals(10, array.subByteArray(0).lengthInBytes());
+ Expect.equals(10, array.subByteArray(0, null).lengthInBytes());
+ Expect.equals(10, array.subByteArray().lengthInBytes());
+ testThrowsIndex(function) {
+ Expect.throws(function, (e) => e is IndexOutOfRangeException);
+ }
+ testThrowsIndex(() => array.subByteArray(0, -1));
+ testThrowsIndex(() => array.subByteArray(1, -1));
+ testThrowsIndex(() => array.subByteArray(10, -1));
+ testThrowsIndex(() => array.subByteArray(-1, 0));
+ testThrowsIndex(() => array.subByteArray(-1));
+ testThrowsIndex(() => array.subByteArray(-1, null));
+ testThrowsIndex(() => array.subByteArray(11, 0));
+ testThrowsIndex(() => array.subByteArray(11));
+ testThrowsIndex(() => array.subByteArray(11, null));
+ testThrowsIndex(() => array.subByteArray(6, 5));
+
+ bool checkedMode = false;
+ assert(checkedMode = true);
+ if (!checkedMode) {
+ // In checked mode these will necessarily throw a TypeError.
+ Expect.throws(() => array.subByteArray(0, "5"), (e) => e is ArgumentError);
+ Expect.throws(() => array.subByteArray("0", 5), (e) => e is ArgumentError);
+ Expect.throws(() => array.subByteArray("0"), (e) => e is ArgumentError);
+ }
+ Expect.throws(() => array.subByteArray(null), (e) => e is ArgumentError);
+}
+
main() {
for (int i = 0; i < 2000; i++) {
testCreateByteArray();
testSetRange();
testIndexOutOfRange();
testIndexOf();
+ testSubArray();
}
}
+
diff --git a/tests/standalone/float_array_test.dart b/tests/standalone/float_array_test.dart
index dab3734..41b4f7e 100644
--- a/tests/standalone/float_array_test.dart
+++ b/tests/standalone/float_array_test.dart
@@ -9,7 +9,7 @@
#import('dart:scalarlist');
-void testCreateFloatArray() {
+void testCreateFloat32Array() {
Float32List floatArray;
floatArray = new Float32List(0);
@@ -22,7 +22,7 @@
}
}
-void testSetRange() {
+void testSetRange32() {
Float32List floatArray = new Float32List(3);
List<num> list = [10.0, 11.0, 12.0];
@@ -39,13 +39,14 @@
Expect.equals(20 + i, list[i]);
}
- floatArray.setRange(1, 2, const [8.0, 9.0]);
+ // 4.0e40 is larger than the largest representable float.
+ floatArray.setRange(1, 2, const [8.0, 4.0e40]);
Expect.equals(20, floatArray[0]);
Expect.equals(8, floatArray[1]);
- Expect.equals(9, floatArray[2]);
+ Expect.equals(double.INFINITY, floatArray[2]);
}
-void testIndexOutOfRange() {
+void testIndexOutOfRange32() {
Float32List floatArray = new Float32List(3);
List<num> list = const [0.0, 1.0, 2.0, 3.0];
@@ -61,7 +62,7 @@
});
}
-void testIndexOf() {
+void testIndexOf32() {
var list = new Float32List(10);
for (int i = 0; i < list.length; i++) {
list[i] = i + 10.0;
@@ -81,11 +82,90 @@
Expect.equals(-1, list.indexOf(20.0));
}
+void testCreateFloat64Array() {
+ Float64List floatArray;
+
+ floatArray = new Float64List(0);
+ Expect.equals(0, floatArray.length);
+
+ floatArray = new Float64List(10);
+ Expect.equals(10, floatArray.length);
+ for (int i = 0; i < 10; i++) {
+ Expect.equals(0.0, floatArray[i]);
+ }
+}
+
+void testSetRange64() {
+ Float64List floatArray = new Float64List(3);
+
+ List<num> list = [10.0, 11.0, 12.0];
+ floatArray.setRange(0, 3, list);
+ for (int i = 0; i < 3; i++) {
+ Expect.equals(10 + i, floatArray[i]);
+ }
+
+ floatArray[0] = 20.0;
+ floatArray[1] = 21.0;
+ floatArray[2] = 22.0;
+ list.setRange(0, 3, floatArray);
+ for (int i = 0; i < 3; i++) {
+ Expect.equals(20 + i, list[i]);
+ }
+
+ // Unlike Float32Array we can properly represent 4.0e40
+ floatArray.setRange(1, 2, const [8.0, 4.0e40]);
+ Expect.equals(20, floatArray[0]);
+ Expect.equals(8, floatArray[1]);
+ Expect.equals(4.0e40, floatArray[2]);
+}
+
+void testIndexOutOfRange64() {
+ Float64List floatArray = new Float64List(3);
+ List<num> list = const [0.0, 1.0, 2.0, 3.0];
+
+ Expect.throws(() {
+ floatArray[5] = 2.0;
+ });
+ Expect.throws(() {
+ floatArray.setRange(0, 4, list);
+ });
+
+ Expect.throws(() {
+ floatArray.setRange(3, 1, list);
+ });
+}
+
+void testIndexOf64() {
+ var list = new Float64List(10);
+ for (int i = 0; i < list.length; i++) {
+ list[i] = i + 10.0;
+ }
+ Expect.equals(0, list.indexOf(10));
+ Expect.equals(5, list.indexOf(15));
+ Expect.equals(9, list.indexOf(19));
+ Expect.equals(-1, list.indexOf(20));
+
+ list = new Float64List(10);
+ for (int i = 0; i < list.length; i++) {
+ list[i] = i + 10.0;
+ }
+ Expect.equals(0, list.indexOf(10.0));
+ Expect.equals(5, list.indexOf(15.0));
+ Expect.equals(9, list.indexOf(19.0));
+ Expect.equals(-1, list.indexOf(20.0));
+}
+
main() {
for (int i = 0; i < 2000; i++) {
- testCreateFloatArray();
- testSetRange();
- testIndexOutOfRange();
- testIndexOf();
+ testCreateFloat32Array();
+ testSetRange32();
+ testIndexOutOfRange32();
+ testIndexOf32();
+ }
+ for (int i = 0; i < 2000; i++) {
+ testCreateFloat64Array();
+ testSetRange64();
+ testIndexOutOfRange64();
+ testIndexOf64();
}
}
diff --git a/tools/VERSION b/tools/VERSION
index bf439ec..82ee775 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
MAJOR 0
MINOR 1
-BUILD 1
+BUILD 3
PATCH 0
diff --git a/tools/testing/dart/version.dart b/tools/release/version.dart
similarity index 73%
rename from tools/testing/dart/version.dart
rename to tools/release/version.dart
index dba3be3..5197f75 100644
--- a/tools/testing/dart/version.dart
+++ b/tools/release/version.dart
@@ -35,7 +35,9 @@
int BUILD;
int PATCH;
- Version(String this._versionFileName);
+ Version(Path versionFile) {
+ _versionFileName = versionFile.toNativePath();
+ }
/**
* Get the version number for this specific build using the version info
@@ -95,14 +97,14 @@
if (!c.future.isComplete) {
getRevision().then((revision) {
REVISION = revision;
- getUserName().then((username) {
- USERNAME = username;
- if (username != '') username = "_$username";
- var revisionString = "";
- if (revision != 0) revisionString = "_r$revision";
- c.complete("$MAJOR.$MINOR.$BUILD.$PATCH$revisionString$username");
- return;
- });
+ USERNAME = getUserName();
+ var userNameString = "";
+ if (USERNAME != '') userNameString = "_$USERNAME";
+ var revisionString = "";
+ if (revision != 0) revisionString = "_r$revision";
+ c.complete(
+ "$MAJOR.$MINOR.$BUILD.$PATCH$revisionString$userNameString");
+ return;
});
}
};
@@ -110,40 +112,62 @@
return c.future;
}
+ String getExecutableSuffix() {
+ if (Platform.operatingSystem == 'windows') {
+ return '.bat';
+ }
+ return '';
+ }
+
+ int getRevisionFromSvnInfo(String info) {
+ if (info == null || info == '') return 0;
+ var lines = info.split("\n");
+ RegExp exp = const RegExp(r"Revision: (\d*)");
+ for (var line in lines) {
+ if (exp.hasMatch(line)) {
+ String revisionString = (exp.firstMatch(line).group(1));
+ try {
+ return int.parse(revisionString);
+ } catch(e) {
+ return 0;
+ }
+ }
+ }
+ return 0;
+ }
+
Future<int> getRevision() {
if (repositoryType == RepositoryType.UNKNOWN) {
return new Future.immediate(0);
}
var isSvn = repositoryType == RepositoryType.SVN;
var command = isSvn ? "svn" : "git";
+ command = "$command${getExecutableSuffix()}";
var arguments = isSvn ? ["info"] : ["svn", "info"];
return Process.run(command, arguments).transform((result) {
if (result.exitCode != 0) {
return 0;
}
- // If anything goes wrong parsing the revision we simply return 0.
- try {
- // Extract the revision. It's located at the 8th line,
- // 18 characters in.
- String revisionString = result.stdout.split("\n")[8].substring(18);
- return int.parse(revisionString);
- } catch (e) {
- return 0;
- }
+ return getRevisionFromSvnInfo(result.stdout);
});
}
- Future<String> getUserName() {
+ bool isProductionBuild(String username) {
+ return username == "chrome-bot";
+ }
+
+ String getUserName() {
// TODO(ricow): Don't add this on the buildbot.
- // If we can't get the username simple return "" (e.g. on windows).
- return Process.run("whoami", []).transform((result) {
- if (result.exitCode != 0) {
- return "";
- }
- return result.stdout;
- }).transformException((e) {
- return "";
- });
+ var key = "USER";
+ if (Platform.operatingSystem == 'windows') {
+ key = "USERNAME";
+ }
+ if (!Platform.environment.containsKey(key)) return "";
+ var username = Platform.environment[key];
+ // If this is a production build, i.e., this is something we are shipping,
+ // don't suffix the version with the username.
+ if (isProductionBuild(username)) return "";
+ return username;
}
RepositoryType get repositoryType {
diff --git a/tools/test.py b/tools/test.py
index bd16393..3ab247b 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -15,11 +15,6 @@
def Main():
args = sys.argv[1:]
tools_dir = os.path.dirname(os.path.realpath(__file__))
- dart_binary_prefix = os.path.join(tools_dir, 'testing', 'bin')
- if utils.IsWindows():
- dart_binary = os.path.join(dart_binary_prefix, 'windows', 'dart.exe')
- else:
- dart_binary = os.path.join(dart_binary_prefix, utils.GuessOS(), 'dart')
current_directory = os.path.abspath('');
client = os.path.abspath(os.path.join(tools_dir, '..'));
if current_directory == os.path.join(client, 'runtime'):
@@ -27,7 +22,7 @@
else:
dart_script_name = 'test.dart'
dart_test_script = string.join([tools_dir, dart_script_name], os.sep)
- command = [dart_binary, dart_test_script] + args
+ command = [utils.DartBinary(), dart_test_script] + args
exit_code = subprocess.call(command)
utils.DiagnoseExitCode(exit_code, command)
return exit_code
diff --git a/tools/touch_version.py b/tools/touch_version.py
new file mode 100644
index 0000000..98841fe
--- /dev/null
+++ b/tools/touch_version.py
@@ -0,0 +1,18 @@
+# Copyright (c) 2012, 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.
+#
+# This python script "touches" the tools/VERSION file.
+
+import os
+import sys
+
+# Change into the dart directory as we want to be able to access the VERSION file
+# from a simple path.
+runtime_src = os.path.join(os.path.dirname(sys.argv[0]), os.pardir)
+os.chdir(runtime_src)
+
+if __name__ == '__main__':
+ print 'Touching tools/VERSION.'
+ os.utime(os.path.join('tools', 'VERSION'), None)
+ sys.exit(0)
diff --git a/tools/utils.py b/tools/utils.py
index 1c6ef7f..2ae3821 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -297,6 +297,15 @@
os.utime(name, None)
+def DartBinary():
+ tools_dir = os.path.dirname(os.path.realpath(__file__))
+ dart_binary_prefix = os.path.join(tools_dir, 'testing', 'bin')
+ if IsWindows():
+ return os.path.join(dart_binary_prefix, 'windows', 'dart.exe')
+ else:
+ return os.path.join(dart_binary_prefix, GuessOS(), 'dart')
+
+
if __name__ == "__main__":
import sys
Main(sys.argv)
diff --git a/tools/version.dart b/tools/version.dart
index e08091c..0b4254c 100644
--- a/tools/version.dart
+++ b/tools/version.dart
@@ -1,11 +1,14 @@
+#!/usr/bin/env dart
// Copyright (c) 2012, 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.
-#import("testing/dart/version.dart");
+import "dart:io";
+import "release/version.dart";
void main() {
- Version version = new Version("tools/VERSION");
+ Path scriptPath = new Path(new Options().script).directoryPath;
+ Version version = new Version(scriptPath.append("VERSION"));
Future f = version.getVersion();
f.then((currentVersion) {
print(currentVersion);