[vm/bytecode] Represent classes, libraries, scripts and recursive types in bytecode

Size of a large application:
Before: 26628600
After: 21480120 (-19.3%)

Size of snapshots:

isolate_snapshot_framework.bin
Before: 9322496
After: 6782976 (-27.2%)

isolate_snapshot_product_framework.bin
Before: 9166848
After: 6602752 (-27.9%)

Regressions in tests:

1) Test language_2/type_alias_equality_test/04 fails similarly to default mode, as VM
does not implement comparison of function types according to the specification.
Previously this test was passing as function types were canonicalized in bytecode,
which was not always correct. This CL fixes the problem with canonicalization of
function types in bytecode and the test starts failing again.

2) Tests standalone_2/entrypoints_verification_test, standalone_2/io/test_extension_test,
standalone_2/io/test_extension_fail_test fail as native extensions are not supported
in bytecode yet. These tests start passing after df5e7aac17,
which switched bytecode tests to kernel service (on x64), because kernel service doesn't
drop ASTs. This CL switches from reading AST library declarations to bytecode even if
AST is not removed, so tests fail again.

Change-Id: I8b7ba44bfa49d0b1599b2509553ff7c831a4e244
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/104700
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Alexander Markov 2019-06-20 18:27:21 +00:00 committed by commit-bot@chromium.org
parent 85a4fdb81a
commit da8cb470cc
56 changed files with 3282 additions and 1935 deletions

View file

@ -40,7 +40,8 @@ export '../fasta/fasta_codes.dart'
templateFfiTypeInvalid,
templateFfiTypeMismatch,
templateFfiTypeUnsized,
templateFfiFieldInitializer;
templateFfiFieldInitializer,
templateIllegalRecursiveType;
export '../fasta/hybrid_file_system.dart' show HybridFileSystem;

View file

@ -4276,6 +4276,29 @@ Message _withArgumentsIllegalMixinDueToConstructorsCause(String name) {
arguments: {'name': name});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(DartType _type)> templateIllegalRecursiveType =
const Template<Message Function(DartType _type)>(
messageTemplate: r"""Illegal recursive type '#type'.""",
withArguments: _withArgumentsIllegalRecursiveType);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Message Function(DartType _type)> codeIllegalRecursiveType =
const Code<Message Function(DartType _type)>(
"IllegalRecursiveType",
templateIllegalRecursiveType,
);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
Message _withArgumentsIllegalRecursiveType(DartType _type) {
TypeLabeler labeler = new TypeLabeler();
List<Object> typeParts = labeler.labelType(_type);
String type = typeParts.join();
return new Message(codeIllegalRecursiveType,
message: """Illegal recursive type '${type}'.""" + labeler.originMessages,
arguments: {'type': _type});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeIllegalSyncGeneratorReturnType =
messageIllegalSyncGeneratorReturnType;

View file

@ -280,6 +280,9 @@ IllegalAssignmentToNonAssignable/script1: Fail
IllegalAsyncGeneratorVoidReturnType/analyzerCode: Fail # The analyzer doesn't report this error.
IllegalMixin/example: Fail
IllegalMixinDueToConstructors/example: Fail
IllegalRecursiveType/analyzerCode: Fail
IllegalRecursiveType/part_wrapped_script: Fail
IllegalRecursiveType/script: Fail
IllegalSyncGeneratorVoidReturnType/analyzerCode: Fail # The analyzer doesn't report this error.
ImplementsBeforeExtends/part_wrapped_script: Fail
ImplementsBeforeExtends/script: Fail

View file

@ -3560,3 +3560,9 @@ BadTypeVariableInSupertype:
script: >
class A<X> {}
class B<Y> extends A<Function(Y)> {}
IllegalRecursiveType:
template: "Illegal recursive type '#type'."
script: >
class Base<T> {}
class Derived<T> extends Base<Derived<Derived<T>>> {}

View file

@ -145,12 +145,13 @@ abstract class Compiler {
if (options.bytecode && errors.isEmpty) {
await runWithFrontEndCompilerContext(script, options, component, () {
// TODO(alexmarkov): disable source positions and local variables
// in VM PRODUCT mode.
// TODO(alexmarkov): disable source positions, local variables info
// and source files in VM PRODUCT mode.
generateBytecode(component,
environmentDefines: options.environmentDefines,
emitSourcePositions: true,
emitLocalVarInfo: true);
emitLocalVarInfo: true,
emitSourceFiles: true);
});
}

View file

@ -1,181 +0,0 @@
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library vm.bytecode.ast_remover;
import 'package:kernel/ast.dart' hide MapEntry;
import '../metadata/bytecode.dart';
/// Drops kernel AST for members with bytecode.
/// Can preserve removed AST and restore it if needed.
class ASTRemover extends Transformer {
final BytecodeMetadataRepository metadata;
final stashes = <Node, _Stash>{};
ASTRemover(Component component)
: metadata = component.metadata[new BytecodeMetadataRepository().tag] {
stashes[component] = new _ComponentStash(component.mainMethod,
new Map<String, MetadataRepository<dynamic>>.from(component.metadata));
component.mainMethod = null;
component.metadata.removeWhere((tag, md) => tag != metadata.tag);
}
@override
visitLibrary(Library node) {
stashes[node] = new _LibraryStash(
new List<Expression>.from(node.annotations),
new List<Field>.from(node.fields),
new List<Procedure>.from(node.procedures),
new List<Reference>.from(node.additionalExports));
node.annotations.clear();
node.fields.clear();
node.procedures.clear();
node.additionalExports.clear();
super.visitLibrary(node);
return node;
}
@override
visitLibraryDependency(LibraryDependency node) {
stashes[node] = new _LibraryDependencyStash(
new List<Expression>.from(node.annotations));
node.annotations.clear();
super.visitLibraryDependency(node);
return node;
}
// Still referenced from function types which may appear in class supertypes.
@override
visitTypedef(Typedef node) {
stashes[node] = new _TypedefStash(node.annotations);
node.annotations = const <Expression>[];
super.visitTypedef(node);
// TODO(alexmarkov): fix Typedef visitor to visit these fields.
transformList(node.positionalParameters, this, node);
transformList(node.namedParameters, this, node);
return node;
}
// May appear in typedefs.
@override
visitVariableDeclaration(VariableDeclaration node) {
stashes[node] = new _VariableDeclarationStash(node.annotations);
node.annotations = const <Expression>[];
super.visitVariableDeclaration(node);
return node;
}
@override
visitClass(Class node) {
stashes[node] = new _ClassStash(
node.annotations,
new List<Field>.from(node.fields),
new List<Procedure>.from(node.procedures),
new List<Constructor>.from(node.constructors));
node.annotations = const <Expression>[];
node.fields.clear();
node.procedures.clear();
node.constructors.clear();
super.visitClass(node);
return node;
}
void restoreAST() {
stashes.forEach((Node node, _Stash stash) {
if (node is Component) {
_ComponentStash componentStash = stash as _ComponentStash;
node.mainMethod = componentStash.mainMethod;
node.metadata.addAll(componentStash.metadata);
} else if (node is Library) {
_LibraryStash libraryStash = stash as _LibraryStash;
node.annotations.addAll(libraryStash.annotations);
node.fields.addAll(libraryStash.fields);
node.procedures.addAll(libraryStash.procedures);
node.additionalExports.addAll(libraryStash.additionalExports);
} else if (node is LibraryDependency) {
_LibraryDependencyStash libraryDependencyStash =
stash as _LibraryDependencyStash;
node.annotations.addAll(libraryDependencyStash.annotations);
} else if (node is Typedef) {
_TypedefStash typedefStash = stash as _TypedefStash;
node.annotations = typedefStash.annotations;
} else if (node is VariableDeclaration) {
_VariableDeclarationStash variableDeclarationStash =
stash as _VariableDeclarationStash;
node.annotations = variableDeclarationStash.annotations;
} else if (node is Class) {
_ClassStash classStash = stash as _ClassStash;
node.annotations = classStash.annotations;
node.fields.addAll(classStash.fields);
node.procedures.addAll(classStash.procedures);
node.constructors.addAll(classStash.constructors);
} else {
throw 'Unexpected ${node.runtimeType} $node';
}
});
}
}
abstract class _Stash {}
class _ClassStash extends _Stash {
final List<Expression> annotations;
final List<Field> fields;
final List<Procedure> procedures;
final List<Constructor> constructors;
_ClassStash(
this.annotations, this.fields, this.procedures, this.constructors);
}
class _LibraryStash extends _Stash {
final List<Expression> annotations;
final List<Field> fields;
final List<Procedure> procedures;
final List<Reference> additionalExports;
_LibraryStash(
this.annotations, this.fields, this.procedures, this.additionalExports);
}
class _LibraryDependencyStash extends _Stash {
final List<Expression> annotations;
_LibraryDependencyStash(this.annotations);
}
class _TypedefStash extends _Stash {
final List<Expression> annotations;
_TypedefStash(this.annotations);
}
class _VariableDeclarationStash extends _Stash {
final List<Expression> annotations;
_VariableDeclarationStash(this.annotations);
}
class _ComponentStash extends _Stash {
final Procedure mainMethod;
final Map<String, MetadataRepository<dynamic>> metadata;
_ComponentStash(this.mainMethod, this.metadata);
}

View file

@ -234,6 +234,11 @@ class BufferedReader {
return linkReader.get<T>(offset);
}
ForwardReference<T> readLinkOffsetAsForwardReference<T>() {
final offset = readPackedUInt30();
return new ForwardReference<T>(offset, linkReader);
}
void align(int alignment) {
assert(alignment & (alignment - 1) == 0);
_pos = ((_pos + alignment - 1) & -alignment);
@ -455,6 +460,16 @@ class LinkReader {
}
}
// Placeholder for an object which will be read in future.
class ForwardReference<T> {
final int offset;
final LinkReader linkReader;
ForwardReference(this.offset, this.linkReader);
T get() => linkReader.get<T>(offset);
}
class NamedEntryStatistics {
final String name;
int size = 0;
@ -471,7 +486,15 @@ class BytecodeSizeStatistics {
static int objectTableSize = 0;
static int objectTableEntriesCount = 0;
static int stringTableSize = 0;
static int librariesSize = 0;
static int classesSize = 0;
static int membersSize = 0;
static int codeSize = 0;
static int sourcePositionsSize = 0;
static int sourceFilesSize = 0;
static int lineStartsSize = 0;
static int localVariablesSize = 0;
static int annotationsSize = 0;
static int constantPoolSize = 0;
static int instructionsSize = 0;
static List<NamedEntryStatistics> constantPoolStats =
@ -483,7 +506,15 @@ class BytecodeSizeStatistics {
objectTableSize = 0;
objectTableEntriesCount = 0;
stringTableSize = 0;
librariesSize = 0;
classesSize = 0;
membersSize = 0;
codeSize = 0;
sourcePositionsSize = 0;
sourceFilesSize = 0;
lineStartsSize = 0;
localVariablesSize = 0;
annotationsSize = 0;
constantPoolSize = 0;
instructionsSize = 0;
constantPoolStats = <NamedEntryStatistics>[];
@ -499,7 +530,15 @@ class BytecodeSizeStatistics {
print(" - $entry");
}
print(" - string table: $stringTableSize");
print(" Bytecode members: $membersSize");
print(" Libraries: $librariesSize");
print(" Classes: $classesSize");
print(" Members: $membersSize");
print(" Source positions: $sourcePositionsSize");
print(" Source files: $sourceFilesSize");
print(" Line starts: $lineStartsSize");
print(" Local variables: $localVariablesSize");
print(" Annotations: $annotationsSize");
print(" Code: $codeSize");
print(" - constant pool: $constantPoolSize");
for (var entry in constantPoolStats) {
print(" - $entry");

View file

@ -10,7 +10,7 @@ library vm.bytecode.dbc;
/// Before bumping current bytecode version format, make sure that
/// all users have switched to a VM which is able to consume new
/// version of bytecode.
const int currentBytecodeFormatVersion = 9;
const int currentBytecodeFormatVersion = 10;
/// Version of experimental / bleeding edge bytecode format.
/// Produced by bytecode generator when --use-future-bytecode-format

View file

@ -14,7 +14,250 @@ import 'disassembler.dart' show BytecodeDisassembler;
import 'exceptions.dart' show ExceptionsTable;
import 'local_variable_table.dart' show LocalVariableTable;
import 'object_table.dart' show ObjectTable, ObjectHandle, NameAndType;
import 'source_positions.dart' show SourcePositions;
import 'source_positions.dart' show LineStarts, SourcePositions;
class LibraryDeclaration {
static const usesDartMirrorsFlag = 1 << 0;
static const usesDartFfiFlag = 1 << 1;
ObjectHandle importUri;
final int flags;
final ObjectHandle name;
final ObjectHandle script;
final List<ClassDeclaration> classes;
LibraryDeclaration(
this.importUri, this.flags, this.name, this.script, this.classes);
void write(BufferedWriter writer) {
final start = writer.offset;
writer.writePackedUInt30(flags);
writer.writePackedObject(name);
writer.writePackedObject(script);
writer.writePackedUInt30(classes.length);
for (var cls in classes) {
writer.writePackedObject(cls.name);
writer.writeLinkOffset(cls);
}
BytecodeSizeStatistics.librariesSize += (writer.offset - start);
}
factory LibraryDeclaration.read(BufferedReader reader) {
final flags = reader.readPackedUInt30();
final name = reader.readPackedObject();
final script = reader.readPackedObject();
final classes =
List<ClassDeclaration>.generate(reader.readPackedUInt30(), (_) {
final className = reader.readPackedObject();
return reader.readLinkOffset<ClassDeclaration>()..name = className;
});
return new LibraryDeclaration(null, flags, name, script, classes);
}
@override
String toString() {
final StringBuffer sb = new StringBuffer();
sb.writeln('Library $importUri');
sb.writeln(' name $name');
sb.writeln(' script $script');
if ((flags & usesDartMirrorsFlag) != 0) {
sb.writeln(' uses dart:mirrors');
}
if ((flags & usesDartFfiFlag) != 0) {
sb.writeln(' uses dart:ffi');
}
sb.writeln();
for (var cls in classes) {
sb.write(cls);
}
return sb.toString();
}
}
class ClassDeclaration {
static const isAbstractFlag = 1 << 0;
static const isEnumFlag = 1 << 1;
static const hasTypeParamsFlag = 1 << 2;
static const hasTypeArgumentsFlag = 1 << 3;
static const isTransformedMixinApplicationFlag = 1 << 4;
static const hasSourcePositionsFlag = 1 << 5;
static const hasAnnotationsFlag = 1 << 6;
static const hasPragmaFlag = 1 << 7;
ObjectHandle name;
final int flags;
final ObjectHandle script;
final int position;
final int endPosition;
final TypeParametersDeclaration typeParameters;
final int numTypeArguments;
final ObjectHandle superType;
final List<ObjectHandle> interfaces;
final Members members;
final ObjectHandle annotations;
ClassDeclaration(
this.name,
this.flags,
this.script,
this.position,
this.endPosition,
this.typeParameters,
this.numTypeArguments,
this.superType,
this.interfaces,
this.members,
this.annotations);
void write(BufferedWriter writer) {
final start = writer.offset;
writer.writePackedUInt30(flags);
writer.writePackedObject(script);
if ((flags & hasSourcePositionsFlag) != 0) {
writer.writePackedUInt30(position + 1);
writer.writePackedUInt30(endPosition + 1);
}
if ((flags & hasTypeArgumentsFlag) != 0) {
writer.writePackedUInt30(numTypeArguments);
}
if ((flags & hasTypeParamsFlag) != 0) {
typeParameters.write(writer);
}
writer.writePackedObject(superType);
writer.writePackedList(interfaces);
if ((flags & hasAnnotationsFlag) != 0) {
writer.writeLinkOffset(annotations);
}
writer.writeLinkOffset(members);
BytecodeSizeStatistics.classesSize += (writer.offset - start);
}
factory ClassDeclaration.read(BufferedReader reader) {
final flags = reader.readPackedUInt30();
final script = reader.readPackedObject();
final position = ((flags & hasSourcePositionsFlag) != 0)
? reader.readPackedUInt30() - 1
: TreeNode.noOffset;
final endPosition = ((flags & hasSourcePositionsFlag) != 0)
? reader.readPackedUInt30() - 1
: TreeNode.noOffset;
final numTypeArguments =
((flags & hasTypeArgumentsFlag) != 0) ? reader.readPackedUInt30() : 0;
final typeParameters = ((flags & hasTypeParamsFlag) != 0)
? new TypeParametersDeclaration.read(reader)
: null;
final superType = reader.readPackedObject();
final interfaces = reader.readPackedList<ObjectHandle>();
final annotations = ((flags & hasAnnotationsFlag) != 0)
? reader.readLinkOffset<ObjectHandle>()
: null;
final members = reader.readLinkOffset<Members>();
return new ClassDeclaration(
null,
flags,
script,
position,
endPosition,
typeParameters,
numTypeArguments,
superType,
interfaces,
members,
annotations);
}
@override
String toString() {
final StringBuffer sb = new StringBuffer();
sb.write('Class $name, script = $script');
if ((flags & isAbstractFlag) != 0) {
sb.write(', abstract');
}
if ((flags & isEnumFlag) != 0) {
sb.write(', enum');
}
if ((flags & isTransformedMixinApplicationFlag) != 0) {
sb.write(', mixin-application');
}
if ((flags & hasPragmaFlag) != 0) {
sb.write(', has-pragma');
}
if ((flags & hasSourcePositionsFlag) != 0) {
sb.write(', pos = $position, end-pos = $endPosition');
}
sb.writeln();
if ((flags & hasTypeParamsFlag) != 0) {
sb.write(' type-params $typeParameters (args: $numTypeArguments)\n');
}
if (superType != null) {
sb.write(' extends $superType\n');
}
if (interfaces.isNotEmpty) {
sb.write(' implements $interfaces\n');
}
if ((flags & hasAnnotationsFlag) != 0) {
sb.write(' annotations $annotations\n');
}
sb.writeln();
sb.write(members.toString());
return sb.toString();
}
}
class SourceFile {
static const hasLineStartsFlag = 1 << 0;
static const hasSourceFlag = 1 << 1;
int flags;
final ObjectHandle importUri;
final LineStarts lineStarts;
final String source;
SourceFile(this.importUri, this.lineStarts, this.source) {
flags = 0;
if (lineStarts != null) {
flags |= hasLineStartsFlag;
}
if (source != null && source != '') {
flags |= hasSourceFlag;
}
}
void write(BufferedWriter writer) {
writer.writePackedUInt30(flags);
writer.writePackedObject(importUri);
if ((flags & hasLineStartsFlag) != 0) {
writer.writeLinkOffset(lineStarts);
}
if ((flags & hasSourceFlag) != 0) {
writer.writePackedStringReference(source);
}
}
factory SourceFile.read(BufferedReader reader) {
final flags = reader.readPackedUInt30();
final importUri = reader.readPackedObject();
final lineStarts = ((flags & hasLineStartsFlag) != 0)
? reader.readLinkOffset<LineStarts>()
: null;
final source = ((flags & hasSourceFlag) != 0)
? reader.readPackedStringReference()
: null;
return new SourceFile(importUri, lineStarts, source);
}
@override
String toString() {
final StringBuffer sb = new StringBuffer();
sb.writeln('SourceFile $importUri');
sb.writeln('------------------------------------------------');
sb.write(source);
sb.writeln('------------------------------------------------');
sb.writeln(lineStarts);
return sb.toString();
}
}
class Members {
final List<FieldDeclaration> fields;
@ -36,6 +279,7 @@ class Members {
}
void write(BufferedWriter writer) {
final start = writer.offset;
writer.writePackedUInt30(countFunctions());
writer.writePackedUInt30(fields.length);
for (var field in fields) {
@ -45,6 +289,7 @@ class Members {
for (var func in functions) {
func.write(writer);
}
BytecodeSizeStatistics.membersSize += (writer.offset - start);
}
factory Members.read(BufferedReader reader) {
@ -57,11 +302,8 @@ class Members {
}
@override
String toString() => "\n"
"Members {\n"
"${fields.join('\n')}\n"
"${functions.join('\n')}"
"}\n";
String toString() => "${fields.join('\n')}\n"
"${functions.join('\n')}";
}
class FieldDeclaration {
@ -164,7 +406,7 @@ class FieldDeclaration {
@override
String toString() {
StringBuffer sb = new StringBuffer();
final StringBuffer sb = new StringBuffer();
sb.write('Field $name, type = $type');
if ((flags & hasGetterFlag) != 0) {
sb.write(', getter = $getterName');
@ -195,7 +437,7 @@ class FieldDeclaration {
}
sb.writeln();
if ((flags & hasInitializerFlag) != 0) {
sb.write(' initializer $initializerCode\n');
sb.write(' initializer\n$initializerCode\n');
} else {
sb.write(' value = $value\n');
}
@ -341,7 +583,7 @@ class FunctionDeclaration {
@override
String toString() {
StringBuffer sb = new StringBuffer();
final StringBuffer sb = new StringBuffer();
sb.write('Function $name');
if ((flags & isConstructorFlag) != 0) {
sb.write(', constructor');
@ -571,7 +813,7 @@ class Code {
if (hasClosures) {
closures.forEach((c) => c.code.write(writer));
}
BytecodeSizeStatistics.membersSize += (writer.offset - start);
BytecodeSizeStatistics.codeSize += (writer.offset - start);
}
factory Code.read(BufferedReader reader) {
@ -625,8 +867,7 @@ class Code {
// TODO(alexmarkov): Consider printing constant pool before bytecode.
@override
String toString() => "\n"
"Bytecode {\n"
String toString() => "Bytecode {\n"
"${new BytecodeDisassembler().disassemble(bytecodes, exceptionsTable, annotations: [
hasSourcePositions
? sourcePositions.getBytecodeAnnotations()
@ -761,7 +1002,7 @@ class ClosureDeclaration {
@override
String toString() {
StringBuffer sb = new StringBuffer();
final StringBuffer sb = new StringBuffer();
sb.write('Closure $parent::$name');
if (position != TreeNode.noOffset) {
sb.write(' pos = $position, end-pos = $endPosition');
@ -850,7 +1091,7 @@ class ClosureCode {
String toString() {
StringBuffer sb = new StringBuffer();
sb.writeln('ClosureCode {');
sb.writeln(new BytecodeDisassembler()
sb.write(new BytecodeDisassembler()
.disassemble(bytecodes, exceptionsTable, annotations: [
hasSourcePositions
? sourcePositions.getBytecodeAnnotations()
@ -876,7 +1117,7 @@ class _Section {
class Component {
static const int magicValue = 0x44424332; // 'DBC2'
static const int numSections = 8;
static const int numSections = 13;
static const int sectionAlignment = 4;
// UInt32 magic, version, numSections x (numItems, offset)
@ -885,11 +1126,16 @@ class Component {
int version;
StringTable stringTable;
ObjectTable objectTable;
List<Members> members = <Members>[];
List<Code> codes = <Code>[];
List<SourcePositions> sourcePositions = <SourcePositions>[];
List<LocalVariableTable> localVariables = <LocalVariableTable>[];
List<ObjectHandle> annotations = <ObjectHandle>[];
final List<LibraryDeclaration> libraries = <LibraryDeclaration>[];
final List<ClassDeclaration> classes = <ClassDeclaration>[];
final List<Members> members = <Members>[];
final List<Code> codes = <Code>[];
final List<SourcePositions> sourcePositions = <SourcePositions>[];
final List<LineStarts> lineStarts = <LineStarts>[];
final List<SourceFile> sourceFiles = <SourceFile>[];
final Map<Uri, SourceFile> uriToSource = <Uri, SourceFile>{};
final List<LocalVariableTable> localVariables = <LocalVariableTable>[];
final List<ObjectHandle> annotations = <ObjectHandle>[];
ObjectHandle mainLibrary;
Component(this.version)
@ -902,58 +1148,96 @@ class Component {
// Write sections to their own buffers in reverse order as section may
// reference data structures from successor sections by offsets.
final BufferedWriter annotationsWriter =
new BufferedWriter.fromWriter(writer);
final annotationsWriter = new BufferedWriter.fromWriter(writer);
for (var annot in annotations) {
writer.linkWriter.put(annot, annotationsWriter.offset);
annotationsWriter.writePackedObject(annot);
}
BytecodeSizeStatistics.annotationsSize += annotationsWriter.offset;
final BufferedWriter localVariablesWriter =
new BufferedWriter.fromWriter(writer);
final localVariablesWriter = new BufferedWriter.fromWriter(writer);
for (var lv in localVariables) {
writer.linkWriter.put(lv, localVariablesWriter.offset);
lv.write(localVariablesWriter);
}
BytecodeSizeStatistics.localVariablesSize += localVariablesWriter.offset;
final BufferedWriter sourcePositionsWriter =
new BufferedWriter.fromWriter(writer);
final lineStartsWriter = new BufferedWriter.fromWriter(writer);
for (var ls in lineStarts) {
writer.linkWriter.put(ls, lineStartsWriter.offset);
ls.write(lineStartsWriter);
}
BytecodeSizeStatistics.lineStartsSize += lineStartsWriter.offset;
final sourceFilesWriter = new BufferedWriter.fromWriter(writer);
for (var sf in sourceFiles) {
writer.linkWriter.put(sf, sourceFilesWriter.offset);
sf.write(sourceFilesWriter);
}
BytecodeSizeStatistics.sourceFilesSize += sourceFilesWriter.offset;
final sourcePositionsWriter = new BufferedWriter.fromWriter(writer);
for (var sp in sourcePositions) {
writer.linkWriter.put(sp, sourcePositionsWriter.offset);
sp.write(sourcePositionsWriter);
}
BytecodeSizeStatistics.sourcePositionsSize += sourcePositionsWriter.offset;
final BufferedWriter codesWriter = new BufferedWriter.fromWriter(writer);
final codesWriter = new BufferedWriter.fromWriter(writer);
for (var code in codes) {
writer.linkWriter.put(code, codesWriter.offset);
code.write(codesWriter);
}
final BufferedWriter membersWriter = new BufferedWriter.fromWriter(writer);
final membersWriter = new BufferedWriter.fromWriter(writer);
for (var m in members) {
writer.linkWriter.put(m, membersWriter.offset);
m.write(membersWriter);
}
final classesWriter = new BufferedWriter.fromWriter(writer);
for (var cls in classes) {
writer.linkWriter.put(cls, classesWriter.offset);
cls.write(classesWriter);
}
final librariesWriter = new BufferedWriter.fromWriter(writer);
for (var library in libraries) {
writer.linkWriter.put(library, librariesWriter.offset);
library.write(librariesWriter);
}
final libraryIndexWriter = new BufferedWriter.fromWriter(writer);
for (var library in libraries) {
libraryIndexWriter.writePackedObject(library.importUri);
libraryIndexWriter.writeLinkOffset(library);
}
BytecodeSizeStatistics.librariesSize += libraryIndexWriter.offset;
BufferedWriter mainWriter;
if (mainLibrary != null) {
mainWriter = new BufferedWriter.fromWriter(writer);
mainWriter.writePackedObject(mainLibrary);
}
final BufferedWriter objectsWriter = new BufferedWriter.fromWriter(writer);
final objectsWriter = new BufferedWriter.fromWriter(writer);
objectTable.write(objectsWriter);
final BufferedWriter stringsWriter = new BufferedWriter.fromWriter(writer);
final stringsWriter = new BufferedWriter.fromWriter(writer);
stringTable.write(stringsWriter);
List<_Section> sections = [
new _Section(0, stringsWriter),
new _Section(0, objectsWriter),
new _Section(0, mainWriter),
new _Section(libraries.length, libraryIndexWriter),
new _Section(libraries.length, librariesWriter),
new _Section(classes.length, classesWriter),
new _Section(members.length, membersWriter),
new _Section(codes.length, codesWriter),
new _Section(sourcePositions.length, sourcePositionsWriter),
new _Section(sourceFiles.length, sourceFilesWriter),
new _Section(lineStarts.length, lineStartsWriter),
new _Section(localVariables.length, localVariablesWriter),
new _Section(annotations.length, annotationsWriter),
];
@ -1014,6 +1298,15 @@ class Component {
reader.readUInt32();
final mainOffset = reader.readUInt32();
final librariesNum = reader.readUInt32();
final libraryIndexOffset = reader.readUInt32();
reader.readUInt32();
final librariesOffset = reader.readUInt32();
final classesNum = reader.readUInt32();
final classesOffset = reader.readUInt32();
final membersNum = reader.readUInt32();
final membersOffset = reader.readUInt32();
@ -1023,6 +1316,12 @@ class Component {
final sourcePositionsNum = reader.readUInt32();
final sourcePositionsOffset = reader.readUInt32();
final sourceFilesNum = reader.readUInt32();
final sourceFilesOffset = reader.readUInt32();
final lineStartsNum = reader.readUInt32();
final lineStartsOffset = reader.readUInt32();
final localVariablesNum = reader.readUInt32();
final localVariablesOffset = reader.readUInt32();
@ -1049,6 +1348,24 @@ class Component {
annotations.add(annot);
}
final lineStartsStart = start + lineStartsOffset;
reader.offset = lineStartsStart;
for (int i = 0; i < lineStartsNum; ++i) {
int offset = reader.offset - lineStartsStart;
LineStarts ls = new LineStarts.read(reader);
reader.linkReader.setOffset(ls, offset);
lineStarts.add(ls);
}
final sourceFilesStart = start + sourceFilesOffset;
reader.offset = sourceFilesStart;
for (int i = 0; i < sourceFilesNum; ++i) {
int offset = reader.offset - sourceFilesStart;
SourceFile sf = new SourceFile.read(reader);
reader.linkReader.setOffset(sf, offset);
sourceFiles.add(sf);
}
final sourcePositionsStart = start + sourcePositionsOffset;
reader.offset = sourcePositionsStart;
for (int i = 0; i < sourcePositionsNum; ++i) {
@ -1085,22 +1402,58 @@ class Component {
members.add(m);
}
final classesStart = start + classesOffset;
reader.offset = classesStart;
for (int i = 0; i < classesNum; ++i) {
int offset = reader.offset - classesStart;
ClassDeclaration cls = new ClassDeclaration.read(reader);
reader.linkReader.setOffset(cls, offset);
classes.add(cls);
}
final librariesStart = start + librariesOffset;
reader.offset = librariesStart;
for (int i = 0; i < librariesNum; ++i) {
int offset = reader.offset - librariesStart;
LibraryDeclaration library = new LibraryDeclaration.read(reader);
reader.linkReader.setOffset(library, offset);
libraries.add(library);
}
final libraryIndexStart = start + libraryIndexOffset;
reader.offset = libraryIndexStart;
for (int i = 0; i < librariesNum; ++i) {
final importUri = reader.readPackedObject();
final library = reader.readLinkOffset<LibraryDeclaration>();
library.importUri = importUri;
}
if (mainOffset != 0) {
reader.offset = start + mainOffset;
mainLibrary = reader.readPackedObject();
}
}
String toString() => "\n"
"Bytecode"
" (version: "
"${version == currentBytecodeFormatVersion ? 'stable' : version == futureBytecodeFormatVersion ? 'future' : "v$version"}"
")\n"
// "$objectTable\n"
// "$stringTable\n"
"${mainLibrary != null ? 'Main library: $mainLibrary\n' : ''}"
// "${members.join('\n')}\n"
;
@override
String toString() {
final StringBuffer sb = new StringBuffer();
sb.write("Bytecode (version: ");
if (version == currentBytecodeFormatVersion) {
sb.write("stable");
} else if (version == futureBytecodeFormatVersion) {
sb.write("future");
} else {
sb.write("v$version");
}
sb.writeln(")");
if (mainLibrary != null) {
sb.writeln("Main library: $mainLibrary");
}
for (var library in libraries) {
sb.write(library);
}
return sb.toString();
}
}
void _writeBytecodeInstructions(BufferedWriter writer, List<int> bytecodes) {

View file

@ -8,6 +8,8 @@ library vm.bytecode.gen_bytecode;
// explicitly once constant-update-2018 is shipped.
import 'package:front_end/src/api_prototype/constant_evaluator.dart'
show ConstantEvaluator, EvaluationEnvironment, ErrorReporter;
import 'package:front_end/src/api_unstable/vm.dart'
show CompilerContext, Severity, templateIllegalRecursiveType;
import 'package:kernel/ast.dart' hide MapEntry, Component, FunctionDeclaration;
import 'package:kernel/ast.dart' as ast show Component, FunctionDeclaration;
@ -38,12 +40,15 @@ import 'generics.dart'
import 'local_variable_table.dart' show LocalVariableTable;
import 'local_vars.dart' show LocalVariables;
import 'nullability_detector.dart' show NullabilityDetector;
import 'object_table.dart' show ObjectHandle, ObjectTable, NameAndType;
import 'object_table.dart'
show ObjectHandle, ObjectTable, NameAndType, topLevelClassName;
import 'recognized_methods.dart' show RecognizedMethods;
import 'source_positions.dart' show SourcePositions;
import 'recursive_types_validator.dart' show IllegalRecursiveTypeException;
import 'source_positions.dart' show LineStarts, SourcePositions;
import '../constants_error_reporter.dart' show ForwardConstantEvaluationErrors;
import '../metadata/bytecode.dart';
import 'dart:convert' show utf8;
import 'dart:math' as math;
// This symbol is used as the name in assert assignable's to indicate it comes
@ -55,6 +60,7 @@ void generateBytecode(
ast.Component component, {
bool enableAsserts: true,
bool emitSourcePositions: false,
bool emitSourceFiles: false,
bool emitLocalVarInfo: false,
bool emitAnnotations: false,
bool omitAssertSourcePositions: false,
@ -73,22 +79,29 @@ void generateBytecode(
final constantsBackend = new VmConstantsBackend(coreTypes);
final errorReporter = new ForwardConstantEvaluationErrors();
libraries ??= component.libraries;
final bytecodeGenerator = new BytecodeGenerator(
component,
coreTypes,
hierarchy,
typeEnvironment,
constantsBackend,
environmentDefines,
enableAsserts,
emitSourcePositions,
emitLocalVarInfo,
emitAnnotations,
omitAssertSourcePositions,
useFutureBytecodeFormat,
errorReporter);
for (var library in libraries) {
bytecodeGenerator.visitLibrary(library);
try {
final bytecodeGenerator = new BytecodeGenerator(
component,
coreTypes,
hierarchy,
typeEnvironment,
constantsBackend,
environmentDefines,
enableAsserts,
emitSourcePositions,
emitSourceFiles,
emitLocalVarInfo,
emitAnnotations,
omitAssertSourcePositions,
useFutureBytecodeFormat,
errorReporter);
for (var library in libraries) {
bytecodeGenerator.visitLibrary(library);
}
} on IllegalRecursiveTypeException catch (e) {
CompilerContext.current.options.report(
templateIllegalRecursiveType.withArguments(e.type).withoutLocation(),
Severity.error);
}
}
@ -100,6 +113,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
final Map<String, String> environmentDefines;
final bool enableAsserts;
final bool emitSourcePositions;
final bool emitSourceFiles;
final bool emitLocalVarInfo;
final bool emitAnnotations;
final bool omitAssertSourcePositions;
@ -108,11 +122,13 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
final BytecodeMetadataRepository metadata = new BytecodeMetadataRepository();
final RecognizedMethods recognizedMethods;
final int formatVersion;
final Map<Uri, Source> astUriToSource;
StringTable stringTable;
ObjectTable objectTable;
Component bytecodeComponent;
NullabilityDetector nullabilityDetector;
List<ClassDeclaration> classDeclarations;
List<FieldDeclaration> fieldDeclarations;
List<FunctionDeclaration> functionDeclarations;
Class enclosingClass;
@ -152,6 +168,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
this.environmentDefines,
this.enableAsserts,
this.emitSourcePositions,
this.emitSourceFiles,
this.emitLocalVarInfo,
this.emitAnnotations,
this.omitAssertSourcePositions,
@ -160,14 +177,13 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
: recognizedMethods = new RecognizedMethods(typeEnvironment),
formatVersion = useFutureBytecodeFormat
? futureBytecodeFormatVersion
: currentBytecodeFormatVersion {
: currentBytecodeFormatVersion,
astUriToSource = component.uriToSource {
nullabilityDetector = new NullabilityDetector(recognizedMethods);
component.addMetadataRepository(metadata);
bytecodeComponent = new Component(formatVersion);
metadata.bytecodeComponent = bytecodeComponent;
metadata.mapping[component] =
new ComponentBytecodeMetadata(bytecodeComponent);
metadata.mapping[component] = new BytecodeMetadata(bytecodeComponent);
stringTable = bytecodeComponent.stringTable;
objectTable = bytecodeComponent.objectTable;
@ -185,12 +201,20 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
return;
}
visitList(node.classes, this);
startMembers();
visitList(node.procedures, this);
visitList(node.fields, this);
endMembers(node);
final members = endMembers(node);
classDeclarations = <ClassDeclaration>[
getTopLevelClassDeclaration(node, members)
];
visitList(node.classes, this);
bytecodeComponent.libraries
.add(getLibraryDeclaration(node, classDeclarations));
classDeclarations = null;
}
@override
@ -199,7 +223,9 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
visitList(node.constructors, this);
visitList(node.procedures, this);
visitList(node.fields, this);
endMembers(node);
final members = endMembers(node);
classDeclarations.add(getClassDeclaration(node, members));
}
void startMembers() {
@ -207,13 +233,159 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
functionDeclarations = <FunctionDeclaration>[];
}
void endMembers(TreeNode node) {
Members endMembers(TreeNode node) {
final members = new Members(fieldDeclarations, functionDeclarations);
bytecodeComponent.members.add(members);
metadata.mapping[node] = new MembersBytecodeMetadata(members);
fieldDeclarations = null;
functionDeclarations = null;
return members;
}
ObjectHandle getScript(Uri uri, bool includeSource) {
SourceFile source;
if (includeSource && (emitSourceFiles || emitSourcePositions)) {
source = bytecodeComponent.uriToSource[uri];
if (source == null) {
final astSource = astUriToSource[uri];
if (astSource != null) {
final importUri =
objectTable.getNameHandle(null, astSource.importUri.toString());
LineStarts lineStarts;
if (emitSourcePositions) {
lineStarts = new LineStarts(astSource.lineStarts);
bytecodeComponent.lineStarts.add(lineStarts);
}
String text = '';
if (emitSourceFiles) {
text = astSource.cachedText ??
utf8.decode(astSource.source, allowMalformed: true);
}
source = new SourceFile(importUri, lineStarts, text);
bytecodeComponent.sourceFiles.add(source);
bytecodeComponent.uriToSource[uri] = source;
}
}
}
return objectTable.getScriptHandle(uri, source);
}
LibraryDeclaration getLibraryDeclaration(
Library library, List<ClassDeclaration> classes) {
final importUri =
objectTable.getNameHandle(null, library.importUri.toString());
int flags = 0;
for (var dependency in library.dependencies) {
final targetLibrary = dependency.targetLibrary;
assert(targetLibrary != null);
if (targetLibrary == coreTypes.mirrorsLibrary) {
flags |= LibraryDeclaration.usesDartMirrorsFlag;
} else if (targetLibrary == dartFfiLibrary) {
flags |= LibraryDeclaration.usesDartFfiFlag;
}
}
final name = objectTable.getNameHandle(null, library.name ?? '');
final script = getScript(library.fileUri, true);
return new LibraryDeclaration(importUri, flags, name, script, classes);
}
ClassDeclaration getClassDeclaration(Class cls, Members members) {
int flags = 0;
if (cls.isAbstract) {
flags |= ClassDeclaration.isAbstractFlag;
}
if (cls.isEnum) {
flags |= ClassDeclaration.isEnumFlag;
}
int numTypeArguments = 0;
TypeParametersDeclaration typeParameters;
if (hasInstantiatorTypeArguments(cls)) {
flags |= ClassDeclaration.hasTypeArgumentsFlag;
numTypeArguments = flattenInstantiatorTypeArguments(
cls,
cls.typeParameters
.map((tp) => new TypeParameterType(tp))
.toList())
.length;
assert(numTypeArguments > 0);
if (cls.typeParameters.isNotEmpty) {
flags |= ClassDeclaration.hasTypeParamsFlag;
typeParameters = getTypeParametersDeclaration(cls.typeParameters);
}
}
if (cls.isEliminatedMixin) {
flags |= ClassDeclaration.isTransformedMixinApplicationFlag;
}
int position = TreeNode.noOffset;
int endPosition = TreeNode.noOffset;
if (emitSourcePositions && cls.fileOffset != TreeNode.noOffset) {
flags |= ClassDeclaration.hasSourcePositionsFlag;
position = cls.fileOffset;
endPosition = cls.fileEndOffset;
}
Annotations annotations = getAnnotations(cls.annotations);
if (annotations.object != null) {
flags |= ClassDeclaration.hasAnnotationsFlag;
if (annotations.hasPragma) {
flags |= ClassDeclaration.hasPragmaFlag;
}
}
final nameHandle = objectTable.getNameHandle(
cls.name.startsWith('_') ? cls.enclosingLibrary : null, cls.name);
final script = getScript(cls.fileUri, !cls.isAnonymousMixin);
final superType = objectTable.getHandle(cls.supertype?.asInterfaceType);
final interfaces = objectTable.getHandles(
cls.implementedTypes.map((t) => t.asInterfaceType).toList());
final classDeclaration = new ClassDeclaration(
nameHandle,
flags,
script,
position,
endPosition,
typeParameters,
numTypeArguments,
superType,
interfaces,
members,
annotations.object);
bytecodeComponent.classes.add(classDeclaration);
return classDeclaration;
}
ClassDeclaration getTopLevelClassDeclaration(
Library library, Members members) {
int flags = 0;
int position = TreeNode.noOffset;
if (emitSourcePositions && library.fileOffset != TreeNode.noOffset) {
flags |= ClassDeclaration.hasSourcePositionsFlag;
position = library.fileOffset;
}
Annotations annotations = getAnnotations(library.annotations);
if (annotations.object != null) {
flags |= ClassDeclaration.hasAnnotationsFlag;
if (annotations.hasPragma) {
flags |= ClassDeclaration.hasPragmaFlag;
}
}
final nameHandle = objectTable.getNameHandle(null, topLevelClassName);
final script = getScript(library.fileUri, true);
final classDeclaration = new ClassDeclaration(
nameHandle,
flags,
script,
position,
/* endPosition */ TreeNode.noOffset,
/* typeParameters */ null,
/* numTypeArguments */ 0,
/* superType */ null,
/* interfaces */ const <ObjectHandle>[],
members,
annotations.object);
bytecodeComponent.classes.add(classDeclaration);
return classDeclaration;
}
bool _isPragma(Constant annotation) =>
@ -224,7 +396,14 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
if (nodes.isEmpty) {
return const Annotations(null, false);
}
final savedConstantEvaluator = constantEvaluator;
if (constantEvaluator == null) {
constantEvaluator = new ConstantEvaluator(constantsBackend,
environmentDefines, typeEnvironment, enableAsserts, errorReporter)
..env = new EvaluationEnvironment();
}
List<Constant> constants = nodes.map(_evaluateConstantExpression).toList();
constantEvaluator = savedConstantEvaluator;
bool hasPragma = constants.any(_isPragma);
if (!emitAnnotations) {
if (hasPragma) {
@ -673,6 +852,10 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
_asyncAwaitCompleterGetFuture ??= libraryIndex.getMember(
'dart:async', '_AsyncAwaitCompleter', 'get:future');
Library _dartFfiLibrary;
Library get dartFfiLibrary =>
_dartFfiLibrary ??= libraryIndex.tryGetLibrary('dart:ffi');
void _recordSourcePosition(int fileOffset) {
if (emitSourcePositions) {
asm.currentSourcePosition = fileOffset;
@ -3535,3 +3718,15 @@ class Annotations {
const Annotations(this.object, this.hasPragma);
}
ast.Component createFreshComponentWithBytecode(ast.Component component) {
final newComponent = new ast.Component();
final newRepository = new BytecodeMetadataRepository();
newComponent.addMetadataRepository(newRepository);
final oldRepository = component.metadata[newRepository.tag];
final metadata = oldRepository.mapping[component];
newRepository.mapping[newComponent] = metadata;
return newComponent;
}

View file

@ -152,93 +152,6 @@ class FindFreeTypeParametersVisitor extends DartTypeVisitor<bool> {
}
}
/// Returns true if the given type is recursive after its type arguments
/// are flattened.
bool isRecursiveAfterFlattening(InterfaceType type) {
final visitor = new IsRecursiveAfterFlatteningVisitor();
visitor.visit(type);
return visitor.isRecursive(type);
}
class IsRecursiveAfterFlatteningVisitor extends DartTypeVisitor<void> {
Set<DartType> _visited = new Set<DartType>();
List<DartType> _stack = <DartType>[];
Set<DartType> _recursive;
bool isRecursive(DartType type) =>
_recursive != null && _recursive.contains(type);
void visit(DartType type) {
if (!_visited.add(type)) {
_recordRecursiveType(type);
return;
}
_stack.add(type);
type.accept(this);
_stack.removeLast();
_visited.remove(type);
}
void _recordRecursiveType(DartType type) {
final int start = _stack.lastIndexOf(type);
final recursive = (_recursive ??= new Set<DartType>());
for (int i = start; i < _stack.length; ++i) {
recursive.add(_stack[i]);
}
}
@override
void defaultDartType(DartType node) =>
throw 'Unexpected type ${node.runtimeType} $node';
@override
void visitInvalidType(InvalidType node) {}
@override
void visitDynamicType(DynamicType node) {}
@override
void visitVoidType(VoidType node) {}
@override
void visitBottomType(BottomType node) {}
@override
void visitTypeParameterType(TypeParameterType node) {}
@override
void visitInterfaceType(InterfaceType node) {
for (var typeArg in node.typeArguments) {
visit(typeArg);
}
if (isRecursive(node)) {
return;
}
final flatTypeArgs =
flattenInstantiatorTypeArguments(node.classNode, node.typeArguments);
for (var typeArg in flatTypeArgs.getRange(
0, flatTypeArgs.length - node.typeArguments.length)) {
visit(typeArg);
}
}
@override
void visitTypedefType(TypedefType node) => visit(node.unalias);
@override
void visitFunctionType(FunctionType node) {
for (var p in node.positionalParameters) {
visit(p);
}
for (var p in node.namedParameters) {
visit(p.type);
}
visit(node.returnType);
}
}
/// Returns static type of [expr].
DartType getStaticType(Expression expr, TypeEnvironment typeEnvironment) {
// TODO(dartbug.com/34496): Remove this try/catch once

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,175 @@
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library vm.bytecode.recursive_types_validator;
import 'package:kernel/ast.dart' hide MapEntry;
import 'package:kernel/type_algebra.dart' show Substitution;
import 'generics.dart'
show flattenInstantiatorTypeArguments, hasFreeTypeParameters;
/// Detect recursive types and validates that finalized (flattened)
/// representation of generic types is valid (finite).
class RecursiveTypesValidator {
final Set<DartType> _validatedTypes = <DartType>{};
final Set<DartType> _recursiveTypes = <DartType>{};
final Set<Class> _validatedClases = <Class>{};
/// Validates [type].
void validateType(DartType type) {
if (!isValidated(type)) {
final visitor = new _RecursiveTypesVisitor(this);
visitor.visit(type);
_validatedTypes.addAll(visitor.validated);
_recursiveTypes.addAll(visitor.recursive);
}
}
bool isValidated(DartType type) => _validatedTypes.contains(type);
/// Returns true if [type] is recursive.
/// Should be called only after validating [type].
bool isRecursive(DartType type) {
assert(isValidated(type));
return _recursiveTypes.contains(type);
}
void validateClass(Class cls) {
if (_validatedClases.add(cls)) {
try {
validateType(cls.thisType);
} on IllegalRecursiveTypeException catch (e) {
_validatedClases.remove(cls);
throw e;
}
}
}
}
class IllegalRecursiveTypeException {
final DartType type;
IllegalRecursiveTypeException(this.type);
}
class _RecursiveTypesVisitor extends DartTypeVisitor<void> {
final RecursiveTypesValidator validator;
final Set<DartType> validated = <DartType>{};
final Set<DartType> recursive = <DartType>{};
final Set<DartType> _visited = new Set<DartType>();
final List<DartType> _stack = <DartType>[];
_RecursiveTypesVisitor(this.validator);
void visit(DartType type) {
if (validator.isValidated(type)) {
return;
}
if (!_visited.add(type)) {
final int start = _stack.lastIndexOf(type);
_verifyRecursiveType(start, type);
for (int i = start; i < _stack.length; ++i) {
recursive.add(_stack[i]);
}
return;
}
_stack.add(type);
type.accept(this);
_stack.removeLast();
_visited.remove(type);
validated.add(type);
}
@override
void defaultDartType(DartType node) =>
throw 'Unexpected type ${node.runtimeType} $node';
@override
void visitInvalidType(InvalidType node) {}
@override
void visitDynamicType(DynamicType node) {}
@override
void visitVoidType(VoidType node) {}
@override
void visitBottomType(BottomType node) {}
@override
void visitTypeParameterType(TypeParameterType node) {}
@override
void visitInterfaceType(InterfaceType node) {
// Validate class declaration type separately
// to avoid failures due to types in the current _stack.
validator.validateClass(node.classNode);
for (var typeArg in node.typeArguments) {
visit(typeArg);
}
final flatTypeArgs =
flattenInstantiatorTypeArguments(node.classNode, node.typeArguments);
for (var typeArg in flatTypeArgs.getRange(
0, flatTypeArgs.length - node.typeArguments.length)) {
visit(typeArg);
}
}
@override
void visitTypedefType(TypedefType node) => visit(node.unalias);
@override
void visitFunctionType(FunctionType node) {
for (var p in node.positionalParameters) {
visit(p);
}
for (var p in node.namedParameters) {
visit(p.type);
}
visit(node.returnType);
}
void _verifyRecursiveType(int start, DartType type) {
if (type is InterfaceType) {
if (!hasFreeTypeParameters(type.typeArguments)) {
return;
}
for (int i = start + 1; i < _stack.length; ++i) {
final other = _stack[i];
if (other is InterfaceType &&
other.classNode == type.classNode &&
hasFreeTypeParameters(other.typeArguments)) {
if (!listEquals(_eraseTypeParameters(type.typeArguments),
_eraseTypeParameters(other.typeArguments))) {
throw IllegalRecursiveTypeException(type);
}
}
}
} else {
throw 'Unexpected recursive type ${type.runtimeType} $type';
}
}
List<DartType> _eraseTypeParameters(List<DartType> typeArgs) {
return typeArgs
.map((DartType t) =>
const _EraseTypeParametersToDynamic().substituteType(t))
.toList();
}
}
class _EraseTypeParametersToDynamic extends Substitution {
const _EraseTypeParametersToDynamic();
DartType getSubstitute(TypeParameter parameter, bool upperBound) {
return const DynamicType();
}
}

View file

@ -60,3 +60,29 @@ class SourcePositions {
new MapEntry(pc, 'source position $fileOffset'));
}
}
/// Keeps file offsets of line starts. This information is used to
/// decode source positions to line/column.
class LineStarts {
final List<int> lineStarts;
LineStarts(this.lineStarts);
void write(BufferedWriter writer) {
writer.writePackedUInt30(lineStarts.length);
final encodeLineStarts = new PackedUInt30DeltaEncoder();
for (int lineStart in lineStarts) {
encodeLineStarts.write(writer, lineStart);
}
}
factory LineStarts.read(BufferedReader reader) {
final decodeLineStarts = new PackedUInt30DeltaDecoder();
final lineStarts = new List<int>.generate(
reader.readPackedUInt30(), (_) => decodeLineStarts.read(reader));
return new LineStarts(lineStarts);
}
@override
String toString() => 'Line starts: $lineStarts';
}

View file

@ -45,9 +45,9 @@ import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/target/targets.dart' show Target, TargetFlags, getTarget;
import 'package:kernel/vm/constants_native_effects.dart' as vm_constants;
import 'bytecode/ast_remover.dart' show ASTRemover;
import 'bytecode/bytecode_serialization.dart' show BytecodeSizeStatistics;
import 'bytecode/gen_bytecode.dart' show generateBytecode;
import 'bytecode/gen_bytecode.dart'
show generateBytecode, createFreshComponentWithBytecode;
import 'constants_error_reporter.dart' show ForwardConstantEvaluationErrors;
import 'target/install.dart' show installAdditionalTargets;
@ -306,7 +306,7 @@ Future<Component> compileToKernel(Uri source, CompilerOptions options,
options.onDiagnostic = errorDetector;
setVMEnvironmentDefines(environmentDefines, options);
final component = await kernelForProgram(source, options);
Component component = await kernelForProgram(source, options);
// Run global transformations only if component is correct.
if (aot && component != null) {
@ -327,6 +327,7 @@ Future<Component> compileToKernel(Uri source, CompilerOptions options,
generateBytecode(component,
enableAsserts: enableAsserts,
emitSourcePositions: emitBytecodeSourcePositions,
emitSourceFiles: options.embedSourceText,
emitLocalVarInfo: emitBytecodeLocalVarInfo,
emitAnnotations: emitBytecodeAnnotations,
useFutureBytecodeFormat: useFutureBytecodeFormat,
@ -334,7 +335,7 @@ Future<Component> compileToKernel(Uri source, CompilerOptions options,
});
if (dropAST) {
new ASTRemover(component).visitComponent(component);
component = createFreshComponentWithBytecode(component);
}
}
@ -717,7 +718,7 @@ Future writeOutputSplitByPackages(
component.problemsAsJson = null;
}
ASTRemover astRemover;
Component partComponent = component;
if (genBytecode) {
final List<Library> libraries = component.libraries
.where((lib) => packageFor(lib) == package)
@ -727,26 +728,21 @@ Future writeOutputSplitByPackages(
hierarchy: hierarchy,
enableAsserts: enableAsserts,
emitSourcePositions: emitBytecodeSourcePositions,
emitSourceFiles: compilerOptions.embedSourceText,
emitLocalVarInfo: emitBytecodeLocalVarInfo,
emitAnnotations: emitBytecodeAnnotations,
useFutureBytecodeFormat: useFutureBytecodeFormat,
environmentDefines: environmentDefines);
if (dropAST) {
astRemover = new ASTRemover(component);
for (var library in libraries) {
astRemover.visitLibrary(library);
}
partComponent = createFreshComponentWithBytecode(component);
}
}
final BinaryPrinter printer = new LimitedBinaryPrinter(sink,
(lib) => packageFor(lib) == package, false /* excludeUriToSource */);
printer.writeComponentFile(component);
printer.writeComponentFile(partComponent);
if (genBytecode && dropAST) {
astRemover.restoreAST();
}
component.mainMethod = main;
component.problemsAsJson = problems;

View file

@ -6,53 +6,26 @@ library vm.metadata.bytecode;
import 'package:kernel/ast.dart'
show BinarySink, BinarySource, MetadataRepository, Node, TreeNode;
import 'package:kernel/ast.dart' as ast show Component;
import '../bytecode/bytecode_serialization.dart'
show BufferedWriter, BufferedReader, LinkWriter, LinkReader;
import '../bytecode/declarations.dart' show Component, Members;
import '../bytecode/declarations.dart' show Component;
abstract class BytecodeMetadata {
void write(BufferedWriter writer);
}
class MembersBytecodeMetadata extends BytecodeMetadata {
final Members members;
MembersBytecodeMetadata(this.members);
@override
void write(BufferedWriter writer) {
writer.writeLinkOffset(members);
}
factory MembersBytecodeMetadata.read(BufferedReader reader) {
return new MembersBytecodeMetadata(reader.readLinkOffset<Members>());
}
@override
String toString() => "\n"
"MembersBytecodeMetadata {\n"
"$members\n"
"}\n";
}
class ComponentBytecodeMetadata extends BytecodeMetadata {
class BytecodeMetadata {
final Component component;
ComponentBytecodeMetadata(this.component);
BytecodeMetadata(this.component);
@override
void write(BufferedWriter writer) {
component.write(writer);
}
factory ComponentBytecodeMetadata.read(BufferedReader reader) {
return new ComponentBytecodeMetadata(new Component.read(reader));
factory BytecodeMetadata.read(BufferedReader reader) {
return new BytecodeMetadata(new Component.read(reader));
}
@override
String toString() => "\n"
"ComponentBytecodeMetadata {\n"
"BytecodeMetadata {\n"
"$component\n"
"}\n";
}
@ -66,19 +39,10 @@ class BytecodeMetadataRepository extends MetadataRepository<BytecodeMetadata> {
final Map<TreeNode, BytecodeMetadata> mapping =
<TreeNode, BytecodeMetadata>{};
Component bytecodeComponent;
LinkWriter linkWriter;
LinkReader linkReader;
@override
void writeToBinary(BytecodeMetadata metadata, Node node, BinarySink sink) {
if (node is ast.Component) {
bytecodeComponent = (metadata as ComponentBytecodeMetadata).component;
linkWriter = new LinkWriter();
} else {
assert(bytecodeComponent != null);
assert(linkWriter != null);
}
final bytecodeComponent = metadata.component;
final linkWriter = new LinkWriter();
final writer = new BufferedWriter(
bytecodeComponent.version,
bytecodeComponent.stringTable,
@ -91,22 +55,10 @@ class BytecodeMetadataRepository extends MetadataRepository<BytecodeMetadata> {
@override
BytecodeMetadata readFromBinary(Node node, BinarySource source) {
if (node is ast.Component) {
linkReader = new LinkReader();
final reader = new BufferedReader(
-1, null, null, linkReader, source.bytes,
baseOffset: source.currentOffset);
bytecodeComponent = new Component.read(reader);
return new ComponentBytecodeMetadata(bytecodeComponent);
} else {
final reader = new BufferedReader(
bytecodeComponent.version,
bytecodeComponent.stringTable,
bytecodeComponent.objectTable,
linkReader,
source.bytes,
baseOffset: source.currentOffset);
return new MembersBytecodeMetadata.read(reader);
}
final linkReader = new LinkReader();
final reader = new BufferedReader(-1, null, null, linkReader, source.bytes,
baseOffset: source.currentOffset);
final bytecodeComponent = new Component.read(reader);
return new BytecodeMetadata(bytecodeComponent);
}
}

View file

@ -6,13 +6,16 @@ import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/testing/mock_sdk_component.dart';
import 'package:test/test.dart';
import 'package:vm/bytecode/generics.dart';
import 'package:expect/expect.dart';
import 'package:vm/bytecode/recursive_types_validator.dart';
main() {
Library lib;
Supertype objectSuper;
DartType intType;
DartType doubleType;
Class base;
RecursiveTypesValidator validator;
Class addClass(String name, List<TypeParameter> typeParameters) {
Class cls = new Class(
@ -27,6 +30,7 @@ main() {
CoreTypes coreTypes = new CoreTypes(component);
objectSuper = coreTypes.objectClass.asThisSupertype;
intType = new InterfaceType(coreTypes.intClass);
doubleType = new InterfaceType(coreTypes.doubleClass);
// Add the test library.
lib = new Library(Uri.parse('org-dartlang:///test.dart'), name: 'lib');
@ -35,11 +39,13 @@ main() {
// class Base<T>
base = addClass('Base', [new TypeParameter('T')]);
validator = new RecursiveTypesValidator();
});
tearDown(() {});
test('isRecursiveAfterFlattening-00', () async {
test('simple-recursive-type', () async {
// class Derived<T> extends Base<Derived<T>>
TypeParameter t = new TypeParameter('T');
Class derived = addClass('Derived', [t]);
@ -48,11 +54,14 @@ main() {
DartType derivedOfInt = new InterfaceType(derived, [intType]);
derived.supertype = new Supertype(base, [derivedOfT]);
expect(isRecursiveAfterFlattening(derivedOfT), isTrue);
expect(isRecursiveAfterFlattening(derivedOfInt), isTrue);
validator.validateType(derivedOfT);
Expect.isTrue(validator.isRecursive(derivedOfT));
validator.validateType(derivedOfInt);
Expect.isTrue(validator.isRecursive(derivedOfInt));
});
test('isRecursiveAfterFlattening-01', () async {
test('recursive-type-extends-instantiated', () async {
// class Derived<T> extends Base<Derived<Derived<int>>>
TypeParameter t = new TypeParameter('T');
Class derived = addClass('Derived', [t]);
@ -62,11 +71,15 @@ main() {
DartType derivedOfDerivedOfInt = new InterfaceType(derived, [derivedOfInt]);
derived.supertype = new Supertype(base, [derivedOfDerivedOfInt]);
expect(isRecursiveAfterFlattening(derivedOfT), isFalse);
expect(isRecursiveAfterFlattening(derivedOfInt), isTrue);
validator.validateType(derivedOfT);
validator.validateType(derivedOfInt);
Expect.isFalse(validator.isRecursive(derivedOfT));
Expect.isTrue(validator.isRecursive(derivedOfInt));
Expect.isTrue(validator.isRecursive(derivedOfDerivedOfInt));
});
test('isRecursiveAfterFlattening-02', () async {
test('recursive-non-contractive-type', () async {
// class Derived<T> extends Base<Derived<Derived<T>>>
TypeParameter t = new TypeParameter('T');
Class derived = addClass('Derived', [t]);
@ -76,11 +89,18 @@ main() {
DartType derivedOfDerivedOfT = new InterfaceType(derived, [derivedOfT]);
derived.supertype = new Supertype(base, [derivedOfDerivedOfT]);
expect(isRecursiveAfterFlattening(derivedOfT), isTrue);
expect(isRecursiveAfterFlattening(derivedOfInt), isTrue);
Expect.throws(() {
validator.validateType(derivedOfT);
});
Expect.throws(() {
validator.validateType(derivedOfDerivedOfT);
});
Expect.throws(() {
validator.validateType(derivedOfInt);
});
});
test('isRecursiveAfterFlattening-03', () async {
test('mutually-recursive-types', () async {
// class Derived1<U> extends Base<Derived2<U>>
// class Derived2<V> extends Base<Derived1<V>>
TypeParameter u = new TypeParameter('U');
@ -105,9 +125,40 @@ main() {
new InterfaceType(derived2, [new TypeParameterType(v)]);
DartType derived2OfInt = new InterfaceType(derived2, [intType]);
expect(isRecursiveAfterFlattening(derived1OfU), isTrue);
expect(isRecursiveAfterFlattening(derived1OfInt), isTrue);
expect(isRecursiveAfterFlattening(derived2OfV), isTrue);
expect(isRecursiveAfterFlattening(derived2OfInt), isTrue);
validator.validateType(derived1OfU);
Expect.isTrue(validator.isRecursive(derived1OfU));
validator.validateType(derived1OfInt);
Expect.isTrue(validator.isRecursive(derived1OfInt));
validator.validateType(derived2OfV);
Expect.isTrue(validator.isRecursive(derived2OfV));
validator.validateType(derived2OfInt);
Expect.isTrue(validator.isRecursive(derived2OfInt));
});
test('recursive-two-type-params', () async {
// class F<P1, P2> {}
// class E<Q1, Q2> extends F<E<Q1, int>, Q2> {}
TypeParameter p1 = new TypeParameter('P1');
TypeParameter p2 = new TypeParameter('P2');
Class f = addClass('F', [p1, p2]);
TypeParameter q1 = new TypeParameter('Q1');
TypeParameter q2 = new TypeParameter('Q2');
Class e = addClass('E', [q1, q2]);
DartType eOfQ1Int =
new InterfaceType(e, [new TypeParameterType(q1), intType]);
e.supertype = new Supertype(f, [eOfQ1Int, new TypeParameterType(q2)]);
DartType eOfIntDouble = new InterfaceType(e, [intType, doubleType]);
validator.validateType(eOfIntDouble);
validator.validateType(e.thisType);
Expect.isFalse(validator.isRecursive(eOfIntDouble));
Expect.isFalse(validator.isRecursive(e.thisType));
});
}

View file

@ -1,21 +1,19 @@
main = #lib::main;
[@vm.bytecode=
ComponentBytecodeMetadata {
BytecodeMetadata {
Bytecode (version: stable)
Main library: #lib
Library '#lib'
name '#lib'
script '#lib'
}
] [@vm.bytecode=
MembersBytecodeMetadata {
Class '', script = '#lib'
Members {
Function 'test1', static, reflectable, debuggable
parameters [dart:core::bool 'condition'] (required: 1)
return-type void
Bytecode {
Entry 0
CheckStack 0
@ -42,7 +40,6 @@ Function 'test2', static, reflectable, debuggable
parameters [FunctionType () -> dart:core::bool 'condition', FunctionType () -> dart:core::String 'message'] (required: 2)
return-type void
Bytecode {
Entry 0
CheckStack 0
@ -74,7 +71,6 @@ Function 'main', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -84,7 +80,6 @@ Bytecode {
ConstantPool {
}
}
}
]library #lib from "#lib" as #lib {

View file

@ -1,17 +1,16 @@
main = #lib::main;
[@vm.bytecode=
ComponentBytecodeMetadata {
BytecodeMetadata {
Bytecode (version: stable)
Main library: #lib
Library '#lib'
name '#lib'
script '#lib'
}
] [@vm.bytecode=
MembersBytecodeMetadata {
Class '', script = '#lib'
Members {
Field 'asyncInFieldInitializer', type = FunctionType (dart:async::Future < dart:core::int >) -> dart:async::Future < dart:core::Null >, getter = 'get:asyncInFieldInitializer', reflectable, static
initializer
initializer
Bytecode {
Entry 3
CheckStack 0
@ -167,7 +166,6 @@ ClosureCode {
LoadContextVar 0, 1
InterfaceCall CP#37, 1
ReturnTOS
}
Closure #lib::asyncInFieldInitializer (field)::Closure/0::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
@ -255,7 +253,6 @@ L1:
LoadContextVar 0, 6
PopLocal r4
Jump L4
}
@ -263,7 +260,6 @@ Function 'foo', static, reflectable, async
parameters [] (required: 0)
return-type dart:async::Future < dart:core::int >
Bytecode {
Entry 7
CheckStack 0
@ -420,7 +416,6 @@ L3:
ReturnTOS
L1:
Trap
}
@ -428,7 +423,6 @@ Function 'simpleAsyncAwait', static, reflectable, async
parameters [dart:async::Future < dart:core::int > 'a', dart:async::Future < dart:core::int > 'b'] (required: 2)
return-type dart:async::Future < dart:core::int >
Bytecode {
Entry 4
CheckStack 0
@ -677,7 +671,6 @@ L1:
PushInt 1
JumpIfEqStrict L6
Jump L7
}
@ -685,7 +678,6 @@ Function 'loops', static, reflectable, async
parameters [dart:core::List < dart:core::int > 'list'] (required: 1)
return-type dart:async::Future < dart:core::int >
Bytecode {
Entry 4
CheckStack 0
@ -1058,7 +1050,6 @@ L1:
LoadContextVar 0, 6
PopLocal r4
Jump L11
}
@ -1066,7 +1057,6 @@ Function 'tryCatchRethrow', static, reflectable, async
parameters [dart:async::Future < dart:core::int > 'a', dart:async::Future < dart:core::int > 'b', dart:async::Future < dart:core::int > 'c'] (required: 3)
return-type dart:async::Future < dart:core::int >
Bytecode {
Entry 4
CheckStack 0
@ -1637,7 +1627,6 @@ L1:
PushInt 4
JumpIfEqStrict L16
Jump L17
}
@ -1645,7 +1634,6 @@ Function 'closure', static, reflectable, debuggable
parameters [dart:async::Future < dart:core::int > 'a'] (required: 1)
return-type dynamic
Bytecode {
Entry 4
CheckStack 0
@ -1808,7 +1796,6 @@ ClosureCode {
LoadContextVar 1, 0
InterfaceCall CP#37, 1
ReturnTOS
}
Closure #lib::closure::Closure/0::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
@ -1966,7 +1953,6 @@ L1:
LoadContextVar 1, 5
PopLocal r4
Jump L6
}
@ -1974,7 +1960,6 @@ Function 'testAssert', static, reflectable, async
parameters [dart:async::Future < dart:core::int > 'a'] (required: 1)
return-type dart:async::Future < dart:core::int >
Bytecode {
Entry 4
CheckStack 0
@ -2198,7 +2183,6 @@ L1:
LoadContextVar 0, 6
PopLocal r4
Jump L6
}
@ -2206,7 +2190,6 @@ Function 'main', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -2216,7 +2199,6 @@ Bytecode {
ConstantPool {
}
}
}
]library #lib from "#lib" as #lib {

View file

@ -1,15 +1,14 @@
main = #lib::main;
[@vm.bytecode=
ComponentBytecodeMetadata {
BytecodeMetadata {
Bytecode (version: stable)
Main library: #lib
Library '#lib'
name '#lib'
script '#lib'
}
] [@vm.bytecode=
MembersBytecodeMetadata {
Class '', script = '#lib'
Members {
Field '_stdinFD', type = dart:core::int, reflectable, static
value = const 0
@ -29,7 +28,6 @@ Function '_printString', static, reflectable, debuggable, native 'Builtin_PrintS
parameters [dart:core::String 's'] (required: 1)
return-type void
Bytecode {
Entry 0
CheckStack 0
@ -46,7 +44,6 @@ Function '_print', static, reflectable, debuggable
parameters [dynamic 'arg'] (required: 1)
return-type void
Bytecode {
Entry 0
CheckStack 0
@ -69,7 +66,6 @@ Function '_getPrintClosure', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -85,7 +81,6 @@ Function '_setScheduleImmediateClosure', static, reflectable, debuggable
parameters [FunctionType (FunctionType () -> void) -> void 'closure'] (required: 1)
return-type void
Bytecode {
Entry 1
CheckStack 0
@ -103,7 +98,6 @@ Function '_setStdioFDs', static, reflectable, debuggable
parameters [dart:core::int 'stdin', dart:core::int 'stdout', dart:core::int 'stderr'] (required: 3)
return-type void
Bytecode {
Entry 1
CheckStack 0
@ -127,7 +121,6 @@ Function '_scriptUri', static, reflectable, debuggable
parameters [] (required: 0)
return-type dart:core::Uri
Bytecode {
Entry 2
CheckStack 0
@ -198,7 +191,6 @@ Function '_setupHooks', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 1
CheckStack 0
@ -219,7 +211,6 @@ Function 'get:stdin', getter, static, reflectable, debuggable
parameters [] (required: 0)
return-type #lib::Stdin
Bytecode {
Entry 2
CheckStack 0
@ -257,7 +248,6 @@ Function 'main', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -267,16 +257,9 @@ Bytecode {
ConstantPool {
}
}
Class '_ScheduleImmediate', script = '#lib'
extends dart:core::Object
}
]library #lib from "#lib" as #lib {
typedef _ScheduleImmediateClosure = (() → void) → void;
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Field '_closure', type = FunctionType (FunctionType () -> void) -> void, reflectable, static
value = null
@ -284,7 +267,6 @@ Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::_ScheduleImmediate
Bytecode {
Entry 0
CheckStack 0
@ -299,19 +281,10 @@ ConstantPool {
[1] = Reserved
}
}
Class '_NamespaceImpl', script = '#lib'
extends dart:core::Object
implements [#lib::_Namespace]
}
] class _ScheduleImmediate extends dart.core::Object {
static field (() → void) → void _closure = null;
synthetic constructor •() → #lib::_ScheduleImmediate
: super dart.core::Object::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Field '_cachedNamespace', type = #lib::_NamespaceImpl, reflectable, static
value = null
@ -319,7 +292,6 @@ Function '_', constructor, reflectable, debuggable
parameters [] (required: 0)
return-type #lib::_NamespaceImpl
Bytecode {
Entry 0
CheckStack 0
@ -339,7 +311,6 @@ Function '_create', static, reflectable, debuggable, native 'Namespace_Create'
parameters [#lib::_NamespaceImpl 'namespace', dynamic 'n'] (required: 2)
return-type #lib::_NamespaceImpl
Bytecode {
Entry 0
CheckStack 0
@ -357,7 +328,6 @@ Function '_getPointer', static, reflectable, debuggable, native 'Namespace_GetPo
parameters [#lib::_NamespaceImpl 'namespace'] (required: 1)
return-type dart:core::int
Bytecode {
Entry 0
CheckStack 0
@ -374,7 +344,6 @@ Function '_getDefault', static, reflectable, debuggable, native 'Namespace_GetDe
parameters [] (required: 0)
return-type dart:core::int
Bytecode {
Entry 0
CheckStack 0
@ -390,7 +359,6 @@ Function '_setupNamespace', static, reflectable, debuggable
parameters [dynamic 'namespace'] (required: 1)
return-type void
Bytecode {
Entry 2
CheckStack 0
@ -419,7 +387,6 @@ Function 'get:_namespace', getter, static, reflectable, debuggable
parameters [] (required: 0)
return-type #lib::_NamespaceImpl
Bytecode {
Entry 2
CheckStack 0
@ -456,7 +423,6 @@ Function 'get:_namespacePointer', getter, static, reflectable, debuggable
parameters [] (required: 0)
return-type dart:core::int
Bytecode {
Entry 0
CheckStack 0
@ -471,42 +437,14 @@ ConstantPool {
[3] = Reserved
}
}
Class '_Namespace', script = '#lib'
extends dart:core::Object
}
] class _NamespaceImpl extends dart.core::Object implements #lib::_Namespace {
static field #lib::_NamespaceImpl _cachedNamespace = null;
constructor _() → #lib::_NamespaceImpl
: super dart.core::Object::•()
;
@dart._internal::ExternalName::•("Namespace_Create")
external static method _create(#lib::_NamespaceImpl namespace, dynamic n) → #lib::_NamespaceImpl;
@dart._internal::ExternalName::•("Namespace_GetPointer")
external static method _getPointer(#lib::_NamespaceImpl namespace) → dart.core::int;
@dart._internal::ExternalName::•("Namespace_GetDefault")
external static method _getDefault() → dart.core::int;
static method _setupNamespace(dynamic namespace) → void {
#lib::_NamespaceImpl::_cachedNamespace = #lib::_NamespaceImpl::_create(new #lib::_NamespaceImpl::_(), namespace);
}
static get _namespace() → #lib::_NamespaceImpl {
if(#lib::_NamespaceImpl::_cachedNamespace.{dart.core::Object::==}(null)) {
#lib::_NamespaceImpl::_cachedNamespace = #lib::_NamespaceImpl::_create(new #lib::_NamespaceImpl::_(), #lib::_NamespaceImpl::_getDefault());
}
return #lib::_NamespaceImpl::_cachedNamespace;
}
static get _namespacePointer() → dart.core::int
return #lib::_NamespaceImpl::_getPointer(#lib::_NamespaceImpl::_namespace);
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::_Namespace
Bytecode {
Entry 0
CheckStack 0
@ -526,7 +464,6 @@ Function '_setupNamespace', static, reflectable, debuggable
parameters [dynamic 'namespace'] (required: 1)
return-type void
Bytecode {
Entry 0
CheckStack 0
@ -546,7 +483,6 @@ Function 'get:_namespace', getter, static, reflectable, debuggable
parameters [] (required: 0)
return-type #lib::_Namespace
Bytecode {
Entry 0
CheckStack 0
@ -563,7 +499,6 @@ Function 'get:_namespacePointer', getter, static, reflectable, debuggable
parameters [] (required: 0)
return-type dart:core::int
Bytecode {
Entry 0
CheckStack 0
@ -575,25 +510,9 @@ ConstantPool {
[1] = Reserved
}
}
Class 'VMLibraryHooks', script = '#lib'
extends dart:core::Object
}
] class _Namespace extends dart.core::Object {
synthetic constructor •() → #lib::_Namespace
: super dart.core::Object::•()
;
static method _setupNamespace(dynamic namespace) → void {
#lib::_NamespaceImpl::_setupNamespace(namespace);
}
static get _namespace() → #lib::_Namespace
return #lib::_NamespaceImpl::_namespace;
static get _namespacePointer() → dart.core::int
return #lib::_NamespaceImpl::_namespacePointer;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Field 'timerFactory', type = dynamic, reflectable, static
value = null
@ -631,7 +550,6 @@ Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::VMLibraryHooks
Bytecode {
Entry 0
CheckStack 0
@ -651,7 +569,6 @@ Function 'set:platformScript', setter, static, reflectable, debuggable
parameters [dynamic 'f'] (required: 1)
return-type void
Bytecode {
Entry 1
CheckStack 0
@ -672,7 +589,6 @@ Function 'get:platformScript', getter, static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 1
CheckStack 0
@ -708,10 +624,111 @@ ConstantPool {
[3] = ICData dynamic target-name 'call', arg-desc CP#2
}
Class 'Stdin', script = '#lib'
extends dart:core::Object
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::Stdin
Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
}
ConstantPool {
[0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
[1] = Reserved
}
Class '_StdIOUtils', script = '#lib'
extends dart:core::Object
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::_StdIOUtils
Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
}
] class VMLibraryHooks extends dart.core::Object {
ConstantPool {
[0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
[1] = Reserved
}
Function '_getStdioInputStream', static, reflectable, debuggable
parameters [dart:core::int 'fd'] (required: 1)
return-type #lib::Stdin
Bytecode {
Entry 0
CheckStack 0
PushNull
ReturnTOS
}
ConstantPool {
}
}
]library #lib from "#lib" as #lib {
typedef _ScheduleImmediateClosure = (() → void) → void;
class _ScheduleImmediate extends dart.core::Object {
static field (() → void) → void _closure = null;
synthetic constructor •() → #lib::_ScheduleImmediate
: super dart.core::Object::•()
;
}
class _NamespaceImpl extends dart.core::Object implements #lib::_Namespace {
static field #lib::_NamespaceImpl _cachedNamespace = null;
constructor _() → #lib::_NamespaceImpl
: super dart.core::Object::•()
;
@dart._internal::ExternalName::•("Namespace_Create")
external static method _create(#lib::_NamespaceImpl namespace, dynamic n) → #lib::_NamespaceImpl;
@dart._internal::ExternalName::•("Namespace_GetPointer")
external static method _getPointer(#lib::_NamespaceImpl namespace) → dart.core::int;
@dart._internal::ExternalName::•("Namespace_GetDefault")
external static method _getDefault() → dart.core::int;
static method _setupNamespace(dynamic namespace) → void {
#lib::_NamespaceImpl::_cachedNamespace = #lib::_NamespaceImpl::_create(new #lib::_NamespaceImpl::_(), namespace);
}
static get _namespace() → #lib::_NamespaceImpl {
if(#lib::_NamespaceImpl::_cachedNamespace.{dart.core::Object::==}(null)) {
#lib::_NamespaceImpl::_cachedNamespace = #lib::_NamespaceImpl::_create(new #lib::_NamespaceImpl::_(), #lib::_NamespaceImpl::_getDefault());
}
return #lib::_NamespaceImpl::_cachedNamespace;
}
static get _namespacePointer() → dart.core::int
return #lib::_NamespaceImpl::_getPointer(#lib::_NamespaceImpl::_namespace);
}
class _Namespace extends dart.core::Object {
synthetic constructor •() → #lib::_Namespace
: super dart.core::Object::•()
;
static method _setupNamespace(dynamic namespace) → void {
#lib::_NamespaceImpl::_setupNamespace(namespace);
}
static get _namespace() → #lib::_Namespace
return #lib::_NamespaceImpl::_namespace;
static get _namespacePointer() → dart.core::int
return #lib::_NamespaceImpl::_namespacePointer;
}
class VMLibraryHooks extends dart.core::Object {
static field dynamic timerFactory = null;
static field dynamic eventHandlerSendData = null;
static field dynamic timerMillisecondClock = null;
@ -737,81 +754,12 @@ ConstantPool {
return #lib::VMLibraryHooks::_cachedScript;
}
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::Stdin
Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
}
ConstantPool {
[0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
[1] = Reserved
}
}
}
] class Stdin extends dart.core::Object {
class Stdin extends dart.core::Object {
synthetic constructor •() → #lib::Stdin
: super dart.core::Object::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::_StdIOUtils
Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
}
ConstantPool {
[0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
[1] = Reserved
}
Function '_getStdioInputStream', static, reflectable, debuggable
parameters [dart:core::int 'fd'] (required: 1)
return-type #lib::Stdin
Bytecode {
Entry 0
CheckStack 0
PushNull
ReturnTOS
}
ConstantPool {
}
}
}
] class _StdIOUtils extends dart.core::Object {
class _StdIOUtils extends dart.core::Object {
synthetic constructor •() → #lib::_StdIOUtils
: super dart.core::Object::•()
;

View file

@ -1,21 +1,19 @@
main = #lib::main;
[@vm.bytecode=
ComponentBytecodeMetadata {
BytecodeMetadata {
Bytecode (version: stable)
Main library: #lib
Library '#lib'
name '#lib'
script '#lib'
}
] [@vm.bytecode=
MembersBytecodeMetadata {
Class '', script = '#lib'
Members {
Function 'simpleClosure', static, reflectable, debuggable
parameters [] (required: 0)
return-type dart:core::int
Bytecode {
Entry 4
CheckStack 0
@ -92,7 +90,6 @@ ClosureCode {
StoreContextVar 0, 0
PushNull
ReturnTOS
}
@ -101,7 +98,6 @@ Function 'callWithArgs', static, reflectable, debuggable
parameters [] (required: 0)
return-type void
Bytecode {
Entry 2
CheckStack 0
@ -187,7 +183,6 @@ Function 'callA', static, reflectable, debuggable
parameters [] (required: 0)
return-type void
Bytecode {
Entry 1
CheckStack 0
@ -241,7 +236,6 @@ Function 'testPartialInstantiation', static, reflectable, debuggable
parameters [] (required: 0)
return-type FunctionType (dart:core::int) -> dynamic
Bytecode {
Entry 7
CheckStack 0
@ -351,7 +345,6 @@ L2:
Drop1
PushNull
ReturnTOS
}
@ -359,7 +352,6 @@ Function 'main', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -369,22 +361,14 @@ Bytecode {
ConstantPool {
}
}
Class 'C1', script = '#lib'
extends dart:core::Object
}
]library #lib from "#lib" as #lib {
typedef IntFunc = (dart.core::int) → dynamic;
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::C1
Bytecode {
Entry 0
CheckStack 0
@ -399,24 +383,14 @@ ConstantPool {
[1] = Reserved
}
}
Class 'C2', script = '#lib'
extends dart:core::Object
}
] class C1 extends dart.core::Object {
synthetic constructor •() → #lib::C1
: super dart.core::Object::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::C2
Bytecode {
Entry 0
CheckStack 0
@ -431,24 +405,14 @@ ConstantPool {
[1] = Reserved
}
}
Class 'C3', script = '#lib'
extends dart:core::Object
}
] class C2 extends dart.core::Object {
synthetic constructor •() → #lib::C2
: super dart.core::Object::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::C3
Bytecode {
Entry 0
CheckStack 0
@ -463,24 +427,14 @@ ConstantPool {
[1] = Reserved
}
}
Class 'C4', script = '#lib'
extends dart:core::Object
}
] class C3 extends dart.core::Object {
synthetic constructor •() → #lib::C3
: super dart.core::Object::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::C4
Bytecode {
Entry 0
CheckStack 0
@ -495,24 +449,14 @@ ConstantPool {
[1] = Reserved
}
}
Class 'C5', script = '#lib'
extends dart:core::Object
}
] class C4 extends dart.core::Object {
synthetic constructor •() → #lib::C4
: super dart.core::Object::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::C5
Bytecode {
Entry 0
CheckStack 0
@ -527,24 +471,14 @@ ConstantPool {
[1] = Reserved
}
}
Class 'C6', script = '#lib'
extends dart:core::Object
}
] class C5 extends dart.core::Object {
synthetic constructor •() → #lib::C5
: super dart.core::Object::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::C6
Bytecode {
Entry 0
CheckStack 0
@ -559,24 +493,14 @@ ConstantPool {
[1] = Reserved
}
}
Class 'C7', script = '#lib'
extends dart:core::Object
}
] class C6 extends dart.core::Object {
synthetic constructor •() → #lib::C6
: super dart.core::Object::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::C7
Bytecode {
Entry 0
CheckStack 0
@ -591,24 +515,14 @@ ConstantPool {
[1] = Reserved
}
}
Class 'C8', script = '#lib'
extends dart:core::Object
}
] class C7 extends dart.core::Object {
synthetic constructor •() → #lib::C7
: super dart.core::Object::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::C8
Bytecode {
Entry 0
CheckStack 0
@ -623,24 +537,15 @@ ConstantPool {
[1] = Reserved
}
}
Class 'A', script = '#lib'
type-params <dart:core::Object T1, dart:core::Object T2> (args: 2)
extends dart:core::Object
}
] class C8 extends dart.core::Object {
synthetic constructor •() → #lib::C8
: super dart.core::Object::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::A < #lib::A::TypeParam/0, #lib::A::TypeParam/1 >
Bytecode {
Entry 0
CheckStack 0
@ -661,7 +566,6 @@ Function 'foo', reflectable, debuggable
parameters [] (required: 0)
return-type void
Bytecode {
Entry 5
CheckStack 0
@ -804,7 +708,6 @@ L2:
Drop1
PushNull
ReturnTOS
}
Closure #lib::A::foo::Closure/0::'nested2' <dart:core::Object T7, dart:core::Object T8> () -> void
@ -856,7 +759,6 @@ L2:
Drop1
PushNull
ReturnTOS
}
Closure #lib::A::foo::Closure/1::'<anonymous closure>' () -> dart:core::Null
@ -939,36 +841,11 @@ ClosureCode {
Drop1
PushNull
ReturnTOS
}
}
Class 'B', script = '#lib'
extends dart:core::Object
}
] class A<T1 extends dart.core::Object = dynamic, T2 extends dart.core::Object = dynamic> extends dart.core::Object {
synthetic constructor •() → #lib::A<#lib::A::T1, #lib::A::T2>
: super dart.core::Object::•()
;
method foo<T3 extends dart.core::Object = dynamic, T4 extends dart.core::Object = dynamic>() → void {
function nested1<T5 extends dart.core::Object = dynamic, T6 extends dart.core::Object = dynamic>() → void {
function nested2<T7 extends dart.core::Object = dynamic, T8 extends dart.core::Object = dynamic>() → void {
() → dart.core::Null nested3 = () → dart.core::Null {
dart.core::print(<dart.core::Type>[#lib::A::T1, #lib::A::T2, #lib::A::foo::T3, #lib::A::foo::T4, T5, T6, T7, T8]);
#lib::callWithArgs<#lib::A::T1, #lib::A::T2, #lib::A::foo::T3, #lib::A::foo::T4, T5, T6, T7, T8>();
};
[@vm.call-site-attributes.metadata=receiverType:() → dart.core::Null] nested3.call();
}
[@vm.call-site-attributes.metadata=receiverType:<T7 extends dart.core::Object = dynamic, T8 extends dart.core::Object = dynamic>() → void] nested2.call<#lib::C7, #lib::C8>();
[@vm.call-site-attributes.metadata=receiverType:<T7 extends dart.core::Object = dynamic, T8 extends dart.core::Object = dynamic>() → void] nested2.call<dart.core::List<#lib::C7>, dart.core::List<#lib::C8>>();
}
[@vm.call-site-attributes.metadata=receiverType:<T5 extends dart.core::Object = dynamic, T6 extends dart.core::Object = dynamic>() → void] nested1.call<#lib::C5, #lib::C6>();
[@vm.call-site-attributes.metadata=receiverType:<T5 extends dart.core::Object = dynamic, T6 extends dart.core::Object = dynamic>() → void] nested1.call<dart.core::List<#lib::C5>, dart.core::List<#lib::C6>>();
}
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Field 'foo', type = dart:core::int, getter = 'get:foo', setter = 'set:foo', reflectable
value = null
@ -976,7 +853,6 @@ Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::B
Bytecode {
Entry 0
CheckStack 0
@ -997,7 +873,6 @@ Function 'topLevel', reflectable, debuggable
parameters [] (required: 0)
return-type void
Bytecode {
Entry 5
CheckStack 0
@ -1179,7 +1054,6 @@ ClosureCode {
L1:
PushNull
ReturnTOS
}
Closure #lib::B::topLevel::Closure/0::'closure2' () -> void
@ -1208,7 +1082,6 @@ ClosureCode {
StoreContextVar 1, 1
PushNull
ReturnTOS
}
Closure #lib::B::topLevel::'<anonymous closure>' () -> dart:core::Null
@ -1226,61 +1099,16 @@ ClosureCode {
Drop1
PushNull
ReturnTOS
}
}
Class 'C', script = '#lib'
extends dart:core::Object
}
] class B extends dart.core::Object {
field dart.core::int foo = null;
synthetic constructor •() → #lib::B
: super dart.core::Object::•()
;
method topLevel() → void {
{
dart.core::int x = 1;
{
dart.core::int y = 2;
dart.core::int z = 3;
(dart.core::int) → dart.core::Null closure1 = (dart.core::int y) → dart.core::Null {
x = y.{dart.core::num::+}(1);
if(x.{dart.core::num::>}(5)) {
dart.core::int w = 4;
function closure2() → void {
z = x.{dart.core::num::+}(2);
w = this.{#lib::B::foo}.{dart.core::num::+}(y);
}
[@vm.call-site-attributes.metadata=receiverType:() → void] closure2.call();
dart.core::print(w);
}
};
[@vm.call-site-attributes.metadata=receiverType:(dart.core::int) → dart.core::Null] closure1.call(10);
[@vm.call-site-attributes.metadata=receiverType:(dart.core::int) → dart.core::Null] closure1.call(11);
dart.core::print(y);
dart.core::print(z);
}
dart.core::print(x);
}
{
dart.core::int x = 42;
() → dart.core::Null closure3 = () → dart.core::Null {
this.{#lib::B::foo} = x;
};
[@vm.call-site-attributes.metadata=receiverType:() → dart.core::Null] closure3.call();
}
}
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::C
Bytecode {
Entry 0
CheckStack 0
@ -1300,7 +1128,6 @@ Function 'testForLoop', reflectable, debuggable
parameters [] (required: 0)
return-type void
Bytecode {
Entry 5
CheckStack 0
@ -1436,7 +1263,6 @@ ClosureCode {
LoadContextVar 0, 0
AddInt
ReturnTOS
}
Closure #lib::C::testForLoop::'<anonymous closure>' (dart:core::int ii) -> dart:core::Null
@ -1462,7 +1288,6 @@ ClosureCode {
StoreContextVar 1, 0
PushNull
ReturnTOS
}
@ -1470,7 +1295,6 @@ Function 'testForInLoop', reflectable, debuggable
parameters [dart:core::List < dart:core::int > 'list'] (required: 1)
return-type void
Bytecode {
Entry 5
CheckStack 0
@ -1561,47 +1385,17 @@ ClosureCode {
StoreContextVar 0, 0
PushNull
ReturnTOS
}
}
Class 'D', script = '#lib'
type-params <dart:core::Object T> (args: 1)
extends dart:core::Object
}
] class C extends dart.core::Object {
synthetic constructor •() → #lib::C
: super dart.core::Object::•()
;
method testForLoop() → void {
dart.core::int delta = 0;
dart.core::List<dart.core::Function> getI = <dart.core::Function>[];
dart.core::List<dart.core::Function> setI = <dart.core::Function>[];
for (dart.core::int i = 0; i.{dart.core::num::<}(10); i = i.{dart.core::num::+}(1)) {
[@vm.call-site-attributes.metadata=receiverType:dart.core::List<dart.core::Function>] getI.{dart.core::List::add}(() → dart.core::int => i.{dart.core::num::+}(delta));
[@vm.call-site-attributes.metadata=receiverType:dart.core::List<dart.core::Function>] setI.{dart.core::List::add}((dart.core::int ii) → dart.core::Null {
i = ii.{dart.core::num::+}(delta);
});
}
}
method testForInLoop(dart.core::List<dart.core::int> list) → void {
for (dart.core::int i in list) {
() → dart.core::Null inc = () → dart.core::Null {
i = i.{dart.core::num::+}(1);
};
[@vm.call-site-attributes.metadata=receiverType:() → dart.core::Null] inc.call();
dart.core::print(i);
}
}
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::D < #lib::D::TypeParam/0 >
Bytecode {
Entry 0
CheckStack 0
@ -1621,7 +1415,6 @@ Function 'foo', reflectable, debuggable
parameters [#lib::D::TypeParam/0 't'] (required: 1)
return-type dynamic
Bytecode {
Entry 3
CheckStack 0
@ -1688,7 +1481,6 @@ ClosureCode {
Push r0
LoadContextVar 0, 0
ReturnTOS
}
@ -1696,7 +1488,6 @@ Function 'bar', reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 3
CheckStack 0
@ -1777,7 +1568,6 @@ ClosureCode {
Drop1
PushNull
ReturnTOS
}
Closure #lib::D::bar::Closure/0::'inner' () -> dart:core::Null
@ -1789,13 +1579,138 @@ ClosureCode {
PopLocal r0
PushNull
ReturnTOS
}
}
}
] class D<T extends dart.core::Object = dynamic> extends dart.core::Object {
]library #lib from "#lib" as #lib {
typedef IntFunc = (dart.core::int) → dynamic;
class C1 extends dart.core::Object {
synthetic constructor •() → #lib::C1
: super dart.core::Object::•()
;
}
class C2 extends dart.core::Object {
synthetic constructor •() → #lib::C2
: super dart.core::Object::•()
;
}
class C3 extends dart.core::Object {
synthetic constructor •() → #lib::C3
: super dart.core::Object::•()
;
}
class C4 extends dart.core::Object {
synthetic constructor •() → #lib::C4
: super dart.core::Object::•()
;
}
class C5 extends dart.core::Object {
synthetic constructor •() → #lib::C5
: super dart.core::Object::•()
;
}
class C6 extends dart.core::Object {
synthetic constructor •() → #lib::C6
: super dart.core::Object::•()
;
}
class C7 extends dart.core::Object {
synthetic constructor •() → #lib::C7
: super dart.core::Object::•()
;
}
class C8 extends dart.core::Object {
synthetic constructor •() → #lib::C8
: super dart.core::Object::•()
;
}
class A<T1 extends dart.core::Object = dynamic, T2 extends dart.core::Object = dynamic> extends dart.core::Object {
synthetic constructor •() → #lib::A<#lib::A::T1, #lib::A::T2>
: super dart.core::Object::•()
;
method foo<T3 extends dart.core::Object = dynamic, T4 extends dart.core::Object = dynamic>() → void {
function nested1<T5 extends dart.core::Object = dynamic, T6 extends dart.core::Object = dynamic>() → void {
function nested2<T7 extends dart.core::Object = dynamic, T8 extends dart.core::Object = dynamic>() → void {
() → dart.core::Null nested3 = () → dart.core::Null {
dart.core::print(<dart.core::Type>[#lib::A::T1, #lib::A::T2, #lib::A::foo::T3, #lib::A::foo::T4, T5, T6, T7, T8]);
#lib::callWithArgs<#lib::A::T1, #lib::A::T2, #lib::A::foo::T3, #lib::A::foo::T4, T5, T6, T7, T8>();
};
[@vm.call-site-attributes.metadata=receiverType:() → dart.core::Null] nested3.call();
}
[@vm.call-site-attributes.metadata=receiverType:<T7 extends dart.core::Object = dynamic, T8 extends dart.core::Object = dynamic>() → void] nested2.call<#lib::C7, #lib::C8>();
[@vm.call-site-attributes.metadata=receiverType:<T7 extends dart.core::Object = dynamic, T8 extends dart.core::Object = dynamic>() → void] nested2.call<dart.core::List<#lib::C7>, dart.core::List<#lib::C8>>();
}
[@vm.call-site-attributes.metadata=receiverType:<T5 extends dart.core::Object = dynamic, T6 extends dart.core::Object = dynamic>() → void] nested1.call<#lib::C5, #lib::C6>();
[@vm.call-site-attributes.metadata=receiverType:<T5 extends dart.core::Object = dynamic, T6 extends dart.core::Object = dynamic>() → void] nested1.call<dart.core::List<#lib::C5>, dart.core::List<#lib::C6>>();
}
}
class B extends dart.core::Object {
field dart.core::int foo = null;
synthetic constructor •() → #lib::B
: super dart.core::Object::•()
;
method topLevel() → void {
{
dart.core::int x = 1;
{
dart.core::int y = 2;
dart.core::int z = 3;
(dart.core::int) → dart.core::Null closure1 = (dart.core::int y) → dart.core::Null {
x = y.{dart.core::num::+}(1);
if(x.{dart.core::num::>}(5)) {
dart.core::int w = 4;
function closure2() → void {
z = x.{dart.core::num::+}(2);
w = this.{#lib::B::foo}.{dart.core::num::+}(y);
}
[@vm.call-site-attributes.metadata=receiverType:() → void] closure2.call();
dart.core::print(w);
}
};
[@vm.call-site-attributes.metadata=receiverType:(dart.core::int) → dart.core::Null] closure1.call(10);
[@vm.call-site-attributes.metadata=receiverType:(dart.core::int) → dart.core::Null] closure1.call(11);
dart.core::print(y);
dart.core::print(z);
}
dart.core::print(x);
}
{
dart.core::int x = 42;
() → dart.core::Null closure3 = () → dart.core::Null {
this.{#lib::B::foo} = x;
};
[@vm.call-site-attributes.metadata=receiverType:() → dart.core::Null] closure3.call();
}
}
}
class C extends dart.core::Object {
synthetic constructor •() → #lib::C
: super dart.core::Object::•()
;
method testForLoop() → void {
dart.core::int delta = 0;
dart.core::List<dart.core::Function> getI = <dart.core::Function>[];
dart.core::List<dart.core::Function> setI = <dart.core::Function>[];
for (dart.core::int i = 0; i.{dart.core::num::<}(10); i = i.{dart.core::num::+}(1)) {
[@vm.call-site-attributes.metadata=receiverType:dart.core::List<dart.core::Function>] getI.{dart.core::List::add}(() → dart.core::int => i.{dart.core::num::+}(delta));
[@vm.call-site-attributes.metadata=receiverType:dart.core::List<dart.core::Function>] setI.{dart.core::List::add}((dart.core::int ii) → dart.core::Null {
i = ii.{dart.core::num::+}(delta);
});
}
}
method testForInLoop(dart.core::List<dart.core::int> list) → void {
for (dart.core::int i in list) {
() → dart.core::Null inc = () → dart.core::Null {
i = i.{dart.core::num::+}(1);
};
[@vm.call-site-attributes.metadata=receiverType:() → dart.core::Null] inc.call();
dart.core::print(i);
}
}
}
class D<T extends dart.core::Object = dynamic> extends dart.core::Object {
synthetic constructor •() → #lib::D<#lib::D::T>
: super dart.core::Object::•()
;

View file

@ -1,21 +1,19 @@
main = #lib::main;
[@vm.bytecode=
ComponentBytecodeMetadata {
BytecodeMetadata {
Bytecode (version: stable)
Main library: #lib
Library '#lib'
name '#lib'
script '#lib'
}
] [@vm.bytecode=
MembersBytecodeMetadata {
Class '', script = '#lib'
Members {
Function 'callDeferred', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 1
CheckStack 0
@ -37,7 +35,6 @@ Function 'testLoadLibrary', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -55,7 +52,6 @@ Function 'main', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -65,7 +61,6 @@ Bytecode {
ConstantPool {
}
}
}
]library #lib from "#lib" as #lib {

View file

@ -1,21 +1,19 @@
main = #lib::main;
[@vm.bytecode=
ComponentBytecodeMetadata {
BytecodeMetadata {
Bytecode (version: stable)
Main library: #lib
Library '#lib'
name '#lib'
script '#lib'
}
] [@vm.bytecode=
MembersBytecodeMetadata {
Class '', script = '#lib'
Members {
Function 'main', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -25,15 +23,9 @@ Bytecode {
ConstantPool {
}
}
Class 'A', script = '#lib'
extends dart:core::Object
}
]library #lib from "#lib" as #lib {
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Field 'foo1', type = dart:core::int, getter = 'get:foo1', setter = 'set:foo1', reflectable
value = null
@ -53,7 +45,6 @@ Function '', constructor, reflectable, debuggable
parameters [dart:core::int 'foo4'] (required: 1)
return-type #lib::A
Bytecode {
Entry 0
CheckStack 0
@ -92,7 +83,6 @@ Function 'constr2', constructor, reflectable, debuggable
parameters [dart:core::int 'x', dart:core::int 'y'] (required: 2)
return-type #lib::A
Bytecode {
Entry 0
CheckStack 0
@ -133,7 +123,6 @@ Function 'redirecting1', constructor, reflectable, debuggable
parameters [] (required: 0)
return-type #lib::A
Bytecode {
Entry 0
CheckStack 0
@ -154,7 +143,6 @@ Function 'redirecting2', constructor, reflectable, debuggable
parameters [dart:core::int 'a', dart:core::int 'b', dart:core::int 'c'] (required: 3)
return-type #lib::A
Bytecode {
Entry 0
CheckStack 0
@ -173,32 +161,9 @@ ConstantPool {
[1] = Reserved
}
}
Class 'B', script = '#lib'
extends #lib::A
}
] class A extends dart.core::Object {
field dart.core::int foo1;
field dart.core::int foo2 = null;
field dart.core::int foo3 = 42;
field dart.core::int foo4;
field dart.core::int foo5 = 43;
constructor •(dart.core::int foo4) → #lib::A
: #lib::A::foo1 = null, #lib::A::foo4 = foo4, #lib::A::foo5 = 44, super dart.core::Object::•()
;
constructor constr2(dart.core::int x, dart.core::int y) → #lib::A
: #lib::A::foo4 = null, #lib::A::foo1 = x, #lib::A::foo5 = y.{dart.core::num::+}(1), super dart.core::Object::•()
;
constructor redirecting1() → #lib::A
: this #lib::A::•(45)
;
constructor redirecting2(dart.core::int a, dart.core::int b, dart.core::int c) → #lib::A
: this #lib::A::constr2(a, b.{dart.core::num::*}(c))
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Field 'foo6', type = dart:core::int, getter = 'get:foo6', setter = 'set:foo6', reflectable
value = const 46
@ -212,7 +177,6 @@ Function '', constructor, reflectable, debuggable
parameters [] (required: 0)
return-type #lib::B
Bytecode {
Entry 0
CheckStack 0
@ -238,7 +202,6 @@ Function 'c2', constructor, reflectable, debuggable
parameters [dart:core::int 'i', dart:core::int 'j'] (required: 2)
return-type #lib::B
Bytecode {
Entry 0
CheckStack 0
@ -264,10 +227,30 @@ ConstantPool {
[3] = Reserved
}
}
}
] class B extends #lib::A {
]library #lib from "#lib" as #lib {
class A extends dart.core::Object {
field dart.core::int foo1;
field dart.core::int foo2 = null;
field dart.core::int foo3 = 42;
field dart.core::int foo4;
field dart.core::int foo5 = 43;
constructor •(dart.core::int foo4) → #lib::A
: #lib::A::foo1 = null, #lib::A::foo4 = foo4, #lib::A::foo5 = 44, super dart.core::Object::•()
;
constructor constr2(dart.core::int x, dart.core::int y) → #lib::A
: #lib::A::foo4 = null, #lib::A::foo1 = x, #lib::A::foo5 = y.{dart.core::num::+}(1), super dart.core::Object::•()
;
constructor redirecting1() → #lib::A
: this #lib::A::•(45)
;
constructor redirecting2(dart.core::int a, dart.core::int b, dart.core::int c) → #lib::A
: this #lib::A::constr2(a, b.{dart.core::num::*}(c))
;
}
class B extends #lib::A {
field dart.core::int foo6 = 46;
static field dart.core::int foo7 = 47;
static const field dart.core::int foo8 = 48;

View file

@ -1,21 +1,19 @@
main = #lib::main;
[@vm.bytecode=
ComponentBytecodeMetadata {
BytecodeMetadata {
Bytecode (version: stable)
Main library: #lib
Library '#lib'
name '#lib'
script '#lib'
}
] [@vm.bytecode=
MembersBytecodeMetadata {
Class '', script = '#lib'
Members {
Function 'main', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -31,7 +29,6 @@ ConstantPool {
[2] = Reserved
}
}
}
]library #lib from "#lib" as #lib {

View file

@ -1,21 +1,19 @@
main = #lib::main;
[@vm.bytecode=
ComponentBytecodeMetadata {
BytecodeMetadata {
Bytecode (version: stable)
Main library: #lib
Library '#lib'
name '#lib'
script '#lib'
}
] [@vm.bytecode=
MembersBytecodeMetadata {
Class '', script = '#lib'
Members {
Function 'foo1', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 1
CheckStack 0
@ -39,7 +37,6 @@ Function 'foo2', static, reflectable, debuggable
parameters [] (required: 0)
return-type void
Bytecode {
Entry 1
CheckStack 0
@ -81,7 +78,6 @@ Function 'foo3', static, reflectable, debuggable
parameters [] (required: 0)
return-type void
Bytecode {
Entry 2
CheckStack 0
@ -111,7 +107,6 @@ Function 'foo4', static, reflectable, debuggable
parameters [] (required: 0)
return-type void
Bytecode {
Entry 0
CheckStack 0
@ -132,7 +127,6 @@ Function 'foo5', static, reflectable, debuggable
parameters [] (required: 0)
return-type void
Bytecode {
Entry 0
CheckStack 0
@ -158,7 +152,6 @@ Function 'foo6', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -178,7 +171,6 @@ Function 'foo7', static, reflectable, debuggable
parameters [dart:core::int 'n'] (required: 1)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -198,7 +190,6 @@ Function 'main', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -222,15 +213,10 @@ ConstantPool {
[6] = Reserved
}
}
Class 'Base', script = '#lib'
type-params <dart:core::Object T1, dart:core::Object T2> (args: 2)
extends dart:core::Object
}
]library #lib from "#lib" as #lib {
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Field 't1', type = #lib::Base::TypeParam/0, getter = 'get:t1', setter = 'set:t1', reflectable
value = null
@ -241,7 +227,6 @@ Function '', constructor, reflectable, debuggable
parameters [] (required: 0)
return-type #lib::Base < #lib::Base::TypeParam/0, #lib::Base::TypeParam/1 >
Bytecode {
Entry 1
CheckStack 0
@ -295,26 +280,13 @@ ConstantPool {
[10] = Reserved
}
}
Class 'A', script = '#lib'
extends #lib::Base < dart:core::int, dart:core::String >
}
] class Base<T1 extends dart.core::Object = dynamic, T2 extends dart.core::Object = dynamic> extends dart.core::Object {
generic-covariant-impl field #lib::Base::T1 t1 = null;
generic-covariant-impl field #lib::Base::T2 t2 = null;
constructor •() → #lib::Base<#lib::Base::T1, #lib::Base::T2>
: super dart.core::Object::•() {
dart.core::print("Base: ${#lib::Base::T1}, ${#lib::Base::T2}");
}
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable, debuggable
parameters [dart:core::String 's'] (required: 1)
return-type #lib::A
return-type #lib::A < dart:core::int, dart:core::String >
Bytecode {
Entry 0
@ -330,24 +302,15 @@ ConstantPool {
[1] = Reserved
}
}
Class 'B', script = '#lib'
type-params <dart:core::Object T> (args: 3)
extends #lib::Base < dart:core::List < #lib::B::TypeParam/0 >, dart:core::String >
}
] class A extends #lib::Base<dart.core::int, dart.core::String> {
constructor •(dart.core::String s) → #lib::A
: super #lib::Base::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable, debuggable
parameters [] (required: 0)
return-type #lib::B < dart:core::List < #lib::B::TypeParam/0 >, dart:core::String, #lib::B::TypeParam/0 >
Bytecode {
Entry 1
CheckStack 0
@ -387,25 +350,14 @@ ConstantPool {
[8] = Reserved
}
}
Class 'C', script = '#lib'
extends dart:core::Object
}
] class B<T extends dart.core::Object = dynamic> extends #lib::Base<dart.core::List<#lib::B::T>, dart.core::String> {
constructor •() → #lib::B<#lib::B::T>
: super #lib::Base::•() {
dart.core::print("B: ${#lib::B::T}");
}
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable, debuggable
parameters [dart:core::String 's'] (required: 1)
return-type #lib::C
Bytecode {
Entry 1
CheckStack 0
@ -440,25 +392,15 @@ ConstantPool {
[6] = Reserved
}
}
Class 'E', script = '#lib'
type-params <dart:core::Object K, dart:core::Object V> (args: 2)
extends dart:core::Object
}
] class C extends dart.core::Object {
constructor •(dart.core::String s) → #lib::C
: super dart.core::Object::•() {
dart.core::print("C: ${s}");
}
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::E < #lib::E::TypeParam/0, #lib::E::TypeParam/1 >
Bytecode {
Entry 0
CheckStack 0
@ -478,7 +420,6 @@ Function 'test_reuse1', reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -493,26 +434,15 @@ ConstantPool {
[2] = Reserved
}
}
Class 'F', script = '#lib'
type-params <dart:core::Object K, dart:core::Object V> (args: 4)
extends #lib::E < dart:core::String, dart:core::List < #lib::F::TypeParam/1 > >
}
] class E<K extends dart.core::Object = dynamic, V extends dart.core::Object = dynamic> extends dart.core::Object {
synthetic constructor •() → #lib::E<#lib::E::K, #lib::E::V>
: super dart.core::Object::•()
;
method test_reuse1() → dynamic
return dart.core::Map::•<#lib::E::K, #lib::E::V>();
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::F < dart:core::String, dart:core::List < #lib::F::TypeParam/1 >, #lib::F::TypeParam/0, #lib::F::TypeParam/1 >
Bytecode {
Entry 0
CheckStack 0
@ -532,7 +462,6 @@ Function 'test_reuse2', reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -547,26 +476,15 @@ ConstantPool {
[2] = Reserved
}
}
Class 'G', script = '#lib'
type-params <dart:core::Object K, dart:core::Object V> (args: 2)
extends dart:core::Object
}
] class F<K extends dart.core::Object = dynamic, V extends dart.core::Object = dynamic> extends #lib::E<dart.core::String, dart.core::List<#lib::F::V>> {
synthetic constructor •() → #lib::F<#lib::F::K, #lib::F::V>
: super #lib::E::•()
;
method test_reuse2() → dynamic
return dart.core::Map::•<dart.core::String, dart.core::List<#lib::F::V>>();
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable, debuggable
parameters [] (required: 0)
return-type #lib::G < #lib::G::TypeParam/0, #lib::G::TypeParam/1 >
Bytecode {
Entry 0
CheckStack 0
@ -587,7 +505,6 @@ Function 'test_factory', factory, static, reflectable, debuggable
parameters [] (required: 0)
return-type #lib::G < #lib::G::test_factory (constructor)::TypeParam/0, #lib::G::test_factory (constructor)::TypeParam/1 >
Bytecode {
Entry 1
CheckStack 0
@ -609,26 +526,15 @@ ConstantPool {
[3] = Reserved
}
}
Class 'H', script = '#lib'
type-params <dart:core::Object P1, dart:core::Object P2, dart:core::Object P3> (args: 5)
extends #lib::G < #lib::H::TypeParam/1, #lib::H::TypeParam/2 >
}
] class G<K extends dart.core::Object = dynamic, V extends dart.core::Object = dynamic> extends dart.core::Object {
constructor •() → #lib::G<#lib::G::K, #lib::G::V>
: super dart.core::Object::•()
;
static factory test_factory<K extends dart.core::Object = dynamic, V extends dart.core::Object = dynamic>() → #lib::G<#lib::G::test_factory::K, #lib::G::test_factory::V>
return new #lib::H::•<dart.core::String, #lib::G::test_factory::K, #lib::G::test_factory::V>();
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::H < #lib::H::TypeParam/1, #lib::H::TypeParam/2, #lib::H::TypeParam/0, #lib::H::TypeParam/1, #lib::H::TypeParam/2 >
Bytecode {
Entry 0
CheckStack 0
@ -643,24 +549,14 @@ ConstantPool {
[1] = Reserved
}
}
Class 'I', script = '#lib'
extends dart:core::Object
}
] class H<P1 extends dart.core::Object = dynamic, P2 extends dart.core::Object = dynamic, P3 extends dart.core::Object = dynamic> extends #lib::G<#lib::H::P2, #lib::H::P3> {
synthetic constructor •() → #lib::H<#lib::H::P1, #lib::H::P2, #lib::H::P3>
: super #lib::G::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable, debuggable
parameters [dynamic 'param'] (required: 1)
return-type #lib::I
Bytecode {
Entry 0
CheckStack 0
@ -680,7 +576,6 @@ Function 'test_factory2', factory, static, has-optional-named-params, reflectabl
parameters [dynamic 'param'] (required: 0)
return-type #lib::I
Bytecode {
EntryOptional 1, 0, 1
LoadConstant r1, CP#0
@ -703,26 +598,14 @@ ConstantPool {
[4] = Reserved
}
}
Class 'J', script = '#lib'
extends dart:core::Object
}
] class I extends dart.core::Object {
constructor •(dynamic param) → #lib::I
: super dart.core::Object::•()
;
static factory test_factory2({dynamic param = null}) → #lib::I
return new #lib::I::•(param);
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', factory, static, reflectable, debuggable, native 'agent_J'
parameters [] (required: 0)
return-type #lib::J
Bytecode {
Entry 0
CheckStack 0
@ -734,24 +617,16 @@ ConstantPool {
[0] = NativeEntry agent_J
}
}
Class 'K', script = '#lib', abstract
type-params <dart:core::Object A, dart:core::Object B> (args: 2)
extends dart:core::Object
}
] class J extends dart.core::Object {
@dart._internal::ExternalName::•("agent_J")
external static factory •() → #lib::J;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', factory, static, reflectable, debuggable
type-params <dart:core::Object A, dart:core::Object B>
parameters [] (required: 0)
return-type #lib::K < #lib::K:: (constructor)::TypeParam/0, #lib::K:: (constructor)::TypeParam/1 >
Bytecode {
Entry 1
CheckStack 0
@ -770,23 +645,16 @@ ConstantPool {
[2] = Reserved
}
}
Class 'TestTypeArgReuse', script = '#lib'
type-params <dart:core::Object P, dart:core::Object Q> (args: 2)
extends #lib::Base < #lib::TestTypeArgReuse::TypeParam/0, #lib::TestTypeArgReuse::TypeParam/1 >
implements [#lib::K < #lib::TestTypeArgReuse::TypeParam/0, #lib::TestTypeArgReuse::TypeParam/1 >]
}
] abstract class K<A extends dart.core::Object = dynamic, B extends dart.core::Object = dynamic> extends dart.core::Object {
static factory •<A extends dart.core::Object = dynamic, B extends dart.core::Object = dynamic>() → #lib::K<#lib::K::•::A, #lib::K::•::B>
return new #lib::TestTypeArgReuse::•<#lib::K::•::A, #lib::K::•::B>();
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::TestTypeArgReuse < #lib::TestTypeArgReuse::TypeParam/0, #lib::TestTypeArgReuse::TypeParam/1 >
Bytecode {
Entry 0
CheckStack 0
@ -801,10 +669,77 @@ ConstantPool {
[1] = Reserved
}
}
}
] class TestTypeArgReuse<P extends dart.core::Object = dynamic, Q extends dart.core::Object = dynamic> extends #lib::Base<#lib::TestTypeArgReuse::P, #lib::TestTypeArgReuse::Q> implements #lib::K<#lib::TestTypeArgReuse::P, #lib::TestTypeArgReuse::Q> {
]library #lib from "#lib" as #lib {
class Base<T1 extends dart.core::Object = dynamic, T2 extends dart.core::Object = dynamic> extends dart.core::Object {
generic-covariant-impl field #lib::Base::T1 t1 = null;
generic-covariant-impl field #lib::Base::T2 t2 = null;
constructor •() → #lib::Base<#lib::Base::T1, #lib::Base::T2>
: super dart.core::Object::•() {
dart.core::print("Base: ${#lib::Base::T1}, ${#lib::Base::T2}");
}
}
class A extends #lib::Base<dart.core::int, dart.core::String> {
constructor •(dart.core::String s) → #lib::A
: super #lib::Base::•()
;
}
class B<T extends dart.core::Object = dynamic> extends #lib::Base<dart.core::List<#lib::B::T>, dart.core::String> {
constructor •() → #lib::B<#lib::B::T>
: super #lib::Base::•() {
dart.core::print("B: ${#lib::B::T}");
}
}
class C extends dart.core::Object {
constructor •(dart.core::String s) → #lib::C
: super dart.core::Object::•() {
dart.core::print("C: ${s}");
}
}
class E<K extends dart.core::Object = dynamic, V extends dart.core::Object = dynamic> extends dart.core::Object {
synthetic constructor •() → #lib::E<#lib::E::K, #lib::E::V>
: super dart.core::Object::•()
;
method test_reuse1() → dynamic
return dart.core::Map::•<#lib::E::K, #lib::E::V>();
}
class F<K extends dart.core::Object = dynamic, V extends dart.core::Object = dynamic> extends #lib::E<dart.core::String, dart.core::List<#lib::F::V>> {
synthetic constructor •() → #lib::F<#lib::F::K, #lib::F::V>
: super #lib::E::•()
;
method test_reuse2() → dynamic
return dart.core::Map::•<dart.core::String, dart.core::List<#lib::F::V>>();
}
class G<K extends dart.core::Object = dynamic, V extends dart.core::Object = dynamic> extends dart.core::Object {
constructor •() → #lib::G<#lib::G::K, #lib::G::V>
: super dart.core::Object::•()
;
static factory test_factory<K extends dart.core::Object = dynamic, V extends dart.core::Object = dynamic>() → #lib::G<#lib::G::test_factory::K, #lib::G::test_factory::V>
return new #lib::H::•<dart.core::String, #lib::G::test_factory::K, #lib::G::test_factory::V>();
}
class H<P1 extends dart.core::Object = dynamic, P2 extends dart.core::Object = dynamic, P3 extends dart.core::Object = dynamic> extends #lib::G<#lib::H::P2, #lib::H::P3> {
synthetic constructor •() → #lib::H<#lib::H::P1, #lib::H::P2, #lib::H::P3>
: super #lib::G::•()
;
}
class I extends dart.core::Object {
constructor •(dynamic param) → #lib::I
: super dart.core::Object::•()
;
static factory test_factory2({dynamic param = null}) → #lib::I
return new #lib::I::•(param);
}
class J extends dart.core::Object {
@dart._internal::ExternalName::•("agent_J")
external static factory •() → #lib::J;
}
abstract class K<A extends dart.core::Object = dynamic, B extends dart.core::Object = dynamic> extends dart.core::Object {
static factory •<A extends dart.core::Object = dynamic, B extends dart.core::Object = dynamic>() → #lib::K<#lib::K::•::A, #lib::K::•::B>
return new #lib::TestTypeArgReuse::•<#lib::K::•::A, #lib::K::•::B>();
}
class TestTypeArgReuse<P extends dart.core::Object = dynamic, Q extends dart.core::Object = dynamic> extends #lib::Base<#lib::TestTypeArgReuse::P, #lib::TestTypeArgReuse::Q> implements #lib::K<#lib::TestTypeArgReuse::P, #lib::TestTypeArgReuse::Q> {
synthetic constructor •() → #lib::TestTypeArgReuse<#lib::TestTypeArgReuse::P, #lib::TestTypeArgReuse::Q>
: super #lib::Base::•()
;

View file

@ -1,17 +1,16 @@
main = #lib::main;
[@vm.bytecode=
ComponentBytecodeMetadata {
BytecodeMetadata {
Bytecode (version: stable)
Main library: #lib
Library '#lib'
name '#lib'
script '#lib'
}
] [@vm.bytecode=
MembersBytecodeMetadata {
Class '', script = '#lib'
Members {
Field 'c1', type = #lib::A, getter = 'get:c1', reflectable, static, const, final
initializer
initializer
Bytecode {
Entry 0
CheckStack 0
@ -30,7 +29,7 @@ Field 'c3', type = dart:core::int, reflectable, static, const, final
value = const 6
Field 'c4', type = #lib::C, getter = 'get:c4', reflectable, static, const, final
initializer
initializer
Bytecode {
Entry 0
CheckStack 0
@ -43,7 +42,7 @@ ConstantPool {
Field 'c5', type = #lib::D, getter = 'get:c5', reflectable, static, const, final
initializer
initializer
Bytecode {
Entry 0
CheckStack 0
@ -62,7 +61,6 @@ Function 'test_constants1', static, reflectable, debuggable
parameters [] (required: 0)
return-type void
Bytecode {
Entry 0
CheckStack 0
@ -98,7 +96,6 @@ Function 'test_constants2', static, reflectable, debuggable
parameters [] (required: 0)
return-type void
Bytecode {
Entry 0
CheckStack 0
@ -138,7 +135,6 @@ Function 'test_list_literal', static, reflectable, debuggable
parameters [dart:core::int 'a'] (required: 1)
return-type void
Bytecode {
Entry 1
CheckStack 0
@ -207,7 +203,6 @@ Function 'test_map_literal', static, reflectable, debuggable
parameters [dart:core::int 'a', dart:core::int 'b', #lib::test_map_literal::TypeParam/0 'c'] (required: 3)
return-type void
Bytecode {
Entry 2
CheckStack 0
@ -310,7 +305,6 @@ Function 'test_symbol', static, reflectable, debuggable
parameters [] (required: 0)
return-type void
Bytecode {
Entry 0
CheckStack 0
@ -336,7 +330,6 @@ Function 'test_type_literal', static, reflectable, debuggable
parameters [] (required: 0)
return-type void
Bytecode {
Entry 1
CheckStack 0
@ -364,7 +357,6 @@ Function 'testGenericConstInstance', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -380,7 +372,6 @@ Function 'testGenericFunctionTypeLiteral', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -396,7 +387,6 @@ Function 'testFieldWithDoubleLiteralInitializer', static, reflectable, debuggabl
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -413,7 +403,6 @@ Function 'main', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -423,16 +412,9 @@ Bytecode {
ConstantPool {
}
}
Class 'A', script = '#lib', enum
extends dart:core::Object
}
]library #lib from "#lib" as #lib {
typedef GenericFunctionType = <X extends dart.core::Object = dynamic>(X) → X;
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Field 'index', type = dart:core::int, getter = 'get:index', reflectable, final
value = null
@ -440,7 +422,7 @@ Field '_name', type = dart:core::String, getter = 'get:_name', reflectable, fina
value = null
Field 'values', type = dart:core::List < #lib::A >, getter = 'get:values', reflectable, static, const, final
initializer
initializer
Bytecode {
Entry 0
CheckStack 0
@ -453,7 +435,7 @@ ConstantPool {
Field 'elem1', type = #lib::A, getter = 'get:elem1', reflectable, static, const, final
initializer
initializer
Bytecode {
Entry 0
CheckStack 0
@ -466,7 +448,7 @@ ConstantPool {
Field 'elem2', type = #lib::A, getter = 'get:elem2', reflectable, static, const, final
initializer
initializer
Bytecode {
Entry 0
CheckStack 0
@ -479,7 +461,7 @@ ConstantPool {
Field 'elem3', type = #lib::A, getter = 'get:elem3', reflectable, static, const, final
initializer
initializer
Bytecode {
Entry 0
CheckStack 0
@ -492,7 +474,7 @@ ConstantPool {
Field 'elem4', type = #lib::A, getter = 'get:elem4', reflectable, static, const, final
initializer
initializer
Bytecode {
Entry 0
CheckStack 0
@ -508,7 +490,6 @@ Function '', constructor, const, reflectable, debuggable
parameters [dart:core::int 'index', dart:core::String '_name'] (required: 2)
return-type #lib::A
Bytecode {
Entry 0
CheckStack 0
@ -538,7 +519,6 @@ Function 'toString', reflectable, debuggable
parameters [] (required: 0)
return-type dart:core::String
Bytecode {
Entry 0
CheckStack 0
@ -551,27 +531,9 @@ ConstantPool {
[1] = Reserved
}
}
Class 'B', script = '#lib'
extends dart:core::Object
}
] class A extends dart.core::Object {
final field dart.core::int index;
final field dart.core::String _name;
static const field dart.core::List<#lib::A> values = const <#lib::A>[#lib::A::elem1, #lib::A::elem2, #lib::A::elem3, #lib::A::elem4];
static const field #lib::A elem1 = const #lib::A::•(0, "A.elem1");
static const field #lib::A elem2 = const #lib::A::•(1, "A.elem2");
static const field #lib::A elem3 = const #lib::A::•(2, "A.elem3");
static const field #lib::A elem4 = const #lib::A::•(3, "A.elem4");
const constructor •(dart.core::int index, dart.core::String _name) → #lib::A
: #lib::A::index = index, #lib::A::_name = _name, super dart.core::Object::•()
;
method toString() → dart.core::String
return this.{=#lib::A::_name};
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Field 'i', type = dart:core::int, getter = 'get:i', reflectable, final
value = null
@ -579,7 +541,6 @@ Function '', constructor, const, reflectable, debuggable
parameters [dart:core::int 'i'] (required: 1)
return-type #lib::B
Bytecode {
Entry 0
CheckStack 0
@ -599,19 +560,9 @@ ConstantPool {
[3] = Reserved
}
}
Class 'C', script = '#lib'
extends #lib::B
}
] class B extends dart.core::Object {
final field dart.core::int i;
const constructor •(dart.core::int i) → #lib::B
: #lib::B::i = i, super dart.core::Object::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Field 'j', type = dart:core::int, getter = 'get:j', reflectable, final
value = null
@ -619,7 +570,6 @@ Function '', constructor, const, reflectable, debuggable
parameters [dart:core::int 'a', dart:core::int 'b', dart:core::int 'c'] (required: 3)
return-type #lib::C
Bytecode {
Entry 0
CheckStack 0
@ -644,19 +594,9 @@ ConstantPool {
[3] = Reserved
}
}
Class 'D', script = '#lib'
extends dart:core::Object
}
] class C extends #lib::B {
final field dart.core::int j;
const constructor •(dart.core::int a, dart.core::int b, dart.core::int c) → #lib::C
: #lib::C::j = a.{dart.core::num::+}(b), super #lib::B::•(c.{dart.core::num::*}(5))
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Field 'x', type = dynamic, getter = 'get:x', reflectable, final
value = null
@ -667,7 +607,6 @@ Function '', constructor, const, has-optional-positional-params, reflectable, de
parameters [dynamic 'x', dynamic 'y'] (required: 1)
return-type #lib::D
Bytecode {
EntryOptional 2, 1, 0
LoadConstant r2, CP#0
@ -695,26 +634,15 @@ ConstantPool {
[6] = Reserved
}
}
Class 'E', script = '#lib'
type-params <dart:core::Object T> (args: 1)
extends dart:core::Object
}
] class D extends dart.core::Object {
final field dynamic x;
final field dynamic y;
const constructor •(dynamic x, [dynamic y = null]) → #lib::D
: #lib::D::x = x, #lib::D::y = y, super dart.core::Object::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, const, reflectable, debuggable
parameters [] (required: 0)
return-type #lib::E < #lib::E::TypeParam/0 >
Bytecode {
Entry 0
CheckStack 0
@ -729,24 +657,15 @@ ConstantPool {
[1] = Reserved
}
}
Class 'F', script = '#lib'
type-params <dart:core::Object P, dart:core::Object Q> (args: 3)
extends #lib::E < dart:core::Map < #lib::F::TypeParam/0, #lib::F::TypeParam/1 > >
}
] class E<T extends dart.core::Object = dynamic> extends dart.core::Object {
const constructor •() → #lib::E<#lib::E::T>
: super dart.core::Object::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, const, reflectable, debuggable
parameters [] (required: 0)
return-type #lib::F < dart:core::Map < #lib::F::TypeParam/0, #lib::F::TypeParam/1 >, #lib::F::TypeParam/0, #lib::F::TypeParam/1 >
Bytecode {
Entry 0
CheckStack 0
@ -761,10 +680,50 @@ ConstantPool {
[1] = Reserved
}
}
}
] class F<P extends dart.core::Object = dynamic, Q extends dart.core::Object = dynamic> extends #lib::E<dart.core::Map<#lib::F::P, #lib::F::Q>> {
]library #lib from "#lib" as #lib {
typedef GenericFunctionType = <X extends dart.core::Object = dynamic>(X) → X;
class A extends dart.core::Object {
final field dart.core::int index;
final field dart.core::String _name;
static const field dart.core::List<#lib::A> values = const <#lib::A>[#lib::A::elem1, #lib::A::elem2, #lib::A::elem3, #lib::A::elem4];
static const field #lib::A elem1 = const #lib::A::•(0, "A.elem1");
static const field #lib::A elem2 = const #lib::A::•(1, "A.elem2");
static const field #lib::A elem3 = const #lib::A::•(2, "A.elem3");
static const field #lib::A elem4 = const #lib::A::•(3, "A.elem4");
const constructor •(dart.core::int index, dart.core::String _name) → #lib::A
: #lib::A::index = index, #lib::A::_name = _name, super dart.core::Object::•()
;
method toString() → dart.core::String
return this.{=#lib::A::_name};
}
class B extends dart.core::Object {
final field dart.core::int i;
const constructor •(dart.core::int i) → #lib::B
: #lib::B::i = i, super dart.core::Object::•()
;
}
class C extends #lib::B {
final field dart.core::int j;
const constructor •(dart.core::int a, dart.core::int b, dart.core::int c) → #lib::C
: #lib::C::j = a.{dart.core::num::+}(b), super #lib::B::•(c.{dart.core::num::*}(5))
;
}
class D extends dart.core::Object {
final field dynamic x;
final field dynamic y;
const constructor •(dynamic x, [dynamic y = null]) → #lib::D
: #lib::D::x = x, #lib::D::y = y, super dart.core::Object::•()
;
}
class E<T extends dart.core::Object = dynamic> extends dart.core::Object {
const constructor •() → #lib::E<#lib::E::T>
: super dart.core::Object::•()
;
}
class F<P extends dart.core::Object = dynamic, Q extends dart.core::Object = dynamic> extends #lib::E<dart.core::Map<#lib::F::P, #lib::F::Q>> {
const constructor •() → #lib::F<#lib::F::P, #lib::F::Q>
: super #lib::E::•()
;

View file

@ -1,21 +1,19 @@
main = #lib::main;
[@vm.bytecode=
ComponentBytecodeMetadata {
BytecodeMetadata {
Bytecode (version: stable)
Main library: #lib
Library '#lib'
name '#lib'
script '#lib'
}
] [@vm.bytecode=
MembersBytecodeMetadata {
Class '', script = '#lib'
Members {
Function 'test_for', static, reflectable, debuggable
parameters [dart:core::List < dart:core::int > 'list'] (required: 1)
return-type dart:core::int
Bytecode {
Entry 2
CheckStack 0
@ -58,7 +56,6 @@ Function 'test_for_break', static, reflectable, debuggable
parameters [dart:core::List < dart:core::int > 'list'] (required: 1)
return-type dart:core::int
Bytecode {
Entry 2
CheckStack 0
@ -107,7 +104,6 @@ Function 'test_for_continue', static, reflectable, debuggable
parameters [dart:core::List < dart:core::int > 'list'] (required: 1)
return-type dart:core::int
Bytecode {
Entry 2
CheckStack 0
@ -158,7 +154,6 @@ Function 'test_while', static, reflectable, debuggable
parameters [dart:core::List < dart:core::int > 'list'] (required: 1)
return-type dart:core::int
Bytecode {
Entry 4
CheckStack 0
@ -203,7 +198,6 @@ Function 'test_do_while', static, reflectable, debuggable
parameters [dart:core::List < dart:core::int > 'list'] (required: 1)
return-type dart:core::int
Bytecode {
Entry 2
CheckStack 0
@ -243,7 +237,6 @@ Function 'test_for_in', static, reflectable, debuggable
parameters [dart:core::List < dart:core::int > 'list'] (required: 1)
return-type dart:core::int
Bytecode {
Entry 3
CheckStack 0
@ -283,7 +276,6 @@ Function 'test_for_in_with_outer_var', static, reflectable, debuggable
parameters [dart:core::List < dart:core::int > 'list'] (required: 1)
return-type dart:core::int
Bytecode {
Entry 4
CheckStack 0
@ -327,7 +319,6 @@ Function 'main', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -337,7 +328,6 @@ Bytecode {
ConstantPool {
}
}
}
]library #lib from "#lib" as #lib {

View file

@ -1,21 +1,19 @@
main = #lib::main;
[@vm.bytecode=
ComponentBytecodeMetadata {
BytecodeMetadata {
Bytecode (version: stable)
Main library: #lib
Library '#lib'
name '#lib'
script '#lib'
}
] [@vm.bytecode=
MembersBytecodeMetadata {
Class '', script = '#lib'
Members {
Function 'foo1', static, has-optional-positional-params, reflectable, debuggable
parameters [dynamic 'x', dynamic 'a', dynamic 'b'] (required: 1)
return-type void
Bytecode {
EntryOptional 1, 2, 0
LoadConstant r1, CP#0
@ -87,7 +85,6 @@ Function 'foo2', static, has-optional-named-params, reflectable, debuggable
parameters [dynamic 'y', dynamic 'z', dynamic 'c', dynamic 'a', dynamic 'b'] (required: 2)
return-type void
Bytecode {
EntryOptional 2, 0, 3
LoadConstant r2, CP#0
@ -200,7 +197,6 @@ Function 'foo3', static, has-optional-named-params, reflectable, debuggable
parameters [dynamic 'z', dynamic 'y', dart:core::bool 'a', dart:core::Map < #lib::foo3::TypeParam/0, #lib::foo3::TypeParam/1 > 'b'] (required: 2)
return-type void
Bytecode {
EntryOptional 2, 0, 2
LoadConstant r2, CP#0
@ -239,7 +235,6 @@ Function 'main', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -266,7 +261,6 @@ ConstantPool {
[7] = Reserved
}
}
}
]library #lib from "#lib" as #lib {

View file

@ -1,21 +1,19 @@
main = #lib::main;
[@vm.bytecode=
ComponentBytecodeMetadata {
BytecodeMetadata {
Bytecode (version: stable)
Main library: #lib
Library '#lib'
name '#lib'
script '#lib'
}
] [@vm.bytecode=
MembersBytecodeMetadata {
Class '', script = '#lib'
Members {
Function 'main', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -25,21 +23,14 @@ Bytecode {
ConstantPool {
}
}
Class 'Base1', script = '#lib'
extends dart:core::Object
}
]library #lib from "#lib" as #lib {
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::Base1
Bytecode {
Entry 0
CheckStack 0
@ -60,7 +51,6 @@ Function 'foo', reflectable, debuggable
parameters [#lib::Base1::foo::TypeParam/0 'a1', dart:core::int 'a2'] (required: 2)
return-type void
Bytecode {
Entry 1
CheckStack 0
@ -76,7 +66,6 @@ Function 'get:bar', getter, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -91,7 +80,6 @@ Function 'set:bazz', setter, reflectable, debuggable
parameters [dart:core::int 'x'] (required: 1)
return-type void
Bytecode {
Entry 0
CheckStack 0
@ -101,28 +89,14 @@ Bytecode {
ConstantPool {
}
}
Class 'A', script = '#lib'
extends #lib::Base1
}
] class Base1 extends dart.core::Object {
synthetic constructor •() → #lib::Base1
: super dart.core::Object::•()
;
method foo<T extends dart.core::Object = dynamic>(#lib::Base1::foo::T a1, dart.core::int a2) → void {}
get bar() → dynamic
return 42;
set bazz(dart.core::int x) → void {}
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::A
Bytecode {
Entry 0
CheckStack 0
@ -142,7 +116,6 @@ Function 'testSuperCall', reflectable, debuggable
parameters [dart:core::int 'x'] (required: 1)
return-type dynamic
Bytecode {
Entry 1
CheckStack 0
@ -165,7 +138,6 @@ Function 'testSuperTearOff', reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 1
CheckStack 0
@ -183,7 +155,6 @@ Function 'testSuperGet', reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 1
CheckStack 0
@ -201,7 +172,6 @@ Function 'testSuperCallViaGetter', reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 1
CheckStack 0
@ -226,7 +196,6 @@ Function 'testSuperSet', reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 1
CheckStack 0
@ -242,35 +211,14 @@ ConstantPool {
[1] = Reserved
}
}
Class 'Base2', script = '#lib', abstract
extends dart:core::Object
}
] class A extends #lib::Base1 {
synthetic constructor •() → #lib::A
: super #lib::Base1::•()
;
method testSuperCall(dart.core::int x) → dynamic
return super.{#lib::Base1::foo}<dart.core::String>("a1", 2);
method testSuperTearOff() → dynamic
return super.{#lib::Base1::foo};
method testSuperGet() → dynamic
return super.{#lib::Base1::bar};
method testSuperCallViaGetter() → dynamic
return [@vm.call-site-attributes.metadata=receiverType:dynamic] super.{#lib::Base1::bar}.call<dart.core::int>("param");
method testSuperSet() → dynamic {
super.{#lib::Base1::bazz} = 3;
}
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::Base2
Bytecode {
Entry 0
CheckStack 0
@ -298,27 +246,14 @@ Function 'get:bar', getter, abstract, reflectable, debuggable
Function 'set:bazz', setter, abstract, reflectable, debuggable
parameters [dart:core::int 'x'] (required: 1)
return-type void
}
Class 'B', script = '#lib', abstract
extends #lib::Base2
}
] abstract class Base2 extends dart.core::Object {
synthetic constructor •() → #lib::Base2
: super dart.core::Object::•()
;
abstract method foo<T extends dart.core::Object = dynamic>(dart.core::String a1, #lib::Base2::foo::T a2, dart.core::int a3) → void;
abstract get bar() → dynamic;
abstract set bazz(dart.core::int x) → void;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::B
Bytecode {
Entry 0
CheckStack 0
@ -338,7 +273,6 @@ Function 'testSuperCall', reflectable, debuggable
parameters [dart:core::int 'x'] (required: 1)
return-type dynamic
Bytecode {
Entry 1
CheckStack 0
@ -392,7 +326,6 @@ Function 'testSuperTearOff', reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 1
CheckStack 0
@ -427,7 +360,6 @@ Function 'testSuperGet', reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 1
CheckStack 0
@ -462,7 +394,6 @@ Function 'testSuperCallViaGetter', reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 1
CheckStack 0
@ -504,7 +435,6 @@ Function 'testSuperSet', reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 1
CheckStack 0
@ -540,10 +470,44 @@ ConstantPool {
[6] = Reserved
}
}
}
] abstract class B extends #lib::Base2 {
]library #lib from "#lib" as #lib {
class Base1 extends dart.core::Object {
synthetic constructor •() → #lib::Base1
: super dart.core::Object::•()
;
method foo<T extends dart.core::Object = dynamic>(#lib::Base1::foo::T a1, dart.core::int a2) → void {}
get bar() → dynamic
return 42;
set bazz(dart.core::int x) → void {}
}
class A extends #lib::Base1 {
synthetic constructor •() → #lib::A
: super #lib::Base1::•()
;
method testSuperCall(dart.core::int x) → dynamic
return super.{#lib::Base1::foo}<dart.core::String>("a1", 2);
method testSuperTearOff() → dynamic
return super.{#lib::Base1::foo};
method testSuperGet() → dynamic
return super.{#lib::Base1::bar};
method testSuperCallViaGetter() → dynamic
return [@vm.call-site-attributes.metadata=receiverType:dynamic] super.{#lib::Base1::bar}.call<dart.core::int>("param");
method testSuperSet() → dynamic {
super.{#lib::Base1::bazz} = 3;
}
}
abstract class Base2 extends dart.core::Object {
synthetic constructor •() → #lib::Base2
: super dart.core::Object::•()
;
abstract method foo<T extends dart.core::Object = dynamic>(dart.core::String a1, #lib::Base2::foo::T a2, dart.core::int a3) → void;
abstract get bar() → dynamic;
abstract set bazz(dart.core::int x) → void;
}
abstract class B extends #lib::Base2 {
synthetic constructor •() → #lib::B
: super #lib::Base2::•()
;

View file

@ -1,21 +1,19 @@
main = #lib::main;
[@vm.bytecode=
ComponentBytecodeMetadata {
BytecodeMetadata {
Bytecode (version: stable)
Main library: #lib
Library '#lib'
name '#lib'
script '#lib'
}
] [@vm.bytecode=
MembersBytecodeMetadata {
Class '', script = '#lib'
Members {
Function 'foo1', static, reflectable, debuggable
parameters [dart:core::int 'x'] (required: 1)
return-type dart:core::int
Bytecode {
Entry 2
CheckStack 0
@ -62,7 +60,6 @@ Function 'foo2', static, reflectable, debuggable
parameters [dart:core::int 'x'] (required: 1)
return-type dart:core::int
Bytecode {
Entry 2
CheckStack 0
@ -120,7 +117,6 @@ Function 'foo3', static, reflectable, debuggable
parameters [dart:core::int 'x'] (required: 1)
return-type dart:core::int
Bytecode {
Entry 2
CheckStack 0
@ -178,7 +174,6 @@ Function 'main', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -188,7 +183,6 @@ Bytecode {
ConstantPool {
}
}
}
]library #lib from "#lib" as #lib {

View file

@ -1,21 +1,19 @@
main = #lib::main;
[@vm.bytecode=
ComponentBytecodeMetadata {
BytecodeMetadata {
Bytecode (version: stable)
Main library: #lib
Library '#lib'
name '#lib'
script '#lib'
}
] [@vm.bytecode=
MembersBytecodeMetadata {
Class '', script = '#lib'
Members {
Function 'testTryCatch1', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 4
CheckStack 0
@ -69,7 +67,6 @@ Function 'testTryCatch2', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 5
CheckStack 0
@ -207,7 +204,6 @@ Function 'testTryCatch3', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 7
CheckStack 0
@ -381,7 +377,6 @@ Try #0 handler:
L1:
PushNull
ReturnTOS
}
Closure #lib::testTryCatch3::'bar' () -> void
@ -443,7 +438,6 @@ L2:
L1:
PushNull
ReturnTOS
}
@ -451,7 +445,6 @@ Function 'testRethrow', static, reflectable, debuggable
parameters [dart:core::bool 'cond'] (required: 1)
return-type dynamic
Bytecode {
Entry 8
CheckStack 0
@ -535,7 +528,6 @@ Function 'testTryFinally1', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 3
CheckStack 0
@ -599,7 +591,6 @@ Function 'testTryFinally2', static, reflectable, debuggable
parameters [dart:core::int 'x'] (required: 1)
return-type dynamic
Bytecode {
Entry 9
CheckStack 0
@ -756,7 +747,6 @@ ClosureCode {
Drop1
PushNull
ReturnTOS
}
@ -764,7 +754,6 @@ Function 'testTryFinally3', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 6
CheckStack 0
@ -944,7 +933,6 @@ L3:
Drop1
PushInt 43
ReturnTOS
}
@ -952,7 +940,6 @@ Function 'testTryCatchFinally', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 5
CheckStack 0
@ -1011,7 +998,6 @@ Function 'main', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -1021,7 +1007,6 @@ Bytecode {
ConstantPool {
}
}
}
]library #lib from "#lib" as #lib {

View file

@ -1,15 +1,14 @@
main = #lib::main;
[@vm.bytecode=
ComponentBytecodeMetadata {
BytecodeMetadata {
Bytecode (version: stable)
Main library: #lib
Library '#lib'
name '#lib'
script '#lib'
}
] [@vm.bytecode=
MembersBytecodeMetadata {
Class '', script = '#lib'
Members {
Field 'globalVar', type = dart:core::List < dart:core::Iterable null >, reflectable, static
value = null
@ -17,7 +16,6 @@ Function 'foo1', static, reflectable, debuggable
parameters [dynamic 'x'] (required: 1)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -48,7 +46,7 @@ L2:
ReturnTOS
}
ConstantPool {
[0] = Type #lib::B
[0] = Type #lib::B < dart:core::String >
[1] = InterfaceCall 'dart:core::Object::_simpleInstanceOf', ArgDesc num-args 2, num-type-args 0, names []
[2] = Reserved
[3] = ObjectRef '11'
@ -68,7 +66,6 @@ Function 'foo5', static, reflectable, debuggable
parameters [dynamic 'x'] (required: 1)
return-type void
Bytecode {
Entry 1
CheckStack 0
@ -94,7 +91,6 @@ Function 'main', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
@ -104,21 +100,15 @@ Bytecode {
ConstantPool {
}
}
Class 'A', script = '#lib'
type-params <dart:core::Object T> (args: 1)
extends dart:core::Object
}
]library #lib from "#lib" as #lib {
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::A < #lib::A::TypeParam/0 >
Bytecode {
Entry 0
CheckStack 0
@ -133,23 +123,13 @@ ConstantPool {
[1] = Reserved
}
}
Class 'B', script = '#lib'
extends #lib::A < dart:core::String >
}
] class A<T extends dart.core::Object = dynamic> extends dart.core::Object {
synthetic constructor •() → #lib::A<#lib::A::T>
: super dart.core::Object::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::B
return-type #lib::B < dart:core::String >
Bytecode {
Entry 0
@ -165,24 +145,15 @@ ConstantPool {
[1] = Reserved
}
}
Class 'C', script = '#lib'
type-params <dart:core::Object T1, dart:core::Object T2, dart:core::Object T3> (args: 4)
extends #lib::B < dart:core::String >
}
] class B extends #lib::A<dart.core::String> {
synthetic constructor •() → #lib::B
: super #lib::A::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', constructor, reflectable
parameters [] (required: 0)
return-type #lib::C < dart:core::String, #lib::C::TypeParam/0, #lib::C::TypeParam/1, #lib::C::TypeParam/2 >
Bytecode {
Entry 0
CheckStack 0
@ -197,18 +168,10 @@ ConstantPool {
[1] = Reserved
}
}
Class 'D', script = '#lib'
type-params <dart:core::Object P, dart:core::Object Q> (args: 5)
extends #lib::C < dart:core::String, dart:core::int, #lib::D::TypeParam/1, #lib::D::TypeParam/0 >
}
] class C<T1 extends dart.core::Object = dynamic, T2 extends dart.core::Object = dynamic, T3 extends dart.core::Object = dynamic> extends #lib::B {
synthetic constructor •() → #lib::C<#lib::C::T1, #lib::C::T2, #lib::C::T3>
: super #lib::B::•()
;
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Field 'foo', type = dart:core::Map < #lib::D::TypeParam/0, #lib::D::TypeParam/1 >, getter = 'get:foo', setter = 'set:foo', reflectable
value = null
@ -216,7 +179,6 @@ Function '', constructor, reflectable, debuggable
parameters [dynamic 'tt'] (required: 1)
return-type #lib::D < dart:core::String, dart:core::int, #lib::D::TypeParam/1, #lib::D::TypeParam/0, #lib::D::TypeParam/1 >
Bytecode {
Entry 0
CheckStack 0
@ -251,7 +213,6 @@ Function 'foo2', reflectable, debuggable
parameters [dynamic 'y'] (required: 1)
return-type dynamic
Bytecode {
Entry 1
CheckStack 0
@ -313,7 +274,6 @@ Function 'foo3', reflectable, debuggable
parameters [dynamic 'z'] (required: 1)
return-type dynamic
Bytecode {
Entry 1
CheckStack 0
@ -371,7 +331,6 @@ Function 'foo4', reflectable, debuggable
parameters [dynamic 'w'] (required: 1)
return-type dart:core::Map < #lib::D::TypeParam/0, #lib::D::TypeParam/1 >
Bytecode {
Entry 2
CheckStack 0
@ -416,48 +375,16 @@ ConstantPool {
[7] = SubtypeTestCache
}
}
Class 'E', script = '#lib'
type-params <dart:core::String P> (args: 1)
extends dart:core::Object
}
] class D<P extends dart.core::Object = dynamic, Q extends dart.core::Object = dynamic> extends #lib::C<dart.core::int, #lib::D::Q, #lib::D::P> {
generic-covariant-impl field dart.core::Map<#lib::D::P, #lib::D::Q> foo;
constructor •(dynamic tt) → #lib::D<#lib::D::P, #lib::D::Q>
: #lib::D::foo = tt as{TypeError} dart.core::Map<#lib::D::P, #lib::D::Q>, super #lib::C::•()
;
method foo2(dynamic y) → dynamic {
if(y is #lib::A<#lib::D::P>) {
dart.core::print("21");
}
if(y is #lib::C<dynamic, #lib::D::Q, dart.core::List<#lib::D::P>>) {
dart.core::print("22");
}
[@vm.call-site-attributes.metadata=receiverType:#lib::D<#lib::D::P, #lib::D::Q>] this.{#lib::D::foo} = y as{TypeError} dart.core::Map<#lib::D::P, #lib::D::Q>;
}
method foo3<T1 extends dart.core::Object = dynamic, T2 extends dart.core::Object = dynamic>(dynamic z) → dynamic {
if(z is #lib::A<#lib::D::foo3::T1>) {
dart.core::print("31");
}
if(z is #lib::C<dart.core::Map<#lib::D::foo3::T1, #lib::D::P>, dart.core::List<#lib::D::foo3::T2>, #lib::D::Q>) {
dart.core::print("32");
}
return (z as dart.core::Map<#lib::D::foo3::T2, #lib::D::Q>).{dart.core::Map::values};
}
method foo4(dynamic w) → dart.core::Map<#lib::D::P, #lib::D::Q> {
dart.core::List<dart.core::Map<#lib::D::P, #lib::D::Q>> list = <dart.core::Map<#lib::D::P, #lib::D::Q>>[w as{TypeError} dart.core::Map<#lib::D::P, #lib::D::Q>];
return w as{TypeError} dart.core::Map<#lib::D::P, #lib::D::Q>;
}
}
[@vm.bytecode=
MembersBytecodeMetadata {
Members {
Function '', factory, static, reflectable, debuggable
type-params <dart:core::String P>
parameters [] (required: 0)
return-type #lib::E < #lib::E:: (constructor)::TypeParam/0 >
Bytecode {
Entry 0
CheckStack 0
@ -473,7 +400,6 @@ Function 'foo6', reflectable, debuggable
parameters [dart:core::Map < #lib::E::foo6::TypeParam/0, #lib::E::foo6::TypeParam/1 > 'map'] (required: 1)
return-type void
Bytecode {
Entry 1
CheckStack 0
@ -504,10 +430,54 @@ ConstantPool {
[4] = ObjectRef 'T'
}
}
}
] class E<P extends dart.core::String = dart.core::String> extends dart.core::Object {
]library #lib from "#lib" as #lib {
class A<T extends dart.core::Object = dynamic> extends dart.core::Object {
synthetic constructor •() → #lib::A<#lib::A::T>
: super dart.core::Object::•()
;
}
class B extends #lib::A<dart.core::String> {
synthetic constructor •() → #lib::B
: super #lib::A::•()
;
}
class C<T1 extends dart.core::Object = dynamic, T2 extends dart.core::Object = dynamic, T3 extends dart.core::Object = dynamic> extends #lib::B {
synthetic constructor •() → #lib::C<#lib::C::T1, #lib::C::T2, #lib::C::T3>
: super #lib::B::•()
;
}
class D<P extends dart.core::Object = dynamic, Q extends dart.core::Object = dynamic> extends #lib::C<dart.core::int, #lib::D::Q, #lib::D::P> {
generic-covariant-impl field dart.core::Map<#lib::D::P, #lib::D::Q> foo;
constructor •(dynamic tt) → #lib::D<#lib::D::P, #lib::D::Q>
: #lib::D::foo = tt as{TypeError} dart.core::Map<#lib::D::P, #lib::D::Q>, super #lib::C::•()
;
method foo2(dynamic y) → dynamic {
if(y is #lib::A<#lib::D::P>) {
dart.core::print("21");
}
if(y is #lib::C<dynamic, #lib::D::Q, dart.core::List<#lib::D::P>>) {
dart.core::print("22");
}
[@vm.call-site-attributes.metadata=receiverType:#lib::D<#lib::D::P, #lib::D::Q>] this.{#lib::D::foo} = y as{TypeError} dart.core::Map<#lib::D::P, #lib::D::Q>;
}
method foo3<T1 extends dart.core::Object = dynamic, T2 extends dart.core::Object = dynamic>(dynamic z) → dynamic {
if(z is #lib::A<#lib::D::foo3::T1>) {
dart.core::print("31");
}
if(z is #lib::C<dart.core::Map<#lib::D::foo3::T1, #lib::D::P>, dart.core::List<#lib::D::foo3::T2>, #lib::D::Q>) {
dart.core::print("32");
}
return (z as dart.core::Map<#lib::D::foo3::T2, #lib::D::Q>).{dart.core::Map::values};
}
method foo4(dynamic w) → dart.core::Map<#lib::D::P, #lib::D::Q> {
dart.core::List<dart.core::Map<#lib::D::P, #lib::D::Q>> list = <dart.core::Map<#lib::D::P, #lib::D::Q>>[w as{TypeError} dart.core::Map<#lib::D::P, #lib::D::Q>];
return w as{TypeError} dart.core::Map<#lib::D::P, #lib::D::Q>;
}
}
class E<P extends dart.core::String = dart.core::String> extends dart.core::Object {
static factory •<P extends dart.core::String = dynamic>() → #lib::E<#lib::E::•::P>
return null;
method foo6<generic-covariant-impl T extends #lib::E::P = #lib::E::P, U extends dart.core::List<#lib::E::foo6::T> = dart.core::List<#lib::E::P>>(dart.core::Map<#lib::E::foo6::T, #lib::E::foo6::U> map) → void {}

View file

@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
// OtherResources=appjit_cha_deopt_test_body.dart
// VMOptions=--optimization-counter-threshold=100
// VMOptions=--optimization-counter-threshold=100 --deterministic
// Verify that app-jit snapshot contains dependencies between classes and CHA
// optimized code.

View file

@ -99,18 +99,10 @@ static RawError* BootstrapFromKernel(Thread* thread,
// Load the bootstrap libraries in order (see object_store.h).
Library& library = Library::Handle(zone);
String& dart_name = String::Handle(zone);
for (intptr_t i = 0; i < kBootstrapLibraryCount; ++i) {
ObjectStore::BootstrapLibraryId id = bootstrap_libraries[i].index;
library = isolate->object_store()->bootstrap_library(id);
dart_name = library.url();
for (intptr_t j = 0; j < program->library_count(); ++j) {
const String& kernel_name = loader.LibraryUri(j);
if (kernel_name.Equals(dart_name)) {
loader.LoadLibrary(j);
break;
}
}
loader.LoadLibrary(library);
}
// Finish bootstrapping, including class finalization.
@ -125,8 +117,8 @@ static RawError* BootstrapFromKernel(Thread* thread,
}
// The builtin library should be registered with the VM.
dart_name = String::New("dart:_builtin");
library = Library::LookupLibrary(thread, dart_name);
const auto& dart_builtin = String::Handle(zone, String::New("dart:_builtin"));
library = Library::LookupLibrary(thread, dart_builtin);
isolate->object_store()->set_builtin_library(library);
return Error::null();

View file

@ -1066,26 +1066,30 @@ void ClassFinalizer::FinalizeTypesInClass(const Class& cls) {
}
cls.set_is_type_finalized();
RegisterClassInHierarchy(thread->zone(), cls);
}
void ClassFinalizer::RegisterClassInHierarchy(Zone* zone, const Class& cls) {
auto& type = AbstractType::Handle(zone, cls.super_type());
auto& other_cls = Class::Handle(zone);
// Add this class to the direct subclasses of the superclass, unless the
// superclass is Object.
if (!super_type.IsNull() && !super_type.IsObjectType()) {
ASSERT(!super_class.IsNull());
super_class.AddDirectSubclass(cls);
if (!type.IsNull() && !type.IsObjectType()) {
other_cls = cls.SuperClass();
ASSERT(!other_cls.IsNull());
other_cls.AddDirectSubclass(cls);
}
// Add this class as an implementor to the implemented interface's type
// classes.
Zone* zone = thread->zone();
auto& interface_class = Class::Handle(zone);
const intptr_t mixin_index = cls.is_transformed_mixin_application()
? interface_types.Length() - 1
: -1;
for (intptr_t i = 0; i < interface_types.Length(); ++i) {
interface_type ^= interface_types.At(i);
interface_class = interface_type.type_class();
MarkImplemented(thread->zone(), interface_class);
interface_class.AddDirectImplementor(cls,
/* is_mixin = */ i == mixin_index);
const auto& interfaces = Array::Handle(zone, cls.interfaces());
const intptr_t mixin_index =
cls.is_transformed_mixin_application() ? interfaces.Length() - 1 : -1;
for (intptr_t i = 0; i < interfaces.Length(); ++i) {
type ^= interfaces.At(i);
other_cls = type.type_class();
MarkImplemented(zone, other_cls);
other_cls.AddDirectImplementor(cls, /* is_mixin = */ i == mixin_index);
}
}
@ -1113,9 +1117,14 @@ void ClassFinalizer::FinalizeClass(const Class& cls) {
#if !defined(DART_PRECOMPILED_RUNTIME)
// If loading from a kernel, make sure that the class is fully loaded.
ASSERT(cls.IsTopLevel() || (cls.kernel_offset() > 0));
ASSERT(cls.IsTopLevel() || cls.is_declared_in_bytecode() ||
(cls.kernel_offset() > 0));
if (!cls.is_loaded()) {
kernel::KernelLoader::FinishLoading(cls);
if (cls.is_declared_in_bytecode()) {
kernel::BytecodeReader::FinishClassLoading(cls);
} else {
kernel::KernelLoader::FinishLoading(cls);
}
if (cls.is_finalized()) {
return;
}
@ -1180,6 +1189,14 @@ RawError* ClassFinalizer::LoadClassMembers(const Class& cls) {
ASSERT(Thread::Current()->IsMutatorThread());
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
#if !defined(DART_PRECOMPILED_RUNTIME)
if (!cls.is_declaration_loaded()) {
// Loading of class declaration can be postponed until needed
// if class comes from bytecode.
ASSERT(cls.is_declared_in_bytecode());
kernel::BytecodeReader::LoadClassDeclaration(cls);
}
#endif
// TODO(36584) : We expect is_type_finalized to be true for all classes
// here, but with eager reading of the constant table we get into
// situations where we see classes whose types have not been finalized yet,
@ -1241,7 +1258,7 @@ void ClassFinalizer::AllocateEnumValues(const Class& enum_cls) {
->object_store()
->pending_unevaluated_const_fields());
ASSERT(enum_cls.kernel_offset() > 0);
ASSERT(enum_cls.is_declared_in_bytecode() || enum_cls.kernel_offset() > 0);
Error& error = Error::Handle(zone);
for (intptr_t i = 0; i < fields.Length(); i++) {
field = Field::RawCast(fields.At(i));
@ -1419,7 +1436,7 @@ void ClassFinalizer::SortClasses() {
continue;
}
cls = table->At(cid);
if (cls.is_patch()) {
if (cls.is_patch() || !cls.is_declaration_loaded()) {
continue;
}
if (cls.SuperClass() == I->object_store()->object_class()) {

View file

@ -57,6 +57,9 @@ class ClassFinalizer : public AllStatic {
// is an anonymous top level class).
static void FinalizeTypesInClass(const Class& cls);
// Register class in the lists of direct subclasses and direct implementors.
static void RegisterClassInHierarchy(Zone* zone, const Class& cls);
// Finalize the class including its fields and functions.
static void FinalizeClass(const Class& cls);

View file

@ -178,7 +178,7 @@ class ClassSerializationCluster : public SerializationCluster {
}
s->WriteCid(class_id);
if (s->kind() != Snapshot::kFullAOT) {
s->Write<int32_t>(cls->ptr()->kernel_offset_);
s->Write<uint32_t>(cls->ptr()->binary_declaration_);
}
s->Write<int32_t>(cls->ptr()->instance_size_in_words_);
s->Write<int32_t>(cls->ptr()->next_field_offset_in_words_);
@ -233,7 +233,7 @@ class ClassDeserializationCluster : public DeserializationCluster {
cls->ptr()->id_ = class_id;
#if !defined(DART_PRECOMPILED_RUNTIME)
if (d->kind() != Snapshot::kFullAOT) {
cls->ptr()->kernel_offset_ = d->Read<int32_t>();
cls->ptr()->binary_declaration_ = d->Read<uint32_t>();
}
#endif
if (!RawObject::IsInternalVMdefinedClassId(class_id)) {
@ -264,7 +264,7 @@ class ClassDeserializationCluster : public DeserializationCluster {
cls->ptr()->id_ = class_id;
#if !defined(DART_PRECOMPILED_RUNTIME)
if (d->kind() != Snapshot::kFullAOT) {
cls->ptr()->kernel_offset_ = d->Read<int32_t>();
cls->ptr()->binary_declaration_ = d->Read<uint32_t>();
}
#endif
cls->ptr()->instance_size_in_words_ = d->Read<int32_t>();
@ -1176,7 +1176,7 @@ class LibrarySerializationCluster : public SerializationCluster {
s->Write<bool>(lib->ptr()->is_dart_scheme_);
s->Write<bool>(lib->ptr()->debuggable_);
if (s->kind() != Snapshot::kFullAOT) {
s->Write<int32_t>(lib->ptr()->kernel_offset_);
s->Write<uint32_t>(lib->ptr()->binary_declaration_);
}
}
}
@ -1216,7 +1216,7 @@ class LibraryDeserializationCluster : public DeserializationCluster {
lib->ptr()->is_in_fullsnapshot_ = true;
#if !defined(DART_PRECOMPILED_RUNTIME)
if (d->kind() != Snapshot::kFullAOT) {
lib->ptr()->kernel_offset_ = d->Read<int32_t>();
lib->ptr()->binary_declaration_ = d->Read<uint32_t>();
}
#endif
}
@ -1364,7 +1364,7 @@ class KernelProgramInfoDeserializationCluster : public DeserializationCluster {
array = info.bytecode_component();
if (!array.IsNull()) {
kernel::BytecodeReader::UseBytecodeVersion(
kernel::BytecodeComponentData(array).GetVersion());
kernel::BytecodeComponentData(&array).GetVersion());
}
}
}

View file

@ -11,6 +11,7 @@
#include "vm/compiler/assembler/disassembler_kbc.h"
#include "vm/compiler/frontend/bytecode_scope_builder.h"
#include "vm/constants_kbc.h"
#include "vm/dart_api_impl.h" // For Api::IsFfiEnabled().
#include "vm/dart_entry.h"
#include "vm/debugger.h"
#include "vm/longjump.h"
@ -59,12 +60,14 @@ void BytecodeMetadataHelper::ParseBytecodeFunction(
}
BytecodeComponentData bytecode_component(
Array::Handle(helper_->zone_, GetBytecodeComponent()));
&Array::Handle(helper_->zone_, GetBytecodeComponent()));
BytecodeReaderHelper bytecode_reader(&H, active_class_, &bytecode_component);
bytecode_reader.ParseBytecodeFunction(parsed_function, function);
}
static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 10,
"Cleanup support for old bytecode format versions");
bool BytecodeMetadataHelper::ReadMembers(intptr_t node_offset,
const Class& cls,
bool discard_fields) {
@ -80,18 +83,65 @@ bool BytecodeMetadataHelper::ReadMembers(intptr_t node_offset,
ASSERT(Thread::Current()->IsMutatorThread());
BytecodeComponentData bytecode_component(
Array::Handle(helper_->zone_, GetBytecodeComponent()));
&Array::Handle(helper_->zone_, GetBytecodeComponent()));
BytecodeReaderHelper bytecode_reader(&H, active_class_, &bytecode_component);
AlternativeReadingScope alt(&bytecode_reader.reader(), md_offset);
intptr_t members_offset = bytecode_reader.reader().ReadUInt();
intptr_t members_offset = bytecode_component.GetMembersOffset() +
bytecode_reader.reader().ReadUInt();
bytecode_reader.ReadMembers(cls, members_offset, discard_fields);
AlternativeReadingScope alt2(&bytecode_reader.reader(), members_offset);
bytecode_reader.ReadMembers(cls, discard_fields);
return true;
}
bool BytecodeMetadataHelper::ReadLibraries() {
TIMELINE_DURATION(Thread::Current(), Compiler,
"BytecodeMetadataHelper::ReadLibraries");
ASSERT(Thread::Current()->IsMutatorThread());
if (translation_helper_.GetBytecodeComponent() == Array::null()) {
return false;
}
BytecodeComponentData bytecode_component(
&Array::Handle(helper_->zone_, GetBytecodeComponent()));
static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 10,
"Cleanup condition");
if (bytecode_component.GetVersion() < 10) {
return false;
}
BytecodeReaderHelper bytecode_reader(&H, active_class_, &bytecode_component);
AlternativeReadingScope alt(&bytecode_reader.reader(),
bytecode_component.GetLibraryIndexOffset());
bytecode_reader.ReadLibraryDeclarations(bytecode_component.GetNumLibraries());
return true;
}
void BytecodeMetadataHelper::ReadLibrary(const Library& library) {
TIMELINE_DURATION(Thread::Current(), Compiler,
"BytecodeMetadataHelper::ReadLibrary");
ASSERT(Thread::Current()->IsMutatorThread());
ASSERT(!library.Loaded());
if (translation_helper_.GetBytecodeComponent() == Array::null()) {
return;
}
BytecodeComponentData bytecode_component(
&Array::Handle(helper_->zone_, GetBytecodeComponent()));
BytecodeReaderHelper bytecode_reader(&H, active_class_, &bytecode_component);
AlternativeReadingScope alt(&bytecode_reader.reader(),
library.bytecode_offset());
bytecode_reader.FindAndReadSpecificLibrary(
library, bytecode_component.GetNumLibraries());
}
RawLibrary* BytecodeMetadataHelper::GetMainLibrary() {
const intptr_t md_offset = GetComponentMetadataPayloadOffset();
if (md_offset < 0) {
@ -99,7 +149,7 @@ RawLibrary* BytecodeMetadataHelper::GetMainLibrary() {
}
BytecodeComponentData bytecode_component(
Array::Handle(helper_->zone_, GetBytecodeComponent()));
&Array::Handle(helper_->zone_, GetBytecodeComponent()));
const intptr_t main_offset = bytecode_component.GetMainOffset();
if (main_offset == 0) {
return Library::null();
@ -976,6 +1026,23 @@ RawArray* BytecodeReaderHelper::ReadBytecodeComponent(intptr_t md_offset) {
reader_.ReadUInt32(); // Skip main.numItems
const intptr_t main_offset = start_offset + reader_.ReadUInt32();
intptr_t num_libraries = 0;
intptr_t library_index_offset = 0;
intptr_t libraries_offset = 0;
intptr_t classes_offset = 0;
static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 10,
"Cleanup condition");
if (version >= 10) {
num_libraries = reader_.ReadUInt32();
library_index_offset = start_offset + reader_.ReadUInt32();
reader_.ReadUInt32(); // Skip libraries.numItems
libraries_offset = start_offset + reader_.ReadUInt32();
reader_.ReadUInt32(); // Skip classes.numItems
classes_offset = start_offset + reader_.ReadUInt32();
}
reader_.ReadUInt32(); // Skip members.numItems
const intptr_t members_offset = start_offset + reader_.ReadUInt32();
@ -983,7 +1050,19 @@ RawArray* BytecodeReaderHelper::ReadBytecodeComponent(intptr_t md_offset) {
const intptr_t codes_offset = start_offset + reader_.ReadUInt32();
reader_.ReadUInt32(); // Skip sourcePositions.numItems
const intptr_t sources_positions_offset = start_offset + reader_.ReadUInt32();
const intptr_t source_positions_offset = start_offset + reader_.ReadUInt32();
intptr_t source_files_offset = 0;
intptr_t line_starts_offset = 0;
static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 10,
"Cleanup condition");
if (version >= 10) {
reader_.ReadUInt32(); // Skip sourceFiles.numItems
source_files_offset = start_offset + reader_.ReadUInt32();
reader_.ReadUInt32(); // Skip lineStarts.numItems
line_starts_offset = start_offset + reader_.ReadUInt32();
}
intptr_t local_variables_offset = 0;
static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 9,
@ -1012,14 +1091,16 @@ RawArray* BytecodeReaderHelper::ReadBytecodeComponent(intptr_t md_offset) {
const intptr_t objects_contents_offset = reader_.offset();
reader_.set_offset(objects_contents_offset + objects_size);
const Array& bytecode_component_array = Array::Handle(
auto& bytecode_component_array = Array::Handle(
Z, BytecodeComponentData::New(
Z, version, num_objects, string_table_offset,
strings_contents_offset, objects_contents_offset, main_offset,
members_offset, codes_offset, sources_positions_offset,
num_libraries, library_index_offset, libraries_offset,
classes_offset, members_offset, codes_offset,
source_positions_offset, source_files_offset, line_starts_offset,
local_variables_offset, annotations_offset, Heap::kOld));
BytecodeComponentData bytecode_component(bytecode_component_array);
BytecodeComponentData bytecode_component(&bytecode_component_array);
// Read object offsets.
Smi& offs = Smi::Handle(Z);
@ -1076,6 +1157,8 @@ RawString* BytecodeReaderHelper::ConstructorName(const Class& cls,
RawObject* BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
ASSERT(((header & kReferenceBit) == 0));
static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 10,
"Cleanup obsolete object kinds");
// Must be in sync with enum ObjectKind in
// pkg/vm/lib/bytecode/object_table.dart.
enum ObjectKind {
@ -1084,15 +1167,17 @@ RawObject* BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
kClass,
kMember,
kClosure,
kSimpleType,
kTypeParameter,
kGenericType,
kFunctionType,
kSimpleType, // obsolete in v10
kTypeParameter, // obsolete in v10
kGenericType, // obsolete in v10
kFunctionType, // obsolete in v10
kName,
kTypeArguments,
kFinalizedGenericType,
kFinalizedGenericType, // obsolete in v10
kConstObject,
kArgDesc,
kScript,
kType,
};
// Member flags, must be in sync with _MemberHandle constants in
@ -1105,6 +1190,8 @@ RawObject* BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
const intptr_t kFlagIsDynamic = kFlagBit0;
const intptr_t kFlagIsVoid = kFlagBit1;
static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 10,
"Cleanup old FunctionType flags");
// FunctionType flags, must be in sync with _FunctionTypeHandle constants in
// pkg/vm/lib/bytecode/object_table.dart.
const int kFlagHasOptionalPositionalParams = kFlagBit0;
@ -1116,6 +1203,10 @@ RawObject* BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
const int kFlagHasNamedArgs = kFlagBit0;
const int kFlagHasTypeArgs = kFlagBit1;
// Script flags, must be in sync with _ScriptHandle constants in
// pkg/vm/lib/bytecode/object_table.dart.
const int kFlagHasSourceFile = kFlagBit0;
const intptr_t kind = (header >> kKindShift) & kKindMask;
const intptr_t flags = header & kFlagsMask;
@ -1124,7 +1215,14 @@ RawObject* BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
UNREACHABLE();
break;
case kLibrary: {
const String& uri = String::Handle(Z, ReadString());
String& uri = String::Handle(Z);
static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 10,
"Cleanup condition");
if (bytecode_component_->GetVersion() < 10) {
uri = ReadString();
} else {
uri ^= ReadObject();
}
RawLibrary* library = Library::LookupLibrary(thread_, uri);
if (library == Library::null()) {
FATAL1("Unable to find library %s", uri.ToCString());
@ -1135,9 +1233,15 @@ RawObject* BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
const Library& library = Library::CheckedHandle(Z, ReadObject());
const String& class_name = String::CheckedHandle(Z, ReadObject());
if (class_name.raw() == Symbols::Empty().raw()) {
return library.toplevel_class();
NoSafepointScope no_safepoint_scope(thread_);
RawClass* cls = library.toplevel_class();
if (cls == Class::null()) {
FATAL1("Unable to find toplevel class %s", library.ToCString());
}
return cls;
}
RawClass* cls = library.LookupClassAllowPrivate(class_name);
NoSafepointScope no_safepoint_scope(thread_);
if (cls == Class::null()) {
FATAL2("Unable to find class %s in %s", class_name.ToCString(),
library.ToCString());
@ -1149,6 +1253,7 @@ RawObject* BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
String& name = String::CheckedHandle(Z, ReadObject());
if ((flags & kFlagIsField) != 0) {
RawField* field = cls.LookupFieldAllowPrivate(name);
NoSafepointScope no_safepoint_scope(thread_);
if (field == Field::null()) {
FATAL2("Unable to find field %s in %s", name.ToCString(),
cls.ToCString());
@ -1164,6 +1269,10 @@ RawObject* BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
return scoped_function_.raw();
}
RawFunction* function = cls.LookupFunctionAllowPrivate(name);
{
// To verify that it's OK to hold raw function pointer at this point.
NoSafepointScope no_safepoint_scope(thread_);
}
if (function == Function::null()) {
// When requesting a getter, also return method extractors.
if (Field::IsGetterName(name)) {
@ -1189,6 +1298,8 @@ RawObject* BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
return closures_->At(closure_index);
}
case kSimpleType: {
static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 10,
"Cleanup");
const Class& cls = Class::CheckedHandle(Z, ReadObject());
if ((flags & kFlagIsDynamic) != 0) {
ASSERT(cls.IsNull());
@ -1201,6 +1312,8 @@ RawObject* BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
return cls.DeclarationType();
}
case kTypeParameter: {
static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 10,
"Cleanup");
Object& parent = Object::Handle(Z, ReadObject());
const intptr_t index_in_parent = reader_.ReadUInt();
TypeArguments& type_parameters = TypeArguments::Handle(Z);
@ -1228,14 +1341,18 @@ RawObject* BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
return ClassFinalizer::FinalizeType(*active_class_->klass, type);
}
case kGenericType: {
static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 10,
"Cleanup");
const Class& cls = Class::CheckedHandle(Z, ReadObject());
const TypeArguments& type_arguments =
TypeArguments::Handle(Z, ReadTypeArguments(Class::Handle(Z)));
TypeArguments::Handle(Z, ReadTypeArguments());
const Type& type = Type::Handle(
Z, Type::New(cls, type_arguments, TokenPosition::kNoSource));
return ClassFinalizer::FinalizeType(*active_class_->klass, type);
}
case kFunctionType: {
static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 10,
"Cleanup");
Function& signature_function = Function::ZoneHandle(
Z, Function::NewSignatureFunction(*active_class_->klass,
active_class_->enclosing != NULL
@ -1260,9 +1377,11 @@ RawObject* BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
}
}
case kTypeArguments: {
return ReadTypeArguments(Class::Handle(Z));
return ReadTypeArguments();
}
case kFinalizedGenericType: {
static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 10,
"Cleanup");
const Class& cls = Class::CheckedHandle(Z, ReadObject());
const TypeArguments& type_arguments =
TypeArguments::CheckedHandle(Z, ReadObject());
@ -1292,6 +1411,24 @@ RawObject* BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
return ArgumentsDescriptor::New(num_type_args, num_arguments, array);
}
}
case kScript: {
const String& uri = String::CheckedHandle(Z, ReadObject());
Script& script = Script::Handle(Z);
if ((flags & kFlagHasSourceFile) != 0) {
// TODO(alexmarkov): read source and line starts only when needed.
script =
ReadSourceFile(uri, bytecode_component_->GetSourceFilesOffset() +
reader_.ReadUInt());
} else {
script = Script::New(uri, Object::null_string(), RawScript::kKernelTag);
}
script.set_kernel_program_info(H.GetKernelProgramInfo());
return script.raw();
}
case kType: {
const intptr_t tag = flags / kFlagBit0;
return ReadType(tag);
}
default:
UNREACHABLE();
}
@ -1409,6 +1546,140 @@ RawObject* BytecodeReaderHelper::ReadConstObject(intptr_t tag) {
return Object::null();
}
RawObject* BytecodeReaderHelper::ReadType(intptr_t tag) {
// Must be in sync with enum TypeTag in
// pkg/vm/lib/bytecode/object_table.dart.
enum TypeTag {
kInvalid,
kDynamic,
kVoid,
kSimpleType,
kTypeParameter,
kGenericType,
kRecursiveGenericType,
kRecursiveTypeRef,
kFunctionType,
};
// FunctionType flags, must be in sync with _FunctionTypeHandle constants in
// pkg/vm/lib/bytecode/object_table.dart.
const int kFlagHasOptionalPositionalParams = 1 << 0;
const int kFlagHasOptionalNamedParams = 1 << 1;
const int kFlagHasTypeParams = 1 << 2;
switch (tag) {
case kInvalid:
UNREACHABLE();
break;
case kDynamic:
return AbstractType::dynamic_type().raw();
case kVoid:
return AbstractType::void_type().raw();
case kSimpleType: {
const Class& cls = Class::CheckedHandle(Z, ReadObject());
if (!cls.is_declaration_loaded()) {
ASSERT(cls.is_declared_in_bytecode());
BytecodeReader::LoadClassDeclaration(cls);
}
return cls.DeclarationType();
}
case kTypeParameter: {
Object& parent = Object::Handle(Z, ReadObject());
const intptr_t index_in_parent = reader_.ReadUInt();
TypeArguments& type_parameters = TypeArguments::Handle(Z);
if (parent.IsClass()) {
type_parameters = Class::Cast(parent).type_parameters();
} else if (parent.IsFunction()) {
if (Function::Cast(parent).IsFactory()) {
// For factory constructors VM uses type parameters of a class
// instead of constructor's type parameters.
parent = Function::Cast(parent).Owner();
type_parameters = Class::Cast(parent).type_parameters();
} else {
type_parameters = Function::Cast(parent).type_parameters();
}
} else if (parent.IsNull()) {
ASSERT(function_type_type_parameters_ != nullptr);
type_parameters = function_type_type_parameters_->raw();
} else {
UNREACHABLE();
}
AbstractType& type =
AbstractType::Handle(Z, type_parameters.TypeAt(index_in_parent));
// TODO(alexmarkov): skip type finalization
return ClassFinalizer::FinalizeType(*active_class_->klass, type);
}
case kGenericType: {
const Class& cls = Class::CheckedHandle(Z, ReadObject());
if (!cls.is_declaration_loaded()) {
ASSERT(cls.is_declared_in_bytecode());
BytecodeReader::LoadClassDeclaration(cls);
}
const TypeArguments& type_arguments =
TypeArguments::CheckedHandle(Z, ReadObject());
const Type& type = Type::Handle(
Z, Type::New(cls, type_arguments, TokenPosition::kNoSource));
type.SetIsFinalized();
return type.Canonicalize();
}
case kRecursiveGenericType: {
const intptr_t id = reader_.ReadUInt();
const Class& cls = Class::CheckedHandle(Z, ReadObject());
if (!cls.is_declaration_loaded()) {
ASSERT(cls.is_declared_in_bytecode());
BytecodeReader::LoadClassDeclaration(cls);
}
const auto saved_pending_recursive_types = pending_recursive_types_;
if (id == 0) {
pending_recursive_types_ = &GrowableObjectArray::Handle(
Z, GrowableObjectArray::New(Heap::kOld));
}
ASSERT(id == pending_recursive_types_->Length());
const auto& type_ref =
TypeRef::Handle(Z, TypeRef::New(AbstractType::null_abstract_type()));
pending_recursive_types_->Add(type_ref);
const TypeArguments& type_arguments =
TypeArguments::CheckedHandle(Z, ReadObject());
ASSERT(id == pending_recursive_types_->Length() - 1);
ASSERT(pending_recursive_types_->At(id) == type_ref.raw());
pending_recursive_types_->SetLength(id);
pending_recursive_types_ = saved_pending_recursive_types;
Type& type = Type::Handle(
Z, Type::New(cls, type_arguments, TokenPosition::kNoSource));
type_ref.set_type(type);
type.SetIsFinalized();
return type.Canonicalize();
}
case kRecursiveTypeRef: {
const intptr_t id = reader_.ReadUInt();
ASSERT(pending_recursive_types_ != nullptr);
ASSERT(pending_recursive_types_->Length() >= id);
return pending_recursive_types_->At(id);
}
case kFunctionType: {
const intptr_t flags = reader_.ReadUInt();
Function& signature_function = Function::ZoneHandle(
Z, Function::NewSignatureFunction(*active_class_->klass,
active_class_->enclosing != NULL
? *active_class_->enclosing
: Function::null_function(),
TokenPosition::kNoSource));
// TODO(alexmarkov): skip type finalization
return ReadFunctionSignature(
signature_function, (flags & kFlagHasOptionalPositionalParams) != 0,
(flags & kFlagHasOptionalNamedParams) != 0,
(flags & kFlagHasTypeParams) != 0,
/* has_positional_param_names = */ false);
}
default:
UNREACHABLE();
}
return Object::null();
}
RawString* BytecodeReaderHelper::ReadString(bool is_canonical) {
const int kFlagTwoByteString = 1;
const int kHeaderFields = 2;
@ -1459,8 +1730,42 @@ RawString* BytecodeReaderHelper::ReadString(bool is_canonical) {
}
}
RawTypeArguments* BytecodeReaderHelper::ReadTypeArguments(
const Class& instantiator) {
RawScript* BytecodeReaderHelper::ReadSourceFile(const String& uri,
intptr_t offset) {
// SourceFile flags, must be in sync with SourceFile constants in
// pkg/vm/lib/bytecode/declarations.dart.
const int kHasLineStartsFlag = 1 << 0;
const int kHasSourceFlag = 1 << 1;
AlternativeReadingScope alt(&reader_, offset);
const intptr_t flags = reader_.ReadUInt();
const String& import_uri = String::CheckedHandle(Z, ReadObject());
TypedData& line_starts = TypedData::Handle(Z);
if ((flags & kHasLineStartsFlag) != 0) {
// TODO(alexmarkov): read line starts only when needed.
const intptr_t line_starts_offset =
bytecode_component_->GetLineStartsOffset() + reader_.ReadUInt();
AlternativeReadingScope alt(&reader_, line_starts_offset);
const intptr_t num_line_starts = reader_.ReadUInt();
line_starts = reader_.ReadLineStartsData(num_line_starts);
}
String& source = String::Handle(Z);
if ((flags & kHasSourceFlag) != 0) {
source = ReadString(/* is_canonical = */ false);
}
const Script& script = Script::Handle(
Z, Script::New(import_uri, uri, source, RawScript::kKernelTag));
script.set_line_starts(line_starts);
return script.raw();
}
RawTypeArguments* BytecodeReaderHelper::ReadTypeArguments() {
const intptr_t length = reader_.ReadUInt();
TypeArguments& type_arguments =
TypeArguments::ZoneHandle(Z, TypeArguments::New(length));
@ -1469,36 +1774,14 @@ RawTypeArguments* BytecodeReaderHelper::ReadTypeArguments(
type ^= ReadObject();
type_arguments.SetTypeAt(i, type);
}
type_arguments = type_arguments.Canonicalize();
if (instantiator.IsNull()) {
return type_arguments.raw();
}
if (type_arguments.IsNull() && instantiator.NumTypeArguments() == length) {
return type_arguments.raw();
}
// We make a temporary [Type] object and use `ClassFinalizer::FinalizeType` to
// finalize the argument types.
// (This can for example make the [type_arguments] vector larger)
type = Type::New(instantiator, type_arguments, TokenPosition::kNoSource);
type = ClassFinalizer::FinalizeType(*active_class_->klass, type);
return type.arguments();
return type_arguments.Canonicalize();
}
void BytecodeReaderHelper::ReadMembers(const Class& cls,
intptr_t members_offset,
bool discard_fields) {
void BytecodeReaderHelper::ReadMembers(const Class& cls, bool discard_fields) {
ASSERT(Thread::Current()->IsMutatorThread());
ASSERT(cls.is_type_finalized());
ASSERT(!cls.is_loaded());
const intptr_t offset =
bytecode_component_->GetMembersOffset() + members_offset;
AlternativeReadingScope alt_md(&reader_, offset);
const intptr_t num_functions = reader_.ReadUInt();
functions_ = &Array::Handle(Z, Array::New(num_functions, Heap::kOld));
function_index_ = 0;
@ -1917,6 +2200,263 @@ void BytecodeReaderHelper::ReadFunctionDeclarations(const Class& cls) {
functions_ = nullptr;
}
void BytecodeReaderHelper::ReadClassDeclaration(const Class& cls) {
// Class flags, must be in sync with ClassDeclaration constants in
// pkg/vm/lib/bytecode/declarations.dart.
const int kIsAbstractFlag = 1 << 0;
const int kIsEnumFlag = 1 << 1;
const int kHasTypeParamsFlag = 1 << 2;
const int kHasTypeArgumentsFlag = 1 << 3;
const int kIsTransformedMixinApplicationFlag = 1 << 4;
const int kHasSourcePositionsFlag = 1 << 5;
const int kHasAnnotationsFlag = 1 << 6;
const int kHasPragmaFlag = 1 << 7;
// Class is allocated when reading library declaration in
// BytecodeReaderHelper::ReadLibraryDeclaration.
// Its cid is set in Class::New / Isolate::RegisterClass /
// ClassTable::Register, unless it was loaded for expression evaluation.
ASSERT(cls.is_declared_in_bytecode());
ASSERT(!cls.is_declaration_loaded());
const intptr_t flags = reader_.ReadUInt();
const bool has_pragma = (flags & kHasPragmaFlag) != 0;
// Set early to enable access to type_parameters().
cls.set_is_declaration_loaded();
const auto& script = Script::CheckedHandle(Z, ReadObject());
cls.set_script(script);
TokenPosition position = TokenPosition::kNoSource;
if ((flags & kHasSourcePositionsFlag) != 0) {
position = reader_.ReadPosition();
reader_.ReadPosition(); // end_position
cls.set_token_pos(position);
}
cls.set_has_pragma(has_pragma);
if ((flags & kIsAbstractFlag) != 0) {
cls.set_is_abstract();
}
if ((flags & kIsEnumFlag) != 0) {
cls.set_is_enum_class();
}
if ((flags & kIsTransformedMixinApplicationFlag) != 0) {
cls.set_is_transformed_mixin_application();
}
intptr_t num_type_arguments = 0;
if ((flags & kHasTypeArgumentsFlag) != 0) {
num_type_arguments = reader_.ReadUInt();
}
cls.set_num_type_arguments(num_type_arguments);
if ((flags & kHasTypeParamsFlag) != 0) {
ReadTypeParametersDeclaration(cls, Function::null_function());
}
auto& type = AbstractType::CheckedHandle(Z, ReadObject());
cls.set_super_type(type);
const intptr_t num_interfaces = reader_.ReadUInt();
if (num_interfaces > 0) {
const auto& interfaces =
Array::Handle(Z, Array::New(num_interfaces, Heap::kOld));
for (intptr_t i = 0; i < num_interfaces; ++i) {
type ^= ReadObject();
interfaces.SetAt(i, type);
}
cls.set_interfaces(interfaces);
}
if ((flags & kHasAnnotationsFlag) != 0) {
intptr_t annotations_offset =
reader_.ReadUInt() + bytecode_component_->GetAnnotationsOffset();
ASSERT(annotations_offset > 0);
if (FLAG_enable_mirrors || has_pragma) {
const auto& library = Library::Handle(Z, cls.library());
if (cls.IsTopLevel()) {
ASSERT(!has_pragma);
library.AddLibraryMetadata(cls, TokenPosition::kNoSource, 0,
annotations_offset);
} else {
const auto& top_level_class =
Class::Handle(Z, library.toplevel_class());
library.AddClassMetadata(cls, top_level_class, TokenPosition::kNoSource,
0, annotations_offset);
if (has_pragma) {
// TODO(alexmarkov): read annotations right away using
// annotations_offset.
NoOOBMessageScope no_msg_scope(thread_);
NoReloadScope no_reload_scope(thread_->isolate(), thread_);
library.GetMetadata(cls);
}
}
}
}
const intptr_t members_offset = reader_.ReadUInt();
cls.set_bytecode_offset(members_offset +
bytecode_component_->GetMembersOffset());
// All types are finalized if loading from bytecode.
cls.set_is_type_finalized();
// TODO(alexmarkov): move this to class finalization.
ClassFinalizer::RegisterClassInHierarchy(Z, cls);
}
void BytecodeReaderHelper::ReadLibraryDeclaration(const Library& library,
bool lookup_classes) {
// Library flags, must be in sync with LibraryDeclaration constants in
// pkg/vm/lib/bytecode/declarations.dart.
const int kUsesDartMirrorsFlag = 1 << 0;
const int kUsesDartFfiFlag = 1 << 1;
ASSERT(library.is_declared_in_bytecode());
ASSERT(!library.Loaded());
ASSERT(library.toplevel_class() == Object::null());
// TODO(alexmarkov): fill in library.owned_scripts.
//
// TODO(alexmarkov): figure out if we need to finish class loading immediately
// in case of 'loading_native_wrappers_library_ ' or '!register_class'.
//
// TODO(alexmarkov): support native extension libraries.
//
const intptr_t flags = reader_.ReadUInt();
if (((flags & kUsesDartMirrorsFlag) != 0) && !FLAG_enable_mirrors) {
H.ReportError("import of dart:mirrors with --enable-mirrors=false");
}
if (((flags & kUsesDartFfiFlag) != 0) && !Api::IsFfiEnabled()) {
H.ReportError("import of dart:ffi with --enable-ffi=false");
}
auto& name = String::CheckedHandle(Z, ReadObject());
library.SetName(name);
const auto& script = Script::CheckedHandle(Z, ReadObject());
// The bootstrapper will take care of creating the native wrapper classes,
// but we will add the synthetic constructors to them here.
if (name.raw() ==
Symbols::Symbol(Symbols::kDartNativeWrappersLibNameId).raw()) {
ASSERT(library.LoadInProgress());
loading_native_wrappers_library_ = true;
} else {
loading_native_wrappers_library_ = false;
library.SetLoadInProgress();
}
const bool register_class = !IsExpressionEvaluationLibrary(library);
const intptr_t num_classes = reader_.ReadUInt();
ASSERT(num_classes > 0);
auto& cls = Class::Handle(Z);
for (intptr_t i = 0; i < num_classes; ++i) {
name ^= ReadObject();
const intptr_t class_offset =
bytecode_component_->GetClassesOffset() + reader_.ReadUInt();
if (i == 0) {
ASSERT(name.raw() == Symbols::Empty().raw());
cls = Class::New(library, Symbols::TopLevel(), script,
TokenPosition::kNoSource, register_class);
if (register_class) {
library.set_toplevel_class(cls);
}
} else {
if (lookup_classes) {
cls = library.LookupClassAllowPrivate(name);
}
if (lookup_classes && !cls.IsNull()) {
ASSERT(!cls.is_declaration_loaded());
cls.set_script(script);
} else {
cls = Class::New(library, name, script, TokenPosition::kNoSource,
register_class);
if (register_class) {
library.AddClass(cls);
}
}
}
cls.set_is_declared_in_bytecode(true);
cls.set_bytecode_offset(class_offset);
}
ASSERT(!library.Loaded());
library.SetLoaded();
loading_native_wrappers_library_ = false;
}
void BytecodeReaderHelper::ReadLibraryDeclarations(intptr_t num_libraries) {
auto& library = Library::Handle(Z);
auto& uri = String::Handle(Z);
for (intptr_t i = 0; i < num_libraries; ++i) {
uri ^= ReadObject();
const intptr_t library_offset =
bytecode_component_->GetLibrariesOffset() + reader_.ReadUInt();
if (!FLAG_precompiled_mode && !I->should_load_vmservice()) {
if (uri.raw() == Symbols::DartVMServiceIO().raw()) {
continue;
}
}
bool lookup_classes = true;
library = Library::LookupLibrary(thread_, uri);
if (library.IsNull()) {
lookup_classes = false;
library = Library::New(uri);
if (uri.raw() == Symbols::EvalSourceUri().raw()) {
ASSERT(expression_evaluation_library_ == nullptr);
expression_evaluation_library_ = &Library::Handle(Z, library.raw());
} else {
library.Register(thread_);
}
}
if (library.Loaded()) {
continue;
}
library.set_is_declared_in_bytecode(true);
library.set_bytecode_offset(library_offset);
AlternativeReadingScope alt(&reader_, library_offset);
ReadLibraryDeclaration(library, lookup_classes);
}
}
void BytecodeReaderHelper::FindAndReadSpecificLibrary(const Library& library,
intptr_t num_libraries) {
auto& uri = String::Handle(Z);
for (intptr_t i = 0; i < num_libraries; ++i) {
uri ^= ReadObject();
const intptr_t library_offset =
bytecode_component_->GetLibrariesOffset() + reader_.ReadUInt();
if (uri.raw() == library.url()) {
library.set_is_declared_in_bytecode(true);
library.set_bytecode_offset(library_offset);
AlternativeReadingScope alt(&reader_, library_offset);
ReadLibraryDeclaration(library, /* lookup_classes = */ true);
return;
}
}
}
void BytecodeReaderHelper::ReadParameterCovariance(
const Function& function,
BitVector* is_covariant,
@ -2153,6 +2693,22 @@ intptr_t BytecodeComponentData::GetMainOffset() const {
return Smi::Value(Smi::RawCast(data_.At(kMainOffset)));
}
intptr_t BytecodeComponentData::GetNumLibraries() const {
return Smi::Value(Smi::RawCast(data_.At(kNumLibraries)));
}
intptr_t BytecodeComponentData::GetLibraryIndexOffset() const {
return Smi::Value(Smi::RawCast(data_.At(kLibraryIndexOffset)));
}
intptr_t BytecodeComponentData::GetLibrariesOffset() const {
return Smi::Value(Smi::RawCast(data_.At(kLibrariesOffset)));
}
intptr_t BytecodeComponentData::GetClassesOffset() const {
return Smi::Value(Smi::RawCast(data_.At(kClassesOffset)));
}
intptr_t BytecodeComponentData::GetMembersOffset() const {
return Smi::Value(Smi::RawCast(data_.At(kMembersOffset)));
}
@ -2165,6 +2721,14 @@ intptr_t BytecodeComponentData::GetSourcePositionsOffset() const {
return Smi::Value(Smi::RawCast(data_.At(kSourcePositionsOffset)));
}
intptr_t BytecodeComponentData::GetSourceFilesOffset() const {
return Smi::Value(Smi::RawCast(data_.At(kSourceFilesOffset)));
}
intptr_t BytecodeComponentData::GetLineStartsOffset() const {
return Smi::Value(Smi::RawCast(data_.At(kLineStartsOffset)));
}
intptr_t BytecodeComponentData::GetLocalVariablesOffset() const {
return Smi::Value(Smi::RawCast(data_.At(kLocalVariablesOffset)));
}
@ -2188,9 +2752,15 @@ RawArray* BytecodeComponentData::New(Zone* zone,
intptr_t strings_contents_offset,
intptr_t objects_contents_offset,
intptr_t main_offset,
intptr_t num_libraries,
intptr_t library_index_offset,
intptr_t libraries_offset,
intptr_t classes_offset,
intptr_t members_offset,
intptr_t codes_offset,
intptr_t source_positions_offset,
intptr_t source_files_offset,
intptr_t line_starts_offset,
intptr_t local_variables_offset,
intptr_t annotations_offset,
Heap::Space space) {
@ -2213,6 +2783,18 @@ RawArray* BytecodeComponentData::New(Zone* zone,
smi_handle = Smi::New(main_offset);
data.SetAt(kMainOffset, smi_handle);
smi_handle = Smi::New(num_libraries);
data.SetAt(kNumLibraries, smi_handle);
smi_handle = Smi::New(library_index_offset);
data.SetAt(kLibraryIndexOffset, smi_handle);
smi_handle = Smi::New(libraries_offset);
data.SetAt(kLibrariesOffset, smi_handle);
smi_handle = Smi::New(classes_offset);
data.SetAt(kClassesOffset, smi_handle);
smi_handle = Smi::New(members_offset);
data.SetAt(kMembersOffset, smi_handle);
@ -2222,6 +2804,12 @@ RawArray* BytecodeComponentData::New(Zone* zone,
smi_handle = Smi::New(source_positions_offset);
data.SetAt(kSourcePositionsOffset, smi_handle);
smi_handle = Smi::New(source_files_offset);
data.SetAt(kSourceFilesOffset, smi_handle);
smi_handle = Smi::New(line_starts_offset);
data.SetAt(kLineStartsOffset, smi_handle);
smi_handle = Smi::New(local_variables_offset);
data.SetAt(kLocalVariablesOffset, smi_handle);
@ -2303,7 +2891,7 @@ RawError* BytecodeReader::ReadFunctionBytecode(Thread* thread,
ActiveClass active_class;
BytecodeComponentData bytecode_component(
Array::Handle(zone, translation_helper.GetBytecodeComponent()));
&Array::Handle(zone, translation_helper.GetBytecodeComponent()));
ASSERT(!bytecode_component.IsNull());
BytecodeReaderHelper bytecode_reader(
&translation_helper, &active_class, &bytecode_component);
@ -2343,7 +2931,7 @@ RawError* BytecodeReader::ReadFunctionBytecode(Thread* thread,
zone);
BytecodeComponentData bytecode_component(
Array::Handle(zone, translation_helper.GetBytecodeComponent()));
&Array::Handle(zone, translation_helper.GetBytecodeComponent()));
ASSERT(!bytecode_component.IsNull());
BytecodeReaderHelper bytecode_reader(&translation_helper, &active_class,
&bytecode_component);
@ -2371,7 +2959,7 @@ RawObject* BytecodeReader::ReadAnnotation(const Field& annotation_field) {
ActiveClass active_class;
BytecodeComponentData bytecode_component(
Array::Handle(zone, translation_helper.GetBytecodeComponent()));
&Array::Handle(zone, translation_helper.GetBytecodeComponent()));
ASSERT(!bytecode_component.IsNull());
BytecodeReaderHelper bytecode_reader(&translation_helper, &active_class,
&bytecode_component);
@ -2382,6 +2970,65 @@ RawObject* BytecodeReader::ReadAnnotation(const Field& annotation_field) {
return bytecode_reader.ReadObject();
}
void BytecodeReader::LoadClassDeclaration(const Class& cls) {
TIMELINE_DURATION(Thread::Current(), Compiler,
"BytecodeReader::LoadClassDeclaration");
ASSERT(cls.is_declared_in_bytecode());
ASSERT(!cls.is_declaration_loaded());
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
ASSERT(thread->IsMutatorThread());
const Script& script = Script::Handle(zone, cls.script());
TranslationHelper translation_helper(thread);
translation_helper.InitFromScript(script);
ActiveClass active_class;
ActiveClassScope active_class_scope(&active_class, &cls);
BytecodeComponentData bytecode_component(
&Array::Handle(zone, translation_helper.GetBytecodeComponent()));
ASSERT(!bytecode_component.IsNull());
BytecodeReaderHelper bytecode_reader(&translation_helper, &active_class,
&bytecode_component);
AlternativeReadingScope alt(&bytecode_reader.reader(), cls.bytecode_offset());
bytecode_reader.ReadClassDeclaration(cls);
}
void BytecodeReader::FinishClassLoading(const Class& cls) {
ASSERT(cls.is_declared_in_bytecode());
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
ASSERT(thread->IsMutatorThread());
const Script& script = Script::Handle(zone, cls.script());
TranslationHelper translation_helper(thread);
translation_helper.InitFromScript(script);
ActiveClass active_class;
ActiveClassScope active_class_scope(&active_class, &cls);
BytecodeComponentData bytecode_component(
&Array::Handle(zone, translation_helper.GetBytecodeComponent()));
ASSERT(!bytecode_component.IsNull());
BytecodeReaderHelper bytecode_reader(&translation_helper, &active_class,
&bytecode_component);
AlternativeReadingScope alt(&bytecode_reader.reader(), cls.bytecode_offset());
// If this is a dart:internal.ClassID class ignore field declarations
// contained in the Kernel file and instead inject our own const
// fields.
const bool discard_fields = cls.InjectCIDFields();
bytecode_reader.ReadMembers(cls, discard_fields);
}
#if !defined(PRODUCT)
RawLocalVarDescriptors* BytecodeReader::ComputeLocalVarDescriptors(
Zone* zone,

View file

@ -25,13 +25,18 @@ class BytecodeMetadataHelper : public MetadataHelper {
ActiveClass* active_class);
void ParseBytecodeFunction(ParsedFunction* parsed_function);
void ParseBytecodeImplicitClosureFunction(ParsedFunction* parsed_function);
// Reads members associated with given [node_offset] and fills in [cls].
// Discards fields if [discard_fields] is true.
// Returns true if class members are loaded.
bool ReadMembers(intptr_t node_offset, const Class& cls, bool discard_fields);
// Read all library declarations.
bool ReadLibraries();
// Read specific library declaration.
void ReadLibrary(const Library& library);
RawLibrary* GetMainLibrary();
RawArray* GetBytecodeComponent();
@ -56,12 +61,15 @@ class BytecodeReaderHelper : public ValueObject {
RawArray* CreateForwarderChecks(const Function& function);
void ReadMembers(const Class& cls,
intptr_t members_offset,
bool discard_fields);
void ReadMembers(const Class& cls, bool discard_fields);
void ReadFieldDeclarations(const Class& cls, bool discard_fields);
void ReadFunctionDeclarations(const Class& cls);
void ReadClassDeclaration(const Class& cls);
void ReadLibraryDeclaration(const Library& library, bool lookup_classes);
void ReadLibraryDeclarations(intptr_t num_libraries);
void FindAndReadSpecificLibrary(const Library& library,
intptr_t num_libraries);
void ParseBytecodeFunction(ParsedFunction* parsed_function,
const Function& function);
@ -186,13 +194,20 @@ class BytecodeReaderHelper : public ValueObject {
RawObject* ReadObjectContents(uint32_t header);
RawObject* ReadConstObject(intptr_t tag);
RawObject* ReadType(intptr_t tag);
RawString* ReadString(bool is_canonical = true);
RawTypeArguments* ReadTypeArguments(const Class& instantiator);
RawScript* ReadSourceFile(const String& uri, intptr_t offset);
RawTypeArguments* ReadTypeArguments();
RawPatchClass* GetPatchClass(const Class& cls, const Script& script);
void ParseForwarderFunction(ParsedFunction* parsed_function,
const Function& function,
const Function& target);
bool IsExpressionEvaluationLibrary(const Library& library) const {
return expression_evaluation_library_ != nullptr &&
expression_evaluation_library_->raw() == library.raw();
}
Reader reader_;
TranslationHelper& translation_helper_;
ActiveClass* const active_class_;
@ -201,12 +216,15 @@ class BytecodeReaderHelper : public ValueObject {
BytecodeComponentData* const bytecode_component_;
Array* closures_ = nullptr;
const TypeArguments* function_type_type_parameters_ = nullptr;
GrowableObjectArray* pending_recursive_types_ = nullptr;
PatchClass* patch_class_ = nullptr;
Array* functions_ = nullptr;
intptr_t function_index_ = 0;
Function& scoped_function_;
String& scoped_function_name_;
Class& scoped_function_class_;
Library* expression_evaluation_library_ = nullptr;
bool loading_native_wrappers_library_ = false;
DISALLOW_COPY_AND_ASSIGN(BytecodeReaderHelper);
};
@ -219,24 +237,38 @@ class BytecodeComponentData : ValueObject {
kStringsContentsOffset,
kObjectsContentsOffset,
kMainOffset,
kNumLibraries,
kLibraryIndexOffset,
kLibrariesOffset,
kClassesOffset,
kMembersOffset,
kCodesOffset,
kSourcePositionsOffset,
kSourceFilesOffset,
kLineStartsOffset,
kLocalVariablesOffset,
kAnnotationsOffset,
kNumFields
};
explicit BytecodeComponentData(const Array& data) : data_(data) {}
explicit BytecodeComponentData(Array* data) : data_(*data) {}
void Init(const Array& data) { data_ = data.raw(); }
intptr_t GetVersion() const;
intptr_t GetStringsHeaderOffset() const;
intptr_t GetStringsContentsOffset() const;
intptr_t GetObjectsContentsOffset() const;
intptr_t GetMainOffset() const;
intptr_t GetNumLibraries() const;
intptr_t GetLibraryIndexOffset() const;
intptr_t GetLibrariesOffset() const;
intptr_t GetClassesOffset() const;
intptr_t GetMembersOffset() const;
intptr_t GetCodesOffset() const;
intptr_t GetSourcePositionsOffset() const;
intptr_t GetSourceFilesOffset() const;
intptr_t GetLineStartsOffset() const;
intptr_t GetLocalVariablesOffset() const;
intptr_t GetAnnotationsOffset() const;
void SetObject(intptr_t index, const Object& obj) const;
@ -251,15 +283,21 @@ class BytecodeComponentData : ValueObject {
intptr_t strings_contents_offset,
intptr_t objects_contents_offset,
intptr_t main_offset,
intptr_t num_libraries,
intptr_t library_index_offset,
intptr_t libraries_offset,
intptr_t classes_offset,
intptr_t members_offset,
intptr_t codes_offset,
intptr_t source_positions_offset,
intptr_t source_files_offset,
intptr_t line_starts_offset,
intptr_t local_variables_offset,
intptr_t annotations_offset,
Heap::Space space);
private:
const Array& data_;
Array& data_;
};
class BytecodeReader : public AllStatic {
@ -272,6 +310,15 @@ class BytecodeReader : public AllStatic {
// Read annotation for the given annotation field.
static RawObject* ReadAnnotation(const Field& annotation_field);
// Read declaration of the given library.
static void LoadLibraryDeclaration(const Library& library);
// Read declaration of the given class.
static void LoadClassDeclaration(const Class& cls);
// Read members of the given class.
static void FinishClassLoading(const Class& cls);
#if !defined(PRODUCT)
// Compute local variable descriptors for [function] with [bytecode].
static RawLocalVarDescriptors* ComputeLocalVarDescriptors(

View file

@ -724,9 +724,17 @@ FlowGraph* FlowGraphBuilder::BuildGraph() {
info.potential_natives() == GrowableObjectArray::null());
#endif
auto& kernel_data = ExternalTypedData::Handle(Z);
intptr_t kernel_data_program_offset = 0;
if (!function.is_declared_in_bytecode()) {
kernel_data = function.KernelData();
kernel_data_program_offset = function.KernelDataProgramOffset();
}
// TODO(alexmarkov): refactor this - StreamingFlowGraphBuilder should not be
// used for bytecode functions.
StreamingFlowGraphBuilder streaming_flow_graph_builder(
this, ExternalTypedData::Handle(Z, function.KernelData()),
function.KernelDataProgramOffset());
this, kernel_data, kernel_data_program_offset);
return streaming_flow_graph_builder.BuildGraph();
}

View file

@ -2561,47 +2561,8 @@ RawTypedData* KernelReaderHelper::GetLineStartsFor(intptr_t index) {
SetOffset(GetOffsetForSourceInfo(index));
SkipBytes(ReadUInt()); // skip uri.
SkipBytes(ReadUInt()); // skip source.
const intptr_t line_start_count = ReadUInt(); // read number of line start
// entries.
MallocGrowableArray<int32_t> line_starts_array;
intptr_t max_delta = 0;
for (intptr_t i = 0; i < line_start_count; ++i) {
int32_t delta = ReadUInt();
line_starts_array.Add(delta);
if (delta > max_delta) {
max_delta = delta;
}
}
intptr_t cid;
if (max_delta <= kMaxInt8) {
cid = kTypedDataInt8ArrayCid;
} else if (max_delta <= kMaxInt16) {
cid = kTypedDataInt16ArrayCid;
} else {
cid = kTypedDataInt32ArrayCid;
}
TypedData& line_starts_data =
TypedData::Handle(Z, TypedData::New(cid, line_start_count, Heap::kOld));
for (intptr_t j = 0; j < line_start_count; ++j) {
int32_t line_start = line_starts_array[j];
switch (cid) {
case kTypedDataInt8ArrayCid:
line_starts_data.SetInt8(j, static_cast<int8_t>(line_start));
break;
case kTypedDataInt16ArrayCid:
line_starts_data.SetInt16(j << 1, static_cast<int16_t>(line_start));
break;
case kTypedDataInt32ArrayCid:
line_starts_data.SetInt32(j << 2, line_start);
break;
default:
UNREACHABLE();
}
}
return line_starts_data.raw();
const intptr_t line_start_count = ReadUInt();
return reader_.ReadLineStartsData(line_start_count);
}
String& KernelReaderHelper::SourceTableImportUriFor(intptr_t index,
@ -2787,8 +2748,7 @@ void TypeTranslator::BuildInterfaceType(bool simple) {
} else {
// Note that the type argument vector is not yet extended.
result_ =
Type::New(klass, TypeArguments::Handle(Z, klass.type_parameters()),
klass.token_pos());
Type::New(klass, Object::null_type_arguments(), klass.token_pos());
}
return;
}

View file

@ -62,6 +62,7 @@ class TranslationHelper {
RawGrowableObjectArray* EnsurePotentialPragmaFunctions();
void SetKernelProgramInfo(const KernelProgramInfo& info);
const KernelProgramInfo& GetKernelProgramInfo() const { return info_; }
intptr_t StringOffset(StringIndex index) const;
intptr_t StringSize(StringIndex index) const;

View file

@ -749,7 +749,7 @@ class KernelBytecode {
// Maximum bytecode format version supported by VM.
// The range of supported versions should include version produced by bytecode
// generator (currentBytecodeFormatVersion in pkg/vm/lib/bytecode/dbc.dart).
static const intptr_t kMaxSupportedBytecodeFormatVersion = 9;
static const intptr_t kMaxSupportedBytecodeFormatVersion = 10;
enum Opcode {
#define DECLARE_BYTECODE(name, encoding, kind, op1, op2, op3) k##name,

View file

@ -569,10 +569,6 @@ void Exceptions::JumpToFrame(Thread* thread,
uword stack_pointer,
uword frame_pointer,
bool clear_deopt_at_target) {
uword fp_for_clearing =
(clear_deopt_at_target ? frame_pointer + 1 : frame_pointer);
ClearLazyDeopts(thread, fp_for_clearing);
#if !defined(DART_PRECOMPILED_RUNTIME)
// TODO(regis): We still possibly need to unwind interpreter frames if they
// are callee frames of the C++ frame handling the exception.
@ -585,6 +581,10 @@ void Exceptions::JumpToFrame(Thread* thread,
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
const uword fp_for_clearing =
(clear_deopt_at_target ? frame_pointer + 1 : frame_pointer);
ClearLazyDeopts(thread, fp_for_clearing);
#if defined(USING_SIMULATOR)
// Unwinding of the C++ frames and destroying of their stack resources is done
// by the simulator, because the target stack_pointer is a simulated stack

View file

@ -352,6 +352,16 @@ void CollectTokenPositionsFor(const Script& interesting_script) {
if (klass.script() == interesting_script.raw()) {
token_positions.Add(klass.token_pos().value());
}
// If class is declared in bytecode, its members should be loaded
// (via class finalization) before their token positions could be
// collected.
if (klass.is_declared_in_bytecode() && !klass.is_finalized()) {
const Error& error =
Error::Handle(zone, klass.EnsureIsFinalized(thread));
if (!error.IsNull()) {
Exceptions::PropagateError(error);
}
}
if (klass.is_finalized()) {
temp_array = klass.fields();
for (intptr_t i = 0; i < temp_array.Length(); ++i) {
@ -403,6 +413,7 @@ void CollectTokenPositionsFor(const Script& interesting_script) {
}
} else {
// Class isn't finalized yet: read the data attached to it.
ASSERT(!klass.is_declared_in_bytecode());
ASSERT(klass.kernel_offset() > 0);
data = lib.kernel_data();
ASSERT(!data.IsNull());

View file

@ -29,6 +29,50 @@ const char* Reader::TagName(Tag tag) {
return "Unknown";
}
RawTypedData* Reader::ReadLineStartsData(intptr_t line_start_count) {
TypedData& line_starts_data = TypedData::Handle(
TypedData::New(kTypedDataInt8ArrayCid, line_start_count, Heap::kOld));
const intptr_t start_offset = offset();
intptr_t i = 0;
for (; i < line_start_count; ++i) {
const intptr_t delta = ReadUInt();
if (delta > kMaxInt8) {
break;
}
line_starts_data.SetInt8(i, static_cast<int8_t>(delta));
}
if (i < line_start_count) {
// Slow path: choose representation between Int16 and Int32 typed data.
set_offset(start_offset);
intptr_t max_delta = 0;
for (intptr_t i = 0; i < line_start_count; ++i) {
const intptr_t delta = ReadUInt();
if (delta > max_delta) {
max_delta = delta;
}
}
ASSERT(max_delta > kMaxInt8);
const intptr_t cid = (max_delta <= kMaxInt16) ? kTypedDataInt16ArrayCid
: kTypedDataInt32ArrayCid;
line_starts_data = TypedData::New(cid, line_start_count, Heap::kOld);
set_offset(start_offset);
for (intptr_t i = 0; i < line_start_count; ++i) {
const intptr_t delta = ReadUInt();
if (cid == kTypedDataInt16ArrayCid) {
line_starts_data.SetInt16(i << 1, static_cast<int16_t>(delta));
} else {
line_starts_data.SetInt32(i << 2, delta);
}
}
}
return line_starts_data.raw();
}
const char* kKernelInvalidFilesize =
"File size is too small to be a valid kernel file";
const char* kKernelInvalidMagicIdentifier = "Invalid magic identifier";

View file

@ -366,6 +366,8 @@ class Reader : public ValueObject {
return &buffer()[offset];
}
RawTypedData* ReadLineStartsData(intptr_t line_start_count);
private:
const uint8_t* buffer() const {
if (raw_buffer_ != NULL) {

View file

@ -659,6 +659,7 @@ void KernelLoader::LoadNativeExtensionLibraries(
for (intptr_t i = 0; i < length; ++i) {
library ^= potential_extension_libraries_.At(i);
ASSERT(!library.is_declared_in_bytecode());
helper_.SetOffset(library.kernel_offset());
LibraryHelper library_helper(&helper_);
@ -729,11 +730,17 @@ RawObject* KernelLoader::LoadProgram(bool process_pending_classes) {
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
// Note that `problemsAsJson` on Component is implicitly skipped.
const intptr_t length = program_->library_count();
Object& last_library = Library::Handle(Z);
for (intptr_t i = 0; i < length; i++) {
last_library = LoadLibrary(i);
bool libraries_loaded = false;
if (FLAG_enable_interpreter || FLAG_use_bytecode_compiler) {
libraries_loaded = bytecode_metadata_helper_.ReadLibraries();
}
if (!libraries_loaded) {
// Note that `problemsAsJson` on Component is implicitly skipped.
const intptr_t length = program_->library_count();
for (intptr_t i = 0; i < length; i++) {
LoadLibrary(i);
}
}
if (process_pending_classes) {
@ -797,6 +804,26 @@ RawObject* KernelLoader::LoadProgram(bool process_pending_classes) {
return Thread::Current()->StealStickyError();
}
void KernelLoader::LoadLibrary(const Library& library) {
ASSERT(!library.Loaded());
if (FLAG_enable_interpreter || FLAG_use_bytecode_compiler) {
bytecode_metadata_helper_.ReadLibrary(library);
if (library.Loaded()) {
return;
}
}
const auto& uri = String::Handle(Z, library.url());
const intptr_t num_libraries = program_->library_count();
for (intptr_t i = 0; i < num_libraries; ++i) {
const String& library_uri = LibraryUri(i);
if (library_uri.Equals(uri)) {
LoadLibrary(i);
return;
}
}
}
RawObject* KernelLoader::LoadExpressionEvaluationFunction(
const String& library_url,
const String& klass) {
@ -1067,12 +1094,12 @@ RawLibrary* KernelLoader::LoadLibrary(intptr_t index) {
LoadLibraryImportsAndExports(&library, toplevel_class);
library_helper.SetJustRead(LibraryHelper::kDependencies);
const GrowableObjectArray& classes =
GrowableObjectArray::Handle(Z, I->object_store()->pending_classes());
// Everything up til the classes are skipped implicitly, and library_helper
// is no longer used.
const GrowableObjectArray& classes =
GrowableObjectArray::Handle(Z, I->object_store()->pending_classes());
// Load all classes.
intptr_t next_class_offset = library_index.ClassOffset(0);
Class& klass = Class::Handle(Z);
@ -1092,12 +1119,10 @@ RawLibrary* KernelLoader::LoadLibrary(intptr_t index) {
if (FLAG_enable_mirrors && annotation_count > 0) {
ASSERT(annotations_kernel_offset > 0);
library.AddLibraryMetadata(toplevel_class, TokenPosition::kNoSource,
annotations_kernel_offset);
annotations_kernel_offset, 0);
}
if (register_class) {
classes.Add(toplevel_class, Heap::kOld);
if (library_index.HasSourceReferences()) {
helper_.SetOffset(library_index.SourceReferencesOffset());
intptr_t count = helper_.ReadUInt();
@ -1129,6 +1154,9 @@ void KernelLoader::FinishTopLevelClassLoading(
ActiveClassScope active_class_scope(&active_class_, &toplevel_class);
if (FLAG_enable_interpreter || FLAG_use_bytecode_compiler) {
static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 10,
"Cleanup support for old bytecode format versions");
ASSERT(!toplevel_class.is_declared_in_bytecode());
if (bytecode_metadata_helper_.ReadMembers(library_kernel_offset_,
toplevel_class, false)) {
ASSERT(toplevel_class.is_loaded());
@ -1342,6 +1370,10 @@ void KernelLoader::LoadLibraryImportsAndExports(Library* library,
void KernelLoader::LoadPreliminaryClass(ClassHelper* class_helper,
intptr_t type_parameter_count) {
const Class* klass = active_class_.klass;
// Enable access to type_parameters().
klass->set_is_declaration_loaded();
// Note: This assumes that ClassHelper is exactly at the position where
// the length of the type parameters have been read, and that the order in
// the binary is as follows: [...], kTypeParameters, kSuperClass, kMixinType,
@ -1379,8 +1411,6 @@ void KernelLoader::LoadPreliminaryClass(ClassHelper* class_helper,
if (class_helper->is_transformed_mixin_application()) {
klass->set_is_transformed_mixin_application();
}
klass->set_is_declaration_loaded();
}
void KernelLoader::LoadClass(const Library& library,
@ -1443,7 +1473,7 @@ void KernelLoader::LoadClass(const Library& library,
if ((FLAG_enable_mirrors || has_pragma_annotation) && annotation_count > 0) {
library.AddClassMetadata(*out_class, toplevel_class,
TokenPosition::kNoSource,
class_offset - correction_offset_);
class_offset - correction_offset_, 0);
}
// We do not register expression evaluation classes with the VM:
@ -1474,17 +1504,15 @@ void KernelLoader::FinishClassLoading(const Class& klass,
ActiveClassScope active_class_scope(&active_class_, &klass);
bool discard_fields = false;
if (library.raw() == Library::InternalLibrary() &&
klass.Name() == Symbols::ClassID().raw()) {
// If this is a dart:internal.ClassID class ignore field declarations
// contained in the Kernel file and instead inject our own const
// fields.
klass.InjectCIDFields();
discard_fields = true;
}
// If this is a dart:internal.ClassID class ignore field declarations
// contained in the Kernel file and instead inject our own const
// fields.
const bool discard_fields = klass.InjectCIDFields();
if (FLAG_enable_interpreter || FLAG_use_bytecode_compiler) {
static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 10,
"Cleanup support for old bytecode format versions");
ASSERT(!klass.is_declared_in_bytecode());
if (bytecode_metadata_helper_.ReadMembers(
klass.kernel_offset() + library_kernel_offset_, klass,
discard_fields)) {
@ -1681,6 +1709,7 @@ void KernelLoader::FinishClassLoading(const Class& klass,
}
void KernelLoader::FinishLoading(const Class& klass) {
ASSERT(!klass.is_declared_in_bytecode());
ASSERT(klass.IsTopLevel() || (klass.kernel_offset() > 0));
Zone* zone = Thread::Current()->zone();
@ -2257,9 +2286,11 @@ RawFunction* CreateFieldInitializerFunction(Thread* thread,
const PatchClass& initializer_owner =
PatchClass::Handle(zone, PatchClass::New(field_owner, script));
const Library& lib = Library::Handle(zone, field_owner.library());
initializer_owner.set_library_kernel_data(
ExternalTypedData::Handle(zone, lib.kernel_data()));
initializer_owner.set_library_kernel_offset(lib.kernel_offset());
if (!lib.is_declared_in_bytecode()) {
initializer_owner.set_library_kernel_data(
ExternalTypedData::Handle(zone, lib.kernel_data()));
initializer_owner.set_library_kernel_offset(lib.kernel_offset());
}
// Create a static initializer.
const Function& initializer_fun = Function::Handle(

View file

@ -196,6 +196,9 @@ class KernelLoader : public ValueObject {
// was no main procedure, or a failure object if there was an error.
RawObject* LoadProgram(bool process_pending_classes = true);
// Load given library.
void LoadLibrary(const Library& library);
// Returns the function which will evaluate the expression, or a failure
// object if there was an error.
RawObject* LoadExpressionEvaluationFunction(const String& library_url,
@ -219,8 +222,6 @@ class KernelLoader : public ValueObject {
intptr_t kernel_buffer_length,
const String& url);
RawLibrary* LoadLibrary(intptr_t index);
void FinishTopLevelClassLoading(const Class& toplevel_class,
const Library& library,
const LibraryIndex& library_index);
@ -258,6 +259,16 @@ class KernelLoader : public ValueObject {
return translation_helper_.DartSymbolObfuscate(index);
}
private:
KernelLoader(const Script& script,
const ExternalTypedData& kernel_data,
intptr_t data_program_offset);
void InitializeFields(
DirectChainedHashMap<UriToSourceTableTrait>* uri_to_source_table);
RawLibrary* LoadLibrary(intptr_t index);
const String& LibraryUri(intptr_t library_index) {
return translation_helper_.DartSymbolPlain(
translation_helper_.CanonicalNameString(
@ -284,15 +295,6 @@ class KernelLoader : public ValueObject {
uint8_t CharacterAt(StringIndex string_index, intptr_t index);
private:
friend class BuildingTranslationHelper;
KernelLoader(const Script& script,
const ExternalTypedData& kernel_data,
intptr_t data_program_offset);
void InitializeFields(
DirectChainedHashMap<UriToSourceTableTrait>* uri_to_source_table);
static void index_programs(kernel::Reader* reader,
GrowableArray<intptr_t>* subprogram_file_starts);
void walk_incremental_kernel(BitVector* modified_libs,
@ -459,6 +461,8 @@ class KernelLoader : public ValueObject {
GrowableArray<const Function*> functions_;
GrowableArray<const Field*> fields_;
friend class BuildingTranslationHelper;
DISALLOW_COPY_AND_ASSIGN(KernelLoader);
};

View file

@ -1931,7 +1931,8 @@ RawError* Object::Init(Isolate* isolate,
ASSERT(!lib.IsNull());
cls = lib.LookupClassAllowPrivate(Symbols::ClassID());
ASSERT(!cls.IsNull());
cls.InjectCIDFields();
const bool injected = cls.InjectCIDFields();
ASSERT(injected);
isolate->object_store()->InitKnownObjects();
#endif // !defined(DART_PRECOMPILED_RUNTIME)
@ -2311,7 +2312,8 @@ RawClass* Class::New() {
// references, but do not recompute size.
result.set_is_prefinalized();
}
result.set_kernel_offset(-1);
NOT_IN_PRECOMPILED(result.set_is_declared_in_bytecode(false));
NOT_IN_PRECOMPILED(result.set_binary_declaration_offset(0));
result.InitEmptyFields();
Isolate::Current()->RegisterClass(result);
return result.raw();
@ -2593,12 +2595,13 @@ void Class::set_library(const Library& value) const {
void Class::set_type_parameters(const TypeArguments& value) const {
ASSERT((num_type_arguments() == kUnknownNumTypeArguments) ||
is_prefinalized());
is_declared_in_bytecode() || is_prefinalized());
StorePointer(&raw_ptr()->type_parameters_, value.raw());
}
intptr_t Class::NumTypeParameters(Thread* thread) const {
if (type_parameters() == TypeArguments::null()) {
if (!is_declaration_loaded()) {
ASSERT(is_prefinalized());
const intptr_t cid = id();
if ((cid == kArrayCid) || (cid == kImmutableArrayCid) ||
(cid == kGrowableObjectArrayCid)) {
@ -2606,6 +2609,9 @@ intptr_t Class::NumTypeParameters(Thread* thread) const {
}
return 0;
}
if (type_parameters() == TypeArguments::null()) {
return 0;
}
REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread);
TypeArguments& type_params = thread->TypeArgumentsHandle();
type_params = type_parameters();
@ -3596,7 +3602,12 @@ void Class::AddFields(const GrowableArray<const Field*>& new_fields) const {
SetFields(new_arr);
}
void Class::InjectCIDFields() const {
bool Class::InjectCIDFields() const {
if (library() != Library::InternalLibrary() ||
Name() != Symbols::ClassID().raw()) {
return false;
}
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Field& field = Field::Handle(zone);
@ -3631,6 +3642,8 @@ void Class::InjectCIDFields() const {
CLASS_LIST_TYPED_DATA(ADD_SET_FIELD)
#undef ADD_SET_FIELD
#undef CLASS_LIST_WITH_NULL
return true;
}
template <class FakeInstance>
@ -3654,6 +3667,8 @@ RawClass* Class::NewCommon(intptr_t index) {
result.set_num_type_arguments(kUnknownNumTypeArguments);
result.set_num_native_fields(0);
result.set_state_bits(0);
NOT_IN_PRECOMPILED(result.set_is_declared_in_bytecode(false));
NOT_IN_PRECOMPILED(result.set_binary_declaration_offset(0));
result.InitEmptyFields();
return result.raw();
}
@ -3661,7 +3676,6 @@ RawClass* Class::NewCommon(intptr_t index) {
template <class FakeInstance>
RawClass* Class::New(intptr_t index) {
Class& result = Class::Handle(NewCommon<FakeInstance>(index));
result.set_kernel_offset(-1);
Isolate::Current()->RegisterClass(result);
return result.raw();
}
@ -3676,7 +3690,6 @@ RawClass* Class::New(const Library& lib,
result.set_name(name);
result.set_script(script);
result.set_token_pos(token_pos);
result.set_kernel_offset(-1);
if (register_class) {
Isolate::Current()->RegisterClass(result);
}
@ -3707,7 +3720,6 @@ RawClass* Class::NewNativeWrapper(const Library& library,
cls.set_is_declaration_loaded();
cls.set_is_type_finalized();
cls.set_is_synthesized_class();
cls.set_kernel_offset(-1);
library.AddClass(cls);
return cls.raw();
} else {
@ -3978,6 +3990,11 @@ TokenPosition Class::ComputeEndTokenPos() const {
ASSERT(!scr.IsNull());
if (scr.kind() == RawScript::kKernelTag) {
if (is_declared_in_bytecode()) {
// TODO(alexmarkov): keep end_token_pos in Class?
UNIMPLEMENTED();
return token_pos();
}
ASSERT(kernel_offset() > 0);
const Library& lib = Library::Handle(zone, library());
const ExternalTypedData& kernel_data =
@ -7779,6 +7796,10 @@ RawExternalTypedData* Function::KernelData() const {
}
intptr_t Function::KernelDataProgramOffset() const {
ASSERT(!is_declared_in_bytecode());
if (IsNoSuchMethodDispatcher() || IsInvokeFieldDispatcher()) {
return 0;
}
Object& data = Object::Handle(raw_ptr()->data_);
if (data.IsArray()) {
Object& script = Object::Handle(Array::Cast(data).At(0));
@ -7795,6 +7816,7 @@ intptr_t Function::KernelDataProgramOffset() const {
const Object& obj = Object::Handle(raw_ptr()->owner_);
if (obj.IsClass()) {
Library& lib = Library::Handle(Class::Cast(obj).library());
ASSERT(!lib.is_declared_in_bytecode());
return lib.kernel_offset();
}
ASSERT(obj.IsPatchClass());
@ -8434,6 +8456,7 @@ void Field::InheritBinaryDeclarationFrom(const Field& src) const {
}
intptr_t Field::KernelDataProgramOffset() const {
ASSERT(!is_declared_in_bytecode());
const Object& obj = Object::Handle(raw_ptr()->owner_);
// During background JIT compilation field objects are copied
// and copy points to the original field via the owner field.
@ -8441,6 +8464,7 @@ intptr_t Field::KernelDataProgramOffset() const {
return Field::Cast(obj).KernelDataProgramOffset();
} else if (obj.IsClass()) {
Library& lib = Library::Handle(Class::Cast(obj).library());
ASSERT(!lib.is_declared_in_bytecode());
return lib.kernel_offset();
}
ASSERT(obj.IsPatchClass());
@ -9995,14 +10019,15 @@ void Library::AddMetadata(const Object& owner,
void Library::AddClassMetadata(const Class& cls,
const Object& tl_owner,
TokenPosition token_pos,
intptr_t kernel_offset) const {
intptr_t kernel_offset,
intptr_t bytecode_offset) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
// We use the toplevel class as the owner of a class's metadata field because
// a class's metadata is in scope of the library, not the class.
AddMetadata(tl_owner,
String::Handle(zone, MakeClassMetaName(thread, zone, cls)),
token_pos, kernel_offset, 0);
token_pos, kernel_offset, bytecode_offset);
}
void Library::AddFieldMetadata(const Field& field,
@ -10039,8 +10064,10 @@ void Library::AddTypeParameterMetadata(const TypeParameter& param,
void Library::AddLibraryMetadata(const Object& tl_owner,
TokenPosition token_pos,
intptr_t kernel_offset) const {
AddMetadata(tl_owner, Symbols::TopLevel(), token_pos, kernel_offset, 0);
intptr_t kernel_offset,
intptr_t bytecode_offset) const {
AddMetadata(tl_owner, Symbols::TopLevel(), token_pos, kernel_offset,
bytecode_offset);
}
RawString* Library::MakeMetadataName(const Object& obj) const {
@ -10969,7 +10996,8 @@ RawLibrary* Library::NewLibraryHelper(const String& url, bool import_core_lib) {
result.set_debuggable(true);
}
result.set_is_dart_scheme(dart_scheme);
result.set_kernel_offset(-1);
NOT_IN_PRECOMPILED(result.set_is_declared_in_bytecode(false));
NOT_IN_PRECOMPILED(result.set_binary_declaration_offset(0));
result.StoreNonPointer(&result.raw_ptr()->load_state_,
RawLibrary::kAllocated);
result.StoreNonPointer(&result.raw_ptr()->index_, -1);
@ -17684,7 +17712,14 @@ bool Type::IsEquivalent(const Instance& other, TrailPtr trail) const {
for (intptr_t i = 0; i < from_index; i++) {
type_arg = type_args.TypeAt(i);
other_type_arg = other_type_args.TypeAt(i);
ASSERT(type_arg.IsEquivalent(other_type_arg, trail));
// Type arguments may not match if they are TypeRefs without
// underlying type (which will be set later).
ASSERT(
type_arg.IsEquivalent(other_type_arg, trail) ||
(type_arg.IsTypeRef() &&
TypeRef::Cast(type_arg).type() == AbstractType::null()) ||
(other_type_arg.IsTypeRef() &&
TypeRef::Cast(other_type_arg).type() == AbstractType::null()));
}
}
#endif
@ -18127,7 +18162,7 @@ RawTypeRef* TypeRef::InstantiateFrom(
}
void TypeRef::set_type(const AbstractType& value) const {
ASSERT(value.IsFunctionType() || value.HasTypeClass());
ASSERT(value.IsNull() || value.IsFunctionType() || value.HasTypeClass());
ASSERT(!value.IsTypeRef());
StorePointer(&raw_ptr()->type_, value.raw());
}
@ -18143,9 +18178,10 @@ RawAbstractType* TypeRef::Canonicalize(TrailPtr trail) const {
// TODO(regis): Try to reduce the number of nodes required to represent the
// referenced recursive type.
AbstractType& ref_type = AbstractType::Handle(type());
ASSERT(!ref_type.IsNull());
ref_type = ref_type.Canonicalize(trail);
set_type(ref_type);
if (!ref_type.IsNull()) {
ref_type = ref_type.Canonicalize(trail);
set_type(ref_type);
}
return raw();
}
@ -18172,10 +18208,10 @@ void TypeRef::EnumerateURIs(URIs* uris) const {
intptr_t TypeRef::Hash() const {
// Do not calculate the hash of the referenced type to avoid divergence.
const AbstractType& ref_type = AbstractType::Handle(type());
ASSERT(!ref_type.IsNull());
const uint32_t result = Class::Handle(ref_type.type_class()).id();
return FinalizeHash(result, kHashBits);
// TypeRef can participate in type canonicalization even before referenced
// type is set, so its hash should not rely on referenced type.
const intptr_t kTypeRefHash = 37;
return kTypeRefHash;
}
RawTypeRef* TypeRef::New() {

View file

@ -900,6 +900,7 @@ class Class : public Object {
// The type parameters (and their bounds) are specified as an array of
// TypeParameter.
RawTypeArguments* type_parameters() const {
ASSERT(is_declaration_loaded());
return raw_ptr()->type_parameters_;
}
void set_type_parameters(const TypeArguments& value) const;
@ -965,7 +966,10 @@ class Class : public Object {
RawClass* SuperClass(bool original_classes = false) const;
// Interfaces is an array of Types.
RawArray* interfaces() const { return raw_ptr()->interfaces_; }
RawArray* interfaces() const {
ASSERT(is_declaration_loaded());
return raw_ptr()->interfaces_;
}
void set_interfaces(const Array& value) const;
// Returns the list of classes directly implementing this class.
@ -1050,7 +1054,10 @@ class Class : public Object {
void AddField(const Field& field) const;
void AddFields(const GrowableArray<const Field*>& fields) const;
void InjectCIDFields() const;
// If this is a dart:internal.ClassID class, then inject our own const
// fields. Returns true if synthetic fields are injected and regular
// field declarations should be ignored.
bool InjectCIDFields() const;
// Returns an array of all instance fields of this class and its superclasses
// indexed by offset in words.
@ -1192,18 +1199,72 @@ class Class : public Object {
RawCode* allocation_stub() const { return raw_ptr()->allocation_stub_; }
void set_allocation_stub(const Code& value) const;
#if !defined(DART_PRECOMPILED_RUNTIME)
intptr_t binary_declaration_offset() const {
return RawClass::BinaryDeclarationOffset::decode(
raw_ptr()->binary_declaration_);
}
void set_binary_declaration_offset(intptr_t value) const {
ASSERT(value >= 0);
StoreNonPointer(&raw_ptr()->binary_declaration_,
RawClass::BinaryDeclarationOffset::update(
value, raw_ptr()->binary_declaration_));
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
intptr_t kernel_offset() const {
#if defined(DART_PRECOMPILED_RUNTIME)
return -1;
return 0;
#else
return raw_ptr()->kernel_offset_;
ASSERT(!is_declared_in_bytecode());
return binary_declaration_offset();
#endif
}
void set_kernel_offset(intptr_t offset) const {
NOT_IN_PRECOMPILED(StoreNonPointer(&raw_ptr()->kernel_offset_, offset));
void set_kernel_offset(intptr_t value) const {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
#else
ASSERT(!is_declared_in_bytecode());
set_binary_declaration_offset(value);
#endif
}
intptr_t bytecode_offset() const {
#if defined(DART_PRECOMPILED_RUNTIME)
return 0;
#else
ASSERT(is_declared_in_bytecode());
return binary_declaration_offset();
#endif
}
void set_bytecode_offset(intptr_t value) const {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
#else
ASSERT(is_declared_in_bytecode());
set_binary_declaration_offset(value);
#endif
}
bool is_declared_in_bytecode() const {
#if defined(DART_PRECOMPILED_RUNTIME)
return false;
#else
return RawClass::IsDeclaredInBytecode::decode(
raw_ptr()->binary_declaration_);
#endif
}
#if !defined(DART_PRECOMPILED_RUNTIME)
void set_is_declared_in_bytecode(bool value) const {
StoreNonPointer(&raw_ptr()->binary_declaration_,
RawClass::IsDeclaredInBytecode::update(
value, raw_ptr()->binary_declaration_));
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
void DisableAllocationStub() const;
RawArray* constants() const;
@ -1397,9 +1458,10 @@ class Class : public Object {
static const intptr_t kUnknownNumTypeArguments = -1;
int16_t num_type_arguments() const { return raw_ptr()->num_type_arguments_; }
void set_num_type_arguments(intptr_t value) const;
public:
void set_num_type_arguments(intptr_t value) const;
bool has_pragma() const {
return HasPragmaBit::decode(raw_ptr()->state_bits_);
}
@ -3955,7 +4017,8 @@ class Library : public Object {
void AddClassMetadata(const Class& cls,
const Object& tl_owner,
TokenPosition token_pos,
intptr_t kernel_offset) const;
intptr_t kernel_offset,
intptr_t bytecode_offset) const;
void AddFieldMetadata(const Field& field,
TokenPosition token_pos,
intptr_t kernel_offset,
@ -3966,7 +4029,8 @@ class Library : public Object {
intptr_t bytecode_offset) const;
void AddLibraryMetadata(const Object& tl_owner,
TokenPosition token_pos,
intptr_t kernel_offset) const;
intptr_t kernel_offset,
intptr_t bytecode_offset) const;
void AddTypeParameterMetadata(const TypeParameter& param,
TokenPosition token_pos) const;
void CloneMetadataFrom(const Library& from_library,
@ -4057,17 +4121,72 @@ class Library : public Object {
RawExternalTypedData* kernel_data() const { return raw_ptr()->kernel_data_; }
void set_kernel_data(const ExternalTypedData& data) const;
intptr_t kernel_offset() const {
#if !defined(DART_PRECOMPILED_RUNTIME)
return raw_ptr()->kernel_offset_;
intptr_t binary_declaration_offset() const {
return RawLibrary::BinaryDeclarationOffset::decode(
raw_ptr()->binary_declaration_);
}
void set_binary_declaration_offset(intptr_t value) const {
ASSERT(value >= 0);
StoreNonPointer(&raw_ptr()->binary_declaration_,
RawLibrary::BinaryDeclarationOffset::update(
value, raw_ptr()->binary_declaration_));
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
intptr_t kernel_offset() const {
#if defined(DART_PRECOMPILED_RUNTIME)
return 0;
#else
return -1;
ASSERT(!is_declared_in_bytecode());
return binary_declaration_offset();
#endif
}
void set_kernel_offset(intptr_t offset) const {
NOT_IN_PRECOMPILED(StoreNonPointer(&raw_ptr()->kernel_offset_, offset));
void set_kernel_offset(intptr_t value) const {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
#else
ASSERT(!is_declared_in_bytecode());
set_binary_declaration_offset(value);
#endif
}
intptr_t bytecode_offset() const {
#if defined(DART_PRECOMPILED_RUNTIME)
return 0;
#else
ASSERT(is_declared_in_bytecode());
return binary_declaration_offset();
#endif
}
void set_bytecode_offset(intptr_t value) const {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
#else
ASSERT(is_declared_in_bytecode());
set_binary_declaration_offset(value);
#endif
}
bool is_declared_in_bytecode() const {
#if defined(DART_PRECOMPILED_RUNTIME)
return false;
#else
return RawLibrary::IsDeclaredInBytecode::decode(
raw_ptr()->binary_declaration_);
#endif
}
#if !defined(DART_PRECOMPILED_RUNTIME)
void set_is_declared_in_bytecode(bool value) const {
StoreNonPointer(&raw_ptr()->binary_declaration_,
RawLibrary::IsDeclaredInBytecode::update(
value, raw_ptr()->binary_declaration_));
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
static RawLibrary* LookupLibrary(Thread* thread, const String& url);
static RawLibrary* GetLibrary(intptr_t index);

View file

@ -422,8 +422,10 @@ void Class::PatchFieldsAndFunctions() const {
PatchClass::Handle(PatchClass::New(*this, Script::Handle(script())));
ASSERT(!patch.IsNull());
const Library& lib = Library::Handle(library());
patch.set_library_kernel_data(ExternalTypedData::Handle(lib.kernel_data()));
patch.set_library_kernel_offset(lib.kernel_offset());
if (!lib.is_declared_in_bytecode()) {
patch.set_library_kernel_data(ExternalTypedData::Handle(lib.kernel_data()));
patch.set_library_kernel_offset(lib.kernel_offset());
}
const Array& funcs = Array::Handle(functions());
Function& func = Function::Handle();

View file

@ -807,7 +807,12 @@ class RawClass : public RawObject {
int16_t num_type_arguments_; // Number of type arguments in flattened vector.
uint16_t num_native_fields_;
uint32_t state_bits_;
NOT_IN_PRECOMPILED(intptr_t kernel_offset_);
#if !defined(DART_PRECOMPILED_RUNTIME)
typedef BitField<uint32_t, bool, 0, 1> IsDeclaredInBytecode;
typedef BitField<uint32_t, uint32_t, 1, 31> BinaryDeclarationOffset;
uint32_t binary_declaration_;
#endif // !defined(DART_PRECOMPILED_RUNTIME)
friend class Instance;
friend class Isolate;
@ -1215,9 +1220,12 @@ class RawLibrary : public RawObject {
bool is_dart_scheme_;
bool debuggable_; // True if debugger can stop in library.
bool is_in_fullsnapshot_; // True if library is in a full snapshot.
NOT_IN_PRECOMPILED(intptr_t kernel_offset_); // Offset of this library's
// kernel data in the overall
// kernel program.
#if !defined(DART_PRECOMPILED_RUNTIME)
typedef BitField<uint32_t, bool, 0, 1> IsDeclaredInBytecode;
typedef BitField<uint32_t, uint32_t, 1, 31> BinaryDeclarationOffset;
uint32_t binary_declaration_;
#endif // !defined(DART_PRECOMPILED_RUNTIME)
friend class Class;
friend class Isolate;

View file

@ -2565,6 +2565,7 @@ void DeoptimizeAt(const Code& optimized_code, StackFrame* frame) {
// N.B.: Update the pending deopt table before updating the frame. The
// profiler may attempt a stack walk in between.
ASSERT(!frame->is_interpreted());
thread->isolate()->AddPendingDeopt(frame->fp(), deopt_pc);
frame->MarkForLazyDeopt();

View file

@ -85,6 +85,7 @@ class ObjectPointerVisitor;
V(DartSchemePrivate, "dart:_") \
V(DartTypedData, "dart:typed_data") \
V(DartVMProduct, "dart.vm.product") \
V(DartVMServiceIO, "dart:vmservice_io") \
V(DartVMService, "dart:_vmservice") \
V(DebugClassName, "#DebugClass") \
V(DebugProcedureName, ":Eval") \

View file

@ -1035,10 +1035,12 @@ symbol_conflict_test: Pass, Slow
[ ($arch == simarm || $arch == simarm64 || $arch == simdbc64) && ($compiler == dartk || $compiler == dartkb) ]
least_upper_bound_expansive_test/none: RuntimeError # Please triage.
[ ($compiler == app_jitk || $compiler == dartk || $compiler == dartkb || $compiler == dartkp) && ($runtime == dart_precompiled || $runtime == vm) ]
type_alias_equality_test/04: RuntimeError # Issue 32783
[ ($compiler == app_jitk || $compiler == dartk || $compiler == dartkp) && ($runtime == dart_precompiled || $runtime == vm) ]
covariant_subtyping_with_mixin_test: RuntimeError # Issue 34321
type_alias_equality_test/03: RuntimeError # Issue 32783
type_alias_equality_test/04: RuntimeError # Issue 32783
[ ($compiler == dartk || $compiler == dartkb) && ($hot_reload || $hot_reload_rollback) ]
async_star_test/01: Skip # Timeout