mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 14:29:50 +00:00
These changes are causing a segfault in DartEntry::InvokeFunction in dart_entry.cc in Flutter,
which was blocking the Dart SDK roll. Revert "Take 3 for "[vm/kernel/precomp] Remove procedures from entry points files."" This reverts commit567109df7f
. Revert "[vm/precomp] Extend @pragma entry-points to classes." This reverts commit232698047c
. Change-Id: Ib63d1afb8a1c978be7ddf282af0e7d5547111cc3 Reviewed-on: https://dart-review.googlesource.com/67300 Reviewed-by: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
parent
6e322f794c
commit
08f59e5de3
|
@ -102,6 +102,7 @@ Future<int> compile(List<String> arguments) async {
|
|||
entryPoints.addAll([
|
||||
'pkg/vm/lib/transformations/type_flow/entry_points.json',
|
||||
'pkg/vm/lib/transformations/type_flow/entry_points_extra.json',
|
||||
'pkg/vm/lib/transformations/type_flow/entry_points_extra_standalone.json',
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -1180,7 +1180,7 @@ class TypeFlowAnalysis implements EntryPointsListener, CallHandler {
|
|||
|
||||
TypeFlowAnalysis(Component component, CoreTypes coreTypes,
|
||||
ClosedWorldClassHierarchy hierarchy, this.environment, this.libraryIndex,
|
||||
{List<String> entryPointsJSONFiles, EntryPointsAnnotationMatcher matcher})
|
||||
{List<String> entryPointsJSONFiles})
|
||||
: nativeCodeOracle = new NativeCodeOracle(libraryIndex) {
|
||||
hierarchyCache = new _ClassHierarchyCache(this, hierarchy);
|
||||
summaryCollector =
|
||||
|
@ -1192,10 +1192,7 @@ class TypeFlowAnalysis implements EntryPointsListener, CallHandler {
|
|||
nativeCodeOracle.processEntryPointsJSONFiles(entryPointsJSONFiles, this);
|
||||
}
|
||||
|
||||
matcher ??= new ConstantEntryPointsAnnotationMatcher(coreTypes);
|
||||
|
||||
component
|
||||
.accept(new PragmaEntryPointsVisitor(this, nativeCodeOracle, matcher));
|
||||
component.accept(new PragmaEntryPointsVisitor(coreTypes, this));
|
||||
}
|
||||
|
||||
_Invocation get currentInvocation => workList.callStack.last;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,85 @@
|
|||
{
|
||||
"roots": [
|
||||
{
|
||||
"library": "dart:core",
|
||||
"class": "Object",
|
||||
"name": "noSuchMethod",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"class": "Object",
|
||||
"name": "_haveSameRuntimeType",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"class": "Object",
|
||||
"name": "_instanceOf",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"class": "List",
|
||||
"name": "_fromLiteral",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"class": "Map",
|
||||
"name": "_fromLiteral",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"class": "_ImmutableList",
|
||||
"action": "create-instance"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"class": "_ImmutableMap",
|
||||
"action": "create-instance"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"class": "_ImmutableMap",
|
||||
"name": "_create",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"class": "_StringBase",
|
||||
"name": "_interpolate",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"class": "_StringBase",
|
||||
"name": "_interpolateSingle",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"name": "_classRangeAssert",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"name": "_classIdEqualsAssert",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"class": "_AssertionError",
|
||||
"name": "_evaluateAssertion",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"class": "_AssertionError",
|
||||
"name": "_throwNew",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"class": "_Closure",
|
||||
|
@ -35,6 +115,64 @@
|
|||
"class": "_Closure",
|
||||
"name": "_hash",
|
||||
"action": "get"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"class": "_CompileTimeError",
|
||||
"action": "create-instance"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"class": "Object",
|
||||
"name": "_simpleInstanceOf",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"class": "Object",
|
||||
"name": "_simpleInstanceOfTrue",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:core",
|
||||
"class": "Object",
|
||||
"name": "_simpleInstanceOfFalse",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:_internal",
|
||||
"name": "_classRangeCheck",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:_internal",
|
||||
"name": "_prependTypeArguments",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:async",
|
||||
"name": "_setAsyncThreadStackTrace",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:async",
|
||||
"name": "_clearAsyncThreadStackTrace",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:async",
|
||||
"name": "_asyncStarMoveNextHelper",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:async",
|
||||
"name": "_completeOnAsyncReturn",
|
||||
"action": "call"
|
||||
},
|
||||
{
|
||||
"library": "dart:async",
|
||||
"class": "_AsyncStarStreamController",
|
||||
"action": "create-instance"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"roots": [
|
||||
{
|
||||
"library": "dart:_builtin",
|
||||
"name": "_resolveScriptUri",
|
||||
"action": "call"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -29,23 +29,25 @@ abstract class EntryPointsListener {
|
|||
ConcreteType addAllocatedClass(Class c);
|
||||
}
|
||||
|
||||
abstract class EntryPointsAnnotationMatcher {
|
||||
bool annotationsDefineRoot(List<Expression> annotations);
|
||||
}
|
||||
|
||||
class ConstantEntryPointsAnnotationMatcher
|
||||
implements EntryPointsAnnotationMatcher {
|
||||
/// Some entry points are not listed in any JSON file but are marked with the
|
||||
/// `@pragma('vm.entry_point', ...)` annotation instead.
|
||||
///
|
||||
/// Currently Procedure`s (action "call") can be annotated in this way.
|
||||
//
|
||||
// TODO(sjindel): Support all types of entry points.
|
||||
class PragmaEntryPointsVisitor extends RecursiveVisitor {
|
||||
final EntryPointsListener entryPoints;
|
||||
final CoreTypes coreTypes;
|
||||
|
||||
ConstantEntryPointsAnnotationMatcher(this.coreTypes);
|
||||
PragmaEntryPointsVisitor(this.coreTypes, this.entryPoints);
|
||||
|
||||
bool definesRoot(InstanceConstant constant) {
|
||||
bool _definesRoot(InstanceConstant constant) {
|
||||
if (constant.classReference.node != coreTypes.pragmaClass) return false;
|
||||
|
||||
Constant name = constant.fieldValues[coreTypes.pragmaName.reference];
|
||||
assertx(name != null);
|
||||
if (name is! StringConstant ||
|
||||
(name as StringConstant).value != "vm.entry-point") {
|
||||
(name as StringConstant).value != "vm.entry_point") {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -55,66 +57,34 @@ class ConstantEntryPointsAnnotationMatcher
|
|||
return options is BoolConstant && options.value;
|
||||
}
|
||||
|
||||
@override
|
||||
bool annotationsDefineRoot(List<Expression> annotations) {
|
||||
bool _annotationsDefineRoot(List<Expression> annotations) {
|
||||
for (var annotation in annotations) {
|
||||
if (annotation is ConstantExpression) {
|
||||
Constant constant = annotation.constant;
|
||||
if (constant is InstanceConstant) {
|
||||
if (definesRoot(constant)) {
|
||||
if (_definesRoot(constant)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw "All annotations must be constants!";
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Some entry points are not listed in any JSON file but are marked with the
|
||||
/// `@pragma('vm.entry-point', ...)` annotation instead.
|
||||
///
|
||||
/// Currently Procedure`s (action "call") can be annotated in this way.
|
||||
//
|
||||
// TODO(sjindel): Support all types of entry points.
|
||||
class PragmaEntryPointsVisitor extends RecursiveVisitor {
|
||||
final EntryPointsListener entryPoints;
|
||||
final NativeCodeOracle nativeCodeOracle;
|
||||
final EntryPointsAnnotationMatcher matcher;
|
||||
Class currentClass = null;
|
||||
|
||||
PragmaEntryPointsVisitor(
|
||||
this.entryPoints, this.nativeCodeOracle, this.matcher);
|
||||
|
||||
@override
|
||||
visitClass(Class klass) {
|
||||
if (matcher.annotationsDefineRoot(klass.annotations)) {
|
||||
if (_annotationsDefineRoot(klass.annotations)) {
|
||||
entryPoints.addAllocatedClass(klass);
|
||||
}
|
||||
currentClass = klass;
|
||||
klass.visitChildren(this);
|
||||
}
|
||||
|
||||
@override
|
||||
visitProcedure(Procedure proc) {
|
||||
if (matcher.annotationsDefineRoot(proc.annotations)) {
|
||||
assertx(!proc.isGetter && !proc.isSetter);
|
||||
if (_annotationsDefineRoot(proc.annotations)) {
|
||||
entryPoints.addRawCall(proc.isInstanceMember
|
||||
? new InterfaceSelector(proc, callKind: CallKind.Method)
|
||||
: new DirectSelector(proc, callKind: CallKind.Method));
|
||||
nativeCodeOracle.setMemberReferencedFromNativeCode(proc);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
visitConstructor(Constructor ctor) {
|
||||
if (matcher.annotationsDefineRoot(ctor.annotations)) {
|
||||
entryPoints
|
||||
.addRawCall(new DirectSelector(ctor, callKind: CallKind.Method));
|
||||
entryPoints.addAllocatedClass(currentClass);
|
||||
nativeCodeOracle.setMemberReferencedFromNativeCode(ctor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -131,9 +101,6 @@ class NativeCodeOracle {
|
|||
bool isMemberReferencedFromNativeCode(Member member) =>
|
||||
_membersReferencedFromNativeCode.contains(member);
|
||||
|
||||
void setMemberReferencedFromNativeCode(Member member) =>
|
||||
_membersReferencedFromNativeCode.add(member);
|
||||
|
||||
/// Simulate the execution of a native method by adding its entry points
|
||||
/// using [entryPointsListener]. Returns result type of the native method.
|
||||
Type handleNativeProcedure(
|
||||
|
|
|
@ -14,7 +14,6 @@ import 'package:kernel/library_index.dart' show LibraryIndex;
|
|||
import 'package:kernel/type_environment.dart';
|
||||
|
||||
import 'analysis.dart';
|
||||
import 'native_code.dart';
|
||||
import 'calls.dart';
|
||||
import 'summary_collector.dart';
|
||||
import 'types.dart';
|
||||
|
@ -32,8 +31,7 @@ const bool kDumpClassHierarchy =
|
|||
/// Whole-program type flow analysis and transformation.
|
||||
/// Assumes strong mode and closed world.
|
||||
Component transformComponent(
|
||||
CoreTypes coreTypes, Component component, List<String> entryPoints,
|
||||
[EntryPointsAnnotationMatcher matcher]) {
|
||||
CoreTypes coreTypes, Component component, List<String> entryPoints) {
|
||||
if ((entryPoints == null) || entryPoints.isEmpty) {
|
||||
throw 'Error: unable to perform global type flow analysis without entry points.';
|
||||
}
|
||||
|
@ -55,7 +53,7 @@ Component transformComponent(
|
|||
|
||||
final typeFlowAnalysis = new TypeFlowAnalysis(
|
||||
component, coreTypes, hierarchy, types, libraryIndex,
|
||||
entryPointsJSONFiles: entryPoints, matcher: matcher);
|
||||
entryPointsJSONFiles: entryPoints);
|
||||
|
||||
Procedure main = component.mainMethod;
|
||||
final Selector mainSelector = new DirectSelector(main);
|
||||
|
|
|
@ -8,50 +8,13 @@ import 'package:kernel/ast.dart';
|
|||
import 'package:kernel/core_types.dart';
|
||||
import 'package:kernel/kernel.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm/transformations/type_flow/native_code.dart';
|
||||
import 'package:vm/transformations/type_flow/transformer.dart'
|
||||
show transformComponent;
|
||||
import 'package:vm/transformations/type_flow/utils.dart';
|
||||
|
||||
import '../../common_test_utils.dart';
|
||||
|
||||
final String pkgVmDir = Platform.script.resolve('../../..').toFilePath();
|
||||
|
||||
// Since we don't run the constants transformation in this test, we can't
|
||||
// recognize all pragma annotations precisely. Instead, we pattern match on
|
||||
// annotations which look like a pragma and assume that their options field
|
||||
// evaluates to true.
|
||||
class ExpressionEntryPointsAnnotationMatcher
|
||||
extends EntryPointsAnnotationMatcher {
|
||||
final CoreTypes coreTypes;
|
||||
|
||||
ExpressionEntryPointsAnnotationMatcher(this.coreTypes);
|
||||
|
||||
bool _looksLikePragma(ConstructorInvocation annotation) {
|
||||
if (annotation.target.parent != coreTypes.pragmaClass) return false;
|
||||
|
||||
if (annotation.arguments.types.length != 0 ||
|
||||
annotation.arguments.positional.length < 1 ||
|
||||
annotation.arguments.named.length != 0) {
|
||||
throw "Cannot evaluate pragma annotation $annotation";
|
||||
}
|
||||
|
||||
var argument = annotation.arguments.positional[0];
|
||||
return argument is StringLiteral && argument.value == "vm.entry-point";
|
||||
}
|
||||
|
||||
@override
|
||||
bool annotationsDefineRoot(List<Expression> annotations) {
|
||||
for (var annotation in annotations) {
|
||||
assertx(annotation is! ConstantExpression);
|
||||
if (annotation is ConstructorInvocation && _looksLikePragma(annotation)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
runTestCase(Uri source) async {
|
||||
Component component = await compileTestCaseToKernelProgram(source);
|
||||
|
||||
|
@ -62,8 +25,7 @@ runTestCase(Uri source) async {
|
|||
pkgVmDir + '/lib/transformations/type_flow/entry_points_extra.json',
|
||||
];
|
||||
|
||||
component = transformComponent(coreTypes, component, entryPoints,
|
||||
new ExpressionEntryPointsAnnotationMatcher(coreTypes));
|
||||
component = transformComponent(coreTypes, component, entryPoints);
|
||||
|
||||
final actual = kernelLibraryToString(component.mainMethod.enclosingLibrary);
|
||||
|
||||
|
|
|
@ -90,7 +90,8 @@ export DART_CONFIGURATION=${DART_CONFIGURATION:-ReleaseX64}
|
|||
BIN_DIR="$OUT_DIR/$DART_CONFIGURATION"
|
||||
|
||||
ENTRY_POINTS="--entry-points ${BIN_DIR}/gen/runtime/bin/precompiler_entry_points.json \
|
||||
--entry-points ${SDK_DIR}/pkg/vm/lib/transformations/type_flow/entry_points_extra.json"
|
||||
--entry-points ${SDK_DIR}/pkg/vm/lib/transformations/type_flow/entry_points_extra.json \
|
||||
--entry-points ${SDK_DIR}/pkg/vm/lib/transformations/type_flow/entry_points_extra_standalone.json"
|
||||
|
||||
# Step 1: Generate Kernel binary from the input Dart source.
|
||||
"$BIN_DIR"/dart \
|
||||
|
@ -115,4 +116,4 @@ ENTRY_POINTS="--entry-points ${BIN_DIR}/gen/runtime/bin/precompiler_entry_points
|
|||
# Step 3: Assemble the assembly file into an ELF object.
|
||||
if [ $BUILD_ELF -eq 1 ]; then
|
||||
gcc -shared -o "$SNAPSHOT_FILE" "$DART_BOOTSTRAP_OUT"
|
||||
fi
|
||||
fi
|
|
@ -28,7 +28,6 @@ void _print(arg) {
|
|||
_printString(arg.toString());
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
_getPrintClosure() => _print;
|
||||
|
||||
// Asynchronous loading of resources.
|
||||
|
@ -138,7 +137,6 @@ _enforceTrailingSlash(uri) {
|
|||
|
||||
// Embedder Entrypoint:
|
||||
// The embedder calls this method with the current working directory.
|
||||
@pragma("vm.entry-point")
|
||||
void _setWorkingDirectory(String cwd) {
|
||||
if (!_setupCompleted) {
|
||||
_setupHooks();
|
||||
|
@ -154,7 +152,6 @@ void _setWorkingDirectory(String cwd) {
|
|||
|
||||
// Embedder Entrypoint:
|
||||
// The embedder calls this method with a custom package root.
|
||||
@pragma("vm.entry-point")
|
||||
String _setPackageRoot(String packageRoot) {
|
||||
if (!_setupCompleted) {
|
||||
_setupHooks();
|
||||
|
@ -185,7 +182,6 @@ String _setPackageRoot(String packageRoot) {
|
|||
}
|
||||
|
||||
// Embedder Entrypoint:
|
||||
@pragma("vm.entry-point")
|
||||
String _setPackagesMap(String packagesParam) {
|
||||
if (!_setupCompleted) {
|
||||
_setupHooks();
|
||||
|
@ -217,7 +213,6 @@ String _setPackagesMap(String packagesParam) {
|
|||
|
||||
// Resolves the script uri in the current working directory iff the given uri
|
||||
// did not specify a scheme (e.g. a path to a script file on the command line).
|
||||
@pragma("vm.entry-point")
|
||||
String _resolveScriptUri(String scriptName) {
|
||||
if (_traceLoading) {
|
||||
_log("Resolving script: $scriptName");
|
||||
|
@ -246,7 +241,6 @@ String _resolveScriptUri(String scriptName) {
|
|||
|
||||
// Embedder Entrypoint (gen_snapshot):
|
||||
// Resolve relative paths relative to working directory.
|
||||
@pragma("vm.entry-point")
|
||||
String _resolveInWorkingDirectory(String fileName) {
|
||||
if (!_setupCompleted) {
|
||||
_setupHooks();
|
||||
|
@ -303,7 +297,6 @@ String _filePathFromUri(String userUri) {
|
|||
}
|
||||
|
||||
// Embedder Entrypoint.
|
||||
@pragma("vm.entry-point")
|
||||
_libraryFilePath(String libraryUri) {
|
||||
if (!_setupCompleted) {
|
||||
_setupHooks();
|
||||
|
@ -319,7 +312,6 @@ _libraryFilePath(String libraryUri) {
|
|||
}
|
||||
|
||||
// Register callbacks and hooks with the rest of the core libraries.
|
||||
@pragma("vm.entry-point")
|
||||
_setupHooks() {
|
||||
_setupCompleted = true;
|
||||
VMLibraryHooks.resourceReadAsBytes = _resourceReadAsBytes;
|
||||
|
|
|
@ -55,7 +55,6 @@ class _IOCrypto {
|
|||
static Uint8List getRandomBytes(int count) native "Crypto_GetRandomBytes";
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
_setupHooks() {
|
||||
VMLibraryHooks.eventHandlerSendData = _EventHandler._sendData;
|
||||
VMLibraryHooks.timerMillisecondClock = _EventHandler._timerMillisecondClock;
|
||||
|
|
|
@ -67,5 +67,4 @@ Uri _uriBaseClosure() {
|
|||
return new Uri.directory(result);
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
_getUriBaseClosure() => _uriBaseClosure;
|
||||
|
|
|
@ -414,7 +414,6 @@ class _FSEventStreamFileSystemWatcher extends _FileSystemWatcher {
|
|||
}
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
Uint8List _makeUint8ListView(Uint8List source, int offsetInBytes, int length) {
|
||||
return new Uint8List.view(source.buffer, offsetInBytes, length);
|
||||
}
|
||||
|
|
|
@ -889,20 +889,46 @@ static void ReadFile(const char* filename, uint8_t** buffer, intptr_t* size) {
|
|||
|
||||
static Dart_QualifiedFunctionName standalone_entry_points[] = {
|
||||
// Functions.
|
||||
{"dart:_builtin", "::", "_getPrintClosure"},
|
||||
{"dart:_builtin", "::", "_libraryFilePath"},
|
||||
{"dart:_builtin", "::", "_resolveInWorkingDirectory"},
|
||||
{"dart:_builtin", "::", "_setPackageRoot"},
|
||||
{"dart:_builtin", "::", "_setPackagesMap"},
|
||||
{"dart:_builtin", "::", "_setWorkingDirectory"},
|
||||
{"dart:async", "::", "_setScheduleImmediateClosure"},
|
||||
{"dart:cli", "::", "_getWaitForEvent"},
|
||||
{"dart:cli", "::", "_waitForEventClosure"},
|
||||
{"dart:io", "::", "_getUriBaseClosure"},
|
||||
{"dart:io", "::", "_getWatchSignalInternal"},
|
||||
{"dart:io", "::", "_makeDatagram"},
|
||||
{"dart:io", "::", "_makeUint8ListView"},
|
||||
{"dart:io", "::", "_setupHooks"},
|
||||
{"dart:io", "_EmbedderConfig", "_mayExit"},
|
||||
{"dart:io", "_ExternalBuffer", "get:end"},
|
||||
{"dart:io", "_ExternalBuffer", "get:start"},
|
||||
{"dart:io", "_ExternalBuffer", "set:data"},
|
||||
{"dart:io", "_ExternalBuffer", "set:end"},
|
||||
{"dart:io", "_ExternalBuffer", "set:start"},
|
||||
{"dart:io", "_Namespace", "_setupNamespace"},
|
||||
{"dart:io", "_Platform", "set:_nativeScript"},
|
||||
{"dart:io", "_ProcessStartStatus", "set:_errorCode"},
|
||||
{"dart:io", "_ProcessStartStatus", "set:_errorMessage"},
|
||||
{"dart:io", "_SecureFilterImpl", "get:buffers"},
|
||||
{"dart:io", "_SecureFilterImpl", "get:ENCRYPTED_SIZE"},
|
||||
{"dart:io", "_SecureFilterImpl", "get:SIZE"},
|
||||
{"dart:io", "CertificateException", "CertificateException."},
|
||||
{"dart:io", "Directory", "Directory."},
|
||||
{"dart:io", "File", "File."},
|
||||
{"dart:io", "FileSystemException", "FileSystemException."},
|
||||
{"dart:io", "HandshakeException", "HandshakeException."},
|
||||
{"dart:io", "Link", "Link."},
|
||||
{"dart:io", "OSError", "OSError."},
|
||||
{"dart:io", "TlsException", "TlsException."},
|
||||
{"dart:io", "X509Certificate", "X509Certificate._"},
|
||||
{"dart:isolate", "::", "_getIsolateScheduleImmediateClosure"},
|
||||
{"dart:isolate", "::", "_setupHooks"},
|
||||
{"dart:isolate", "::", "_startMainIsolate"},
|
||||
// Fields
|
||||
{"dart:io", "_EmbedderConfig", "_mayExit"},
|
||||
{"dart:cli", "::", "_waitForEventClosure"},
|
||||
{"dart:_builtin", "::", "_isolateId"},
|
||||
{"dart:_builtin", "::", "_loadPort"},
|
||||
{"dart:_internal", "::", "_printClosure"},
|
||||
|
|
|
@ -33,7 +33,6 @@ class _NamespaceImpl extends NativeFieldWrapperClass1 implements _Namespace {
|
|||
@patch
|
||||
class _Namespace {
|
||||
@patch
|
||||
@pragma("vm.entry-point")
|
||||
static void _setupNamespace(var namespace) {
|
||||
_NamespaceImpl._setupNamespace(namespace);
|
||||
}
|
||||
|
|
|
@ -129,7 +129,6 @@ class _SignalController {
|
|||
native "Process_ClearSignalHandler";
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
Function _getWatchSignalInternal() => _ProcessUtils._watchSignalInternal;
|
||||
|
||||
@patch
|
||||
|
|
|
@ -20,7 +20,6 @@ class _SecureFilter {
|
|||
@patch
|
||||
class X509Certificate {
|
||||
@patch
|
||||
@pragma("vm.entry-point")
|
||||
factory X509Certificate._() => new _X509CertificateImpl();
|
||||
}
|
||||
|
||||
|
|
|
@ -1905,7 +1905,6 @@ class _RawDatagramSocket extends Stream<RawSocketEvent>
|
|||
}
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
Datagram _makeDatagram(
|
||||
List<int> data, String address, List<int> in_addr, int port) {
|
||||
return new Datagram(data, new _InternetAddress(address, null, in_addr), port);
|
||||
|
|
|
@ -220,7 +220,7 @@ _registerSignalHandler() {
|
|||
_signalSubscription = _signalWatch(ProcessSignal.SIGQUIT).listen(_onSignal);
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point", !const bool.fromEnvironment("dart.vm.product"))
|
||||
@pragma("vm.entry_point", !const bool.fromEnvironment("dart.vm.product"))
|
||||
main() {
|
||||
// Set embedder hooks.
|
||||
VMServiceEmbedderHooks.cleanup = cleanupCallback;
|
||||
|
|
|
@ -121,7 +121,6 @@ class _List<E> extends FixedLengthListBase<E> {
|
|||
// classes (and inline cache misses) versus a field in the native
|
||||
// implementation (checks when modifying). We should keep watching
|
||||
// the inline cache misses.
|
||||
@pragma("vm.entry-point")
|
||||
class _ImmutableList<E> extends UnmodifiableListBase<E> {
|
||||
factory _ImmutableList._uninstantiable() {
|
||||
throw new UnsupportedError(
|
||||
|
|
|
@ -52,7 +52,6 @@ class List<E> {
|
|||
|
||||
// Factory constructing a mutable List from a parser generated List literal.
|
||||
// [elements] contains elements that are already type checked.
|
||||
@pragma("vm.entry-point")
|
||||
factory List._fromLiteral(List elements) {
|
||||
if (elements.isEmpty) {
|
||||
return new _GrowableList<E>(0);
|
||||
|
|
|
@ -120,7 +120,6 @@ void _asyncStarListenHelper(var object, var awaiter) {
|
|||
object._awaiter = awaiter;
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
void _asyncStarMoveNextHelper(var stream) {
|
||||
if (stream is! _StreamImpl) {
|
||||
return;
|
||||
|
@ -135,7 +134,6 @@ void _asyncStarMoveNextHelper(var stream) {
|
|||
|
||||
// _AsyncStarStreamController is used by the compiler to implement
|
||||
// async* generator functions.
|
||||
@pragma("vm.entry-point")
|
||||
class _AsyncStarStreamController<T> {
|
||||
StreamController<T> controller;
|
||||
Function asyncStarBody;
|
||||
|
@ -290,7 +288,6 @@ class _StreamImpl<T> {
|
|||
Function _generator;
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
void _completeOnAsyncReturn(Completer completer, Object value) {
|
||||
completer.complete(value);
|
||||
}
|
||||
|
@ -300,11 +297,9 @@ void _completeOnAsyncReturn(Completer completer, Object value) {
|
|||
Object _asyncStackTraceHelper(Function async_op)
|
||||
native "StackTrace_asyncStackTraceHelper";
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
void _clearAsyncThreadStackTrace()
|
||||
native "StackTrace_clearAsyncThreadStackTrace";
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
void _setAsyncThreadStackTrace(StackTrace stackTrace)
|
||||
native "StackTrace_setAsyncThreadStackTrace";
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
// This function takes care of rehashing of the linked hashmaps in [objects]. We
|
||||
// do this eagerly after snapshot deserialization.
|
||||
@pragma("vm.entry-point")
|
||||
void _rehashObjects(List objects) {
|
||||
final int length = objects.length;
|
||||
for (int i = 0; i < length; ++i) {
|
||||
|
|
|
@ -68,7 +68,6 @@ _registerExtension(String method, ServiceExtensionHandler handler)
|
|||
native "Developer_registerExtension";
|
||||
|
||||
// This code is only invoked when there is no other Dart code on the stack.
|
||||
@pragma("vm.entry-point", !const bool.fromEnvironment("dart.vm.product"))
|
||||
_runExtension(
|
||||
ServiceExtensionHandler handler,
|
||||
String method,
|
||||
|
|
|
@ -23,14 +23,12 @@ class Error {
|
|||
}
|
||||
|
||||
class _AssertionError extends Error implements AssertionError {
|
||||
@pragma("vm.entry-point")
|
||||
_AssertionError._create(
|
||||
this._failedAssertion, this._url, this._line, this._column, this.message);
|
||||
|
||||
// AssertionError_throwNew in errors.cc fishes the assertion source code
|
||||
// out of the script. It expects a Dart stack frame from class
|
||||
// _AssertionError. Thus we need a Dart stub that calls the native code.
|
||||
@pragma("vm.entry-point")
|
||||
static _throwNew(int assertionStart, int assertionEnd, Object message) {
|
||||
_doThrowNew(assertionStart, assertionEnd, message);
|
||||
}
|
||||
|
@ -38,7 +36,6 @@ class _AssertionError extends Error implements AssertionError {
|
|||
static _doThrowNew(int assertionStart, int assertionEnd, Object message)
|
||||
native "AssertionError_throwNew";
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
static _evaluateAssertion(condition) {
|
||||
if (identical(condition, true) || identical(condition, false)) {
|
||||
return condition;
|
||||
|
@ -80,7 +77,6 @@ class _AssertionError extends Error implements AssertionError {
|
|||
}
|
||||
|
||||
class _TypeError extends _AssertionError implements TypeError {
|
||||
@pragma("vm.entry-point")
|
||||
_TypeError._create(String url, int line, int column, String errorMsg)
|
||||
: super._create("is assignable", url, line, column, errorMsg);
|
||||
|
||||
|
@ -103,7 +99,6 @@ class _TypeError extends _AssertionError implements TypeError {
|
|||
}
|
||||
|
||||
class _CastError extends Error implements CastError {
|
||||
@pragma("vm.entry-point")
|
||||
_CastError._create(this._url, this._line, this._column, this._errorMsg);
|
||||
|
||||
// A CastError is allocated by TypeError._throwNew() when dst_name equals
|
||||
|
@ -121,7 +116,6 @@ class _CastError extends Error implements CastError {
|
|||
@patch
|
||||
class FallThroughError {
|
||||
@patch
|
||||
@pragma("vm.entry-point")
|
||||
FallThroughError._create(String url, int line)
|
||||
: _url = url,
|
||||
_line = line;
|
||||
|
@ -140,7 +134,6 @@ class FallThroughError {
|
|||
}
|
||||
|
||||
class _InternalError {
|
||||
@pragma("vm.entry-point")
|
||||
const _InternalError(this._msg);
|
||||
String toString() => "InternalError: '${_msg}'";
|
||||
final String _msg;
|
||||
|
@ -162,7 +155,6 @@ class CyclicInitializationError {
|
|||
|
||||
@patch
|
||||
class AbstractClassInstantiationError {
|
||||
@pragma("vm.entry-point")
|
||||
AbstractClassInstantiationError._create(
|
||||
this._className, this._url, this._line);
|
||||
|
||||
|
@ -260,7 +252,6 @@ class NoSuchMethodError {
|
|||
// _throwNew above, taking a TypeArguments object rather than an unpacked list
|
||||
// of types, as well as a list of all arguments and a list of names, rather
|
||||
// than a separate list of positional arguments and a map of named arguments.
|
||||
@pragma("vm.entry-point")
|
||||
NoSuchMethodError._withType(
|
||||
this._receiver,
|
||||
String memberName,
|
||||
|
@ -579,14 +570,12 @@ class NoSuchMethodError {
|
|||
}
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
class _CompileTimeError extends Error {
|
||||
final String _errorMsg;
|
||||
_CompileTimeError(this._errorMsg);
|
||||
String toString() => _errorMsg;
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
dynamic _classRangeAssert(int position, dynamic instance, _Type type, int cid,
|
||||
int lowerLimit, int upperLimit) {
|
||||
if ((cid < lowerLimit || cid > upperLimit) && instance != null) {
|
||||
|
@ -596,7 +585,6 @@ dynamic _classRangeAssert(int position, dynamic instance, _Type type, int cid,
|
|||
return instance;
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
dynamic _classIdEqualsAssert(
|
||||
int position, dynamic instance, _Type type, int cid, int otherCid) {
|
||||
if (cid != otherCid && instance != null) {
|
||||
|
|
|
@ -8,5 +8,4 @@
|
|||
bool identical(Object a, Object b) native "Identical_comparison";
|
||||
|
||||
@patch
|
||||
@pragma("vm.entry-point")
|
||||
int identityHashCode(Object object) => object._identityHashCode;
|
||||
|
|
|
@ -7,11 +7,9 @@
|
|||
/// Immutable map class for compiler generated map literals.
|
||||
// TODO(lrn): Extend MapBase with UnmodifiableMapMixin when mixins
|
||||
// support forwarding const constructors.
|
||||
@pragma("vm.entry-point")
|
||||
class _ImmutableMap<K, V> implements Map<K, V> {
|
||||
final _ImmutableList _kvPairs;
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
const _ImmutableMap._create(_ImmutableList keyValuePairs)
|
||||
: _kvPairs = keyValuePairs;
|
||||
|
||||
|
|
|
@ -68,7 +68,6 @@ final bool is64Bit = _inquireIs64Bit();
|
|||
|
||||
bool _inquireIs64Bit() native "Internal_inquireIs64Bit";
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
bool _classRangeCheck(int cid, int lowerLimit, int upperLimit) {
|
||||
return cid >= lowerLimit && cid <= upperLimit;
|
||||
}
|
||||
|
@ -98,7 +97,6 @@ class Lists {
|
|||
// function type arguments (may be null). The result is null if both input
|
||||
// vectors are null or is a newly allocated and canonicalized vector of length
|
||||
// 'totalLen'.
|
||||
@pragma("vm.entry-point")
|
||||
_prependTypeArguments(functionTypeArguments, parentTypeArguments, parentLen,
|
||||
totalLen) native "Internal_prependTypeArguments";
|
||||
|
||||
|
|
|
@ -176,7 +176,6 @@ class _InvocationMirror implements Invocation {
|
|||
this._positionalArguments, this._namedArguments, this._isSuperInvocation,
|
||||
[this._delayedTypeArgumentsLen = 0]);
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
static _allocateInvocationMirror(String functionName,
|
||||
List argumentsDescriptor, List arguments, bool isSuperInvocation,
|
||||
[int type = null]) {
|
||||
|
@ -189,7 +188,6 @@ class _InvocationMirror implements Invocation {
|
|||
// indicate 0 type arguments, but the actual number of type arguments are
|
||||
// passed in `delayedTypeArgumentsLen`. If any type arguments are available,
|
||||
// the type arguments vector will be the first entry in `arguments`.
|
||||
@pragma("vm.entry-point")
|
||||
static _allocateInvocationMirrorForClosure(
|
||||
String functionName,
|
||||
List argumentsDescriptor,
|
||||
|
|
|
@ -106,7 +106,6 @@ void _isolateScheduleImmediate(void callback()) {
|
|||
_pendingImmediateCallback = callback;
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
void _runPendingImmediateCallback() {
|
||||
if (_pendingImmediateCallback != null) {
|
||||
var callback = _pendingImmediateCallback;
|
||||
|
@ -123,7 +122,6 @@ _ImmediateCallback _removePendingImmediateCallback() {
|
|||
|
||||
/// The embedder can execute this function to get hold of
|
||||
/// [_isolateScheduleImmediate] above.
|
||||
@pragma("vm.entry-point")
|
||||
Function _getIsolateScheduleImmediateClosure() {
|
||||
return _isolateScheduleImmediate;
|
||||
}
|
||||
|
@ -154,14 +152,12 @@ class _RawReceivePortImpl implements RawReceivePort {
|
|||
_get_sendport() native "RawReceivePortImpl_get_sendport";
|
||||
|
||||
// Called from the VM to retrieve the handler for a message.
|
||||
@pragma("vm.entry-point")
|
||||
static _lookupHandler(int id) {
|
||||
var result = _handlerMap[id];
|
||||
return result;
|
||||
}
|
||||
|
||||
// Called from the VM to dispatch to the handler.
|
||||
@pragma("vm.entry-point")
|
||||
static void _handleMessage(Function handler, var message) {
|
||||
// TODO(floitsch): this relies on the fact that any exception aborts the
|
||||
// VM. Once we have non-fatal global exceptions we need to catch errors
|
||||
|
@ -194,7 +190,6 @@ class _RawReceivePortImpl implements RawReceivePort {
|
|||
|
||||
class _SendPortImpl implements SendPort {
|
||||
/*--- public interface ---*/
|
||||
@pragma("vm.entry-point")
|
||||
void send(var message) {
|
||||
_sendInternal(message);
|
||||
}
|
||||
|
@ -224,7 +219,6 @@ typedef _BinaryFunction(Null args, Null message);
|
|||
* initial message. Defers execution of the entry point until the
|
||||
* isolate is in the message loop.
|
||||
*/
|
||||
@pragma("vm.entry-point")
|
||||
void _startMainIsolate(Function entryPoint, List<String> args) {
|
||||
_startIsolate(
|
||||
null, // no parent port
|
||||
|
@ -240,7 +234,6 @@ void _startMainIsolate(Function entryPoint, List<String> args) {
|
|||
* Takes the real entry point as argument and invokes it with the initial
|
||||
* message.
|
||||
*/
|
||||
@pragma("vm.entry-point")
|
||||
void _startIsolate(
|
||||
SendPort parentPort,
|
||||
Function entryPoint,
|
||||
|
|
|
@ -46,7 +46,6 @@ class _LibraryPrefix {
|
|||
var _outstandingLoadRequests = new List<List>();
|
||||
|
||||
// Called from the VM when an outstanding load request has finished.
|
||||
@pragma("vm.entry-point")
|
||||
_completeDeferredLoads() {
|
||||
// Determine which outstanding load requests have completed and complete
|
||||
// their completer (with an error or true). For outstanding load requests
|
||||
|
|
|
@ -11,7 +11,6 @@ class Map<K, V> {
|
|||
// The keys are at position 2*n and are already type checked by the parser
|
||||
// in checked mode.
|
||||
// The values are at position 2*n+1 and are not yet type checked.
|
||||
@pragma("vm.entry-point")
|
||||
factory Map._fromLiteral(List elements) {
|
||||
var map = new LinkedHashMap<K, V>();
|
||||
var len = elements.length;
|
||||
|
|
|
@ -41,7 +41,6 @@ class Object {
|
|||
static String _toString(obj) native "Object_toString";
|
||||
|
||||
@patch
|
||||
@pragma("vm.entry-point")
|
||||
dynamic noSuchMethod(Invocation invocation) {
|
||||
// TODO(regis): Remove temp constructor identifier 'withInvocation'.
|
||||
throw new NoSuchMethodError.withInvocation(this, invocation);
|
||||
|
@ -50,21 +49,16 @@ class Object {
|
|||
@patch
|
||||
Type get runtimeType native "Object_runtimeType";
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
static bool _haveSameRuntimeType(a, b) native "Object_haveSameRuntimeType";
|
||||
|
||||
// Call this function instead of inlining instanceof, thus collecting
|
||||
// type feedback and reducing code size of unoptimized code.
|
||||
@pragma("vm.entry-point")
|
||||
bool _instanceOf(instantiatorTypeArguments, functionTypeArguments, type)
|
||||
native "Object_instanceOf";
|
||||
|
||||
// Group of functions for implementing fast simple instance of.
|
||||
@pragma("vm.entry-point")
|
||||
bool _simpleInstanceOf(type) native "Object_simpleInstanceOf";
|
||||
@pragma("vm.entry-point")
|
||||
bool _simpleInstanceOfTrue(type) => true;
|
||||
@pragma("vm.entry-point")
|
||||
bool _simpleInstanceOfFalse(type) => false;
|
||||
|
||||
// Call this function instead of inlining 'as', thus collecting type
|
||||
|
|
|
@ -21,12 +21,10 @@ class _ScheduleImmediate {
|
|||
static _ScheduleImmediateClosure _closure;
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
void _setScheduleImmediateClosure(_ScheduleImmediateClosure closure) {
|
||||
_ScheduleImmediate._closure = closure;
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
void _ensureScheduleImmediate() {
|
||||
_AsyncRun._scheduleImmediate(_startMicrotaskLoop);
|
||||
}
|
||||
|
|
|
@ -794,7 +794,6 @@ abstract class _StringBase implements String {
|
|||
}
|
||||
|
||||
// Convert single object to string.
|
||||
@pragma("vm.entry-point")
|
||||
static String _interpolateSingle(Object o) {
|
||||
if (o is String) return o;
|
||||
final s = o.toString();
|
||||
|
@ -809,7 +808,6 @@ abstract class _StringBase implements String {
|
|||
* into a result string.
|
||||
* Modifies the input list if it contains non-`String` values.
|
||||
*/
|
||||
@pragma("vm.entry-point")
|
||||
static String _interpolate(final List values) {
|
||||
final numValues = values.length;
|
||||
int totalLength = 0;
|
||||
|
|
|
@ -462,7 +462,6 @@ class _Timer implements Timer {
|
|||
}
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
_setupHooks() {
|
||||
VMLibraryHooks.timerFactory = _Timer._factory;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
||||
@pragma("vm.entry-point")
|
||||
// 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.
|
||||
|
||||
|
@ -37,14 +36,12 @@ import 'dart:math' show Random;
|
|||
@patch
|
||||
class ByteData implements TypedData {
|
||||
@patch
|
||||
@pragma("vm.entry-point")
|
||||
factory ByteData(int length) {
|
||||
final list = new Uint8List(length) as _TypedList;
|
||||
return new _ByteDataView(list, 0, length);
|
||||
}
|
||||
|
||||
// Called directly from C code.
|
||||
@pragma("vm.entry-point")
|
||||
factory ByteData._view(_TypedList typedData, int offsetInBytes, int length) {
|
||||
return new _ByteDataView(typedData, offsetInBytes, length);
|
||||
}
|
||||
|
@ -1903,7 +1900,6 @@ class _ByteBuffer implements ByteBuffer {
|
|||
|
||||
_ByteBuffer(this._data);
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
factory _ByteBuffer._New(data) => new _ByteBuffer(data);
|
||||
|
||||
// Forward calls to _data.
|
||||
|
|
|
@ -156,7 +156,7 @@ class ClassSerializationCluster : public SerializationCluster {
|
|||
s->Write<int32_t>(cls->ptr()->next_field_offset_in_words_);
|
||||
s->Write<int32_t>(cls->ptr()->type_arguments_field_offset_in_words_);
|
||||
s->Write<uint16_t>(cls->ptr()->num_type_arguments_);
|
||||
s->Write<uint16_t>(cls->ptr()->has_pragma_and_num_own_type_arguments_);
|
||||
s->Write<uint16_t>(cls->ptr()->num_own_type_arguments_);
|
||||
s->Write<uint16_t>(cls->ptr()->num_native_fields_);
|
||||
s->WriteTokenPosition(cls->ptr()->token_pos_);
|
||||
s->Write<uint16_t>(cls->ptr()->state_bits_);
|
||||
|
@ -224,7 +224,7 @@ class ClassDeserializationCluster : public DeserializationCluster {
|
|||
}
|
||||
cls->ptr()->type_arguments_field_offset_in_words_ = d->Read<int32_t>();
|
||||
cls->ptr()->num_type_arguments_ = d->Read<uint16_t>();
|
||||
cls->ptr()->has_pragma_and_num_own_type_arguments_ = d->Read<uint16_t>();
|
||||
cls->ptr()->num_own_type_arguments_ = d->Read<uint16_t>();
|
||||
cls->ptr()->num_native_fields_ = d->Read<uint16_t>();
|
||||
cls->ptr()->token_pos_ = d->ReadTokenPosition();
|
||||
cls->ptr()->state_bits_ = d->Read<uint16_t>();
|
||||
|
@ -260,7 +260,7 @@ class ClassDeserializationCluster : public DeserializationCluster {
|
|||
cls->ptr()->next_field_offset_in_words_ = d->Read<int32_t>();
|
||||
cls->ptr()->type_arguments_field_offset_in_words_ = d->Read<int32_t>();
|
||||
cls->ptr()->num_type_arguments_ = d->Read<uint16_t>();
|
||||
cls->ptr()->has_pragma_and_num_own_type_arguments_ = d->Read<uint16_t>();
|
||||
cls->ptr()->num_own_type_arguments_ = d->Read<uint16_t>();
|
||||
cls->ptr()->num_native_fields_ = d->Read<uint16_t>();
|
||||
cls->ptr()->token_pos_ = d->ReadTokenPosition();
|
||||
cls->ptr()->state_bits_ = d->Read<uint16_t>();
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
# Entry points @pragma annotations
|
||||
|
||||
Dart VM precompiler (AOT compiler) performs whole-program optimizations such as
|
||||
tree shaking in order to decrease size of the resulting compiled apps and
|
||||
improve their performance. Such optimizations assume that compiler can see the
|
||||
whole Dart program, and is able to discover and analyze all Dart functions and
|
||||
members which can be potentially executed at run time. While the Dart code is
|
||||
fully available for precompiler, native code of the embedder and native methods
|
||||
are out of reach of the compiler. Such native code can call back to Dart via
|
||||
native Dart API.
|
||||
|
||||
In order to aid precompiler, programmer can explicitly list entry points
|
||||
(roots) - Dart classes and members which are accessed from native code. Note
|
||||
that listing entry points is not optional: as long as program defines native
|
||||
methods which call into Dart, the entry points are required for the correctness
|
||||
of compilation.
|
||||
|
||||
# Pragma annotation
|
||||
|
||||
The annotation `@pragma("vm.entry-point", ...)` can be placed on a class or
|
||||
member to indicate that it may be allocated or invoked directly from native or
|
||||
VM code. The allowed uses of the annotation are as follows.
|
||||
|
||||
## Classes
|
||||
|
||||
Any one of the following forms may be attached to a class:
|
||||
|
||||
```dart
|
||||
@pragma("vm.entry-point")
|
||||
@pragma("vm.entry-point", true/false)
|
||||
@pragma("vm.entry-point", !const bool.formEnvironment("dart.vm.product"))
|
||||
class C { ... }
|
||||
```
|
||||
|
||||
If the second parameter is missing, `null` or `true`, the class will be
|
||||
available for allocation directly from native or VM code.
|
||||
|
||||
## Procedures
|
||||
|
||||
Any one of the following forms may be attached to a procedure (including
|
||||
getters, setters and constructors):
|
||||
|
||||
```dart
|
||||
@pragma("vm.entry-point")
|
||||
@pragma("vm.entry-point", true/false)
|
||||
@pragma("vm.entry-point", !const bool.formEnvironment("dart.vm.product"))
|
||||
void foo() { ... }
|
||||
```
|
||||
|
||||
If the second parameter is missing, `null` or `true`, the procedure will
|
||||
available for lookup and invocation directly from native or VM code. If the
|
||||
procedure is a *generative* constructor, the enclosing class will also be marked
|
||||
for allocation from native or VM code.
|
|
@ -491,6 +491,46 @@ void Precompiler::PrecompileConstructors() {
|
|||
}
|
||||
|
||||
static Dart_QualifiedFunctionName vm_entry_points[] = {
|
||||
// Functions
|
||||
{"dart:async", "::", "_ensureScheduleImmediate"},
|
||||
{"dart:core", "::", "_completeDeferredLoads"},
|
||||
{"dart:core", "::", "identityHashCode"},
|
||||
{"dart:core", "AbstractClassInstantiationError",
|
||||
"AbstractClassInstantiationError._create"},
|
||||
{"dart:core", "ArgumentError", "ArgumentError."},
|
||||
{"dart:core", "ArgumentError", "ArgumentError.value"},
|
||||
{"dart:core", "CyclicInitializationError", "CyclicInitializationError."},
|
||||
{"dart:core", "FallThroughError", "FallThroughError._create"},
|
||||
{"dart:core", "FormatException", "FormatException."},
|
||||
{"dart:core", "NoSuchMethodError", "NoSuchMethodError._withType"},
|
||||
{"dart:core", "NullThrownError", "NullThrownError."},
|
||||
{"dart:core", "OutOfMemoryError", "OutOfMemoryError."},
|
||||
{"dart:core", "RangeError", "RangeError."},
|
||||
{"dart:core", "RangeError", "RangeError.range"},
|
||||
{"dart:core", "StackOverflowError", "StackOverflowError."},
|
||||
{"dart:core", "UnsupportedError", "UnsupportedError."},
|
||||
{"dart:core", "_AssertionError", "_AssertionError._create"},
|
||||
{"dart:core", "_CastError", "_CastError._create"},
|
||||
{"dart:core", "_InternalError", "_InternalError."},
|
||||
{"dart:core", "_InvocationMirror", "_allocateInvocationMirror"},
|
||||
{"dart:core", "_InvocationMirror", "_allocateInvocationMirrorForClosure"},
|
||||
{"dart:core", "_TypeError", "_TypeError._create"},
|
||||
{"dart:collection", "::", "_rehashObjects"},
|
||||
{"dart:isolate", "IsolateSpawnException", "IsolateSpawnException."},
|
||||
{"dart:isolate", "::", "_runPendingImmediateCallback"},
|
||||
{"dart:isolate", "::", "_startIsolate"},
|
||||
{"dart:isolate", "_RawReceivePortImpl", "_handleMessage"},
|
||||
{"dart:isolate", "_RawReceivePortImpl", "_lookupHandler"},
|
||||
{"dart:isolate", "_SendPortImpl", "send"},
|
||||
{"dart:typed_data", "ByteData", "ByteData."},
|
||||
{"dart:typed_data", "ByteData", "ByteData._view"},
|
||||
{"dart:typed_data", "_ByteBuffer", "_ByteBuffer._New"},
|
||||
{"dart:_vmservice", "::", "boot"},
|
||||
#if !defined(PRODUCT)
|
||||
{"dart:_vmservice", "::", "_registerIsolate"},
|
||||
{"dart:developer", "Metrics", "_printMetrics"},
|
||||
{"dart:developer", "::", "_runExtension"},
|
||||
#endif // !PRODUCT
|
||||
// Fields
|
||||
{"dart:core", "Error", "_stackTrace"},
|
||||
{"dart:core", "::", "_uriBaseClosure"},
|
||||
|
@ -1468,7 +1508,7 @@ void Precompiler::AddInstantiatedClass(const Class& cls) {
|
|||
}
|
||||
}
|
||||
|
||||
// Adds all values annotated with @pragma('vm.entry-point') as roots.
|
||||
// Adds all values annotated with @pragma('vm.entry_point') as roots.
|
||||
void Precompiler::AddAnnotatedRoots() {
|
||||
auto& lib = Library::Handle(Z);
|
||||
auto& cls = Class::Handle(isolate()->object_store()->pragma_class());
|
||||
|
@ -1481,48 +1521,38 @@ void Precompiler::AddAnnotatedRoots() {
|
|||
auto& pragma_options_field =
|
||||
Field::Handle(Z, cls.LookupField(Symbols::options()));
|
||||
|
||||
// Local function allows easy reuse of handles above.
|
||||
auto metadata_defines_entrypoint = [&]() {
|
||||
bool is_entry_point = false;
|
||||
for (intptr_t i = 0; i < metadata.Length(); i++) {
|
||||
pragma = metadata.At(i);
|
||||
if (pragma.clazz() != isolate()->object_store()->pragma_class()) {
|
||||
continue;
|
||||
}
|
||||
if (Instance::Cast(pragma).GetField(pragma_name_field) !=
|
||||
Symbols::vm_entry_point().raw()) {
|
||||
continue;
|
||||
}
|
||||
pragma_options = Instance::Cast(pragma).GetField(pragma_options_field);
|
||||
if (pragma_options.raw() == Bool::null() ||
|
||||
pragma_options.raw() == Bool::True().raw()) {
|
||||
is_entry_point = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return is_entry_point;
|
||||
};
|
||||
|
||||
for (intptr_t i = 0; i < libraries_.Length(); i++) {
|
||||
lib ^= libraries_.At(i);
|
||||
ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
|
||||
while (it.HasNext()) {
|
||||
cls = it.GetNextClass();
|
||||
|
||||
if (cls.has_pragma()) {
|
||||
metadata ^= lib.GetMetadata(cls);
|
||||
if (metadata_defines_entrypoint()) {
|
||||
AddInstantiatedClass(cls);
|
||||
}
|
||||
}
|
||||
|
||||
functions = cls.functions();
|
||||
for (intptr_t k = 0; k < functions.Length(); k++) {
|
||||
function ^= functions.At(k);
|
||||
if (!function.has_pragma()) continue;
|
||||
metadata ^= lib.GetMetadata(function);
|
||||
if (metadata.IsNull()) continue;
|
||||
if (!metadata_defines_entrypoint()) continue;
|
||||
|
||||
bool is_entry_point = false;
|
||||
for (intptr_t i = 0; i < metadata.Length(); i++) {
|
||||
pragma = metadata.At(i);
|
||||
if (pragma.clazz() != isolate()->object_store()->pragma_class()) {
|
||||
continue;
|
||||
}
|
||||
if (Instance::Cast(pragma).GetField(pragma_name_field) !=
|
||||
Symbols::vm_entry_point().raw()) {
|
||||
continue;
|
||||
}
|
||||
pragma_options =
|
||||
Instance::Cast(pragma).GetField(pragma_options_field);
|
||||
if (pragma_options.raw() == Bool::null() ||
|
||||
pragma_options.raw() == Bool::True().raw()) {
|
||||
is_entry_point = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_entry_point) continue;
|
||||
|
||||
AddFunction(function);
|
||||
if (function.IsGenerativeConstructor()) {
|
||||
|
|
|
@ -1633,7 +1633,7 @@ TEST_CASE(IsolateReload_TearOff_Parameter_Count_Mismatch) {
|
|||
"Tried calling: C.foo()\n"
|
||||
"Found: C.foo(dynamic) => dynamic\n"
|
||||
"#0 Object.noSuchMethod "
|
||||
"(dart:core/runtime/libobject_patch.dart:47:5)\n"
|
||||
"(dart:core/runtime/libobject_patch.dart:46:5)\n"
|
||||
"#1 main (file:///test-lib:8:12)";
|
||||
} else {
|
||||
error =
|
||||
|
@ -1643,7 +1643,7 @@ TEST_CASE(IsolateReload_TearOff_Parameter_Count_Mismatch) {
|
|||
"Tried calling: C.foo()\n"
|
||||
"Found: C.foo(dynamic) => dynamic\n"
|
||||
"#0 Object.noSuchMethod "
|
||||
"(dart:core-patch/dart:core/object_patch.dart:47)\n"
|
||||
"(dart:core-patch/dart:core/object_patch.dart:46)\n"
|
||||
"#1 main (test-lib:8:12)";
|
||||
}
|
||||
EXPECT_ERROR(error_handle, error);
|
||||
|
|
|
@ -1102,17 +1102,7 @@ Class& KernelLoader::LoadClass(const Library& library,
|
|||
class_helper.ReadUntilIncluding(ClassHelper::kFlags);
|
||||
if (class_helper.is_enum_class()) klass.set_is_enum_class();
|
||||
|
||||
class_helper.ReadUntilExcluding(ClassHelper::kAnnotations);
|
||||
intptr_t annotation_count = helper_.ReadListLength();
|
||||
bool has_pragma_annotation = false;
|
||||
{
|
||||
String& native_name_unused = String::Handle(Z);
|
||||
bool is_potential_native_unused = false;
|
||||
ReadVMAnnotations(annotation_count, &native_name_unused,
|
||||
&is_potential_native_unused, &has_pragma_annotation);
|
||||
}
|
||||
klass.set_has_pragma(has_pragma_annotation);
|
||||
class_helper.SetJustRead(ClassHelper::kAnnotations);
|
||||
class_helper.ReadUntilIncluding(ClassHelper::kAnnotations);
|
||||
class_helper.ReadUntilExcluding(ClassHelper::kTypeParameters);
|
||||
intptr_t type_parameter_counts =
|
||||
helper_.ReadListLength(); // read type_parameters list length.
|
||||
|
@ -1128,7 +1118,7 @@ Class& KernelLoader::LoadClass(const Library& library,
|
|||
class_helper.SetJustRead(ClassHelper::kTypeParameters);
|
||||
}
|
||||
|
||||
if ((FLAG_enable_mirrors || has_pragma_annotation) && annotation_count > 0) {
|
||||
if (FLAG_enable_mirrors && class_helper.annotation_count_ > 0) {
|
||||
library.AddClassMetadata(klass, toplevel_class, TokenPosition::kNoSource,
|
||||
class_offset - correction_offset_);
|
||||
}
|
||||
|
@ -1228,16 +1218,6 @@ void KernelLoader::FinishClassLoading(const Class& klass,
|
|||
intptr_t constructor_offset = helper_.ReaderOffset() - correction_offset_;
|
||||
ActiveMemberScope active_member_scope(&active_class_, NULL);
|
||||
ConstructorHelper constructor_helper(&helper_);
|
||||
constructor_helper.ReadUntilExcluding(ConstructorHelper::kAnnotations);
|
||||
intptr_t annotation_count = helper_.ReadListLength();
|
||||
bool has_pragma_annotation;
|
||||
{
|
||||
String& native_name_unused = String::Handle();
|
||||
bool is_potential_native_unused;
|
||||
ReadVMAnnotations(annotation_count, &native_name_unused,
|
||||
&is_potential_native_unused, &has_pragma_annotation);
|
||||
}
|
||||
constructor_helper.SetJustRead(ConstructorHelper::kAnnotations);
|
||||
constructor_helper.ReadUntilExcluding(ConstructorHelper::kFunction);
|
||||
|
||||
const String& name =
|
||||
|
@ -1264,7 +1244,6 @@ void KernelLoader::FinishClassLoading(const Class& klass,
|
|||
functions_.Add(&function);
|
||||
function.set_kernel_offset(constructor_offset);
|
||||
function.set_result_type(T.ReceiverType(klass));
|
||||
function.set_has_pragma(has_pragma_annotation);
|
||||
|
||||
FunctionNodeHelper function_node_helper(&helper_);
|
||||
function_node_helper.ReadUntilExcluding(
|
||||
|
@ -1281,8 +1260,7 @@ void KernelLoader::FinishClassLoading(const Class& klass,
|
|||
constructor_helper.SetJustRead(ConstructorHelper::kFunction);
|
||||
constructor_helper.ReadUntilExcluding(ConstructorHelper::kEnd);
|
||||
|
||||
if ((FLAG_enable_mirrors || has_pragma_annotation) &&
|
||||
annotation_count > 0) {
|
||||
if (FLAG_enable_mirrors && constructor_helper.annotation_count_ > 0) {
|
||||
library.AddFunctionMetadata(function, TokenPosition::kNoSource,
|
||||
constructor_offset);
|
||||
}
|
||||
|
@ -1342,18 +1320,18 @@ void KernelLoader::FinishLoading(const Class& klass) {
|
|||
//
|
||||
// Output parameters:
|
||||
//
|
||||
// `native_name`: non-null if `@ExternalName(...)` was identified.
|
||||
// `native_name`: non-null if `ExternalName(<name>)` was identified.
|
||||
//
|
||||
// `is_potential_native`: non-null if there may be an `@ExternalName(...)`
|
||||
// `is_potential_native`: non-null if there may be an `ExternalName`
|
||||
// annotation and we need to re-try after reading the constants table.
|
||||
//
|
||||
// `has_pragma_annotation`: non-null if @pragma(...) was found (no information
|
||||
// is given on the kind of pragma directive).
|
||||
//
|
||||
void KernelLoader::ReadVMAnnotations(intptr_t annotation_count,
|
||||
String* native_name,
|
||||
bool* is_potential_native,
|
||||
bool* has_pragma_annotation) {
|
||||
void KernelLoader::ReadProcedureAnnotations(intptr_t annotation_count,
|
||||
String* native_name,
|
||||
bool* is_potential_native,
|
||||
bool* has_pragma_annotation) {
|
||||
*is_potential_native = false;
|
||||
*has_pragma_annotation = false;
|
||||
String& detected_name = String::Handle(Z);
|
||||
|
@ -1458,8 +1436,8 @@ void KernelLoader::LoadProcedure(const Library& library,
|
|||
bool is_potential_native;
|
||||
bool has_pragma_annotation;
|
||||
const intptr_t annotation_count = helper_.ReadListLength();
|
||||
ReadVMAnnotations(annotation_count, &native_name, &is_potential_native,
|
||||
&has_pragma_annotation);
|
||||
ReadProcedureAnnotations(annotation_count, &native_name, &is_potential_native,
|
||||
&has_pragma_annotation);
|
||||
// If this is a potential native, we'll unset is_external in
|
||||
// AnnotateNativeProcedures instead.
|
||||
is_external = is_external && native_name.IsNull();
|
||||
|
|
|
@ -160,10 +160,10 @@ class KernelLoader : public ValueObject {
|
|||
void AnnotateNativeProcedures(const Array& constant_table);
|
||||
void LoadNativeExtensionLibraries(const Array& constant_table);
|
||||
|
||||
void ReadVMAnnotations(intptr_t annotation_count,
|
||||
String* native_name,
|
||||
bool* is_potential_native,
|
||||
bool* has_pragma_annotation);
|
||||
void ReadProcedureAnnotations(intptr_t annotation_count,
|
||||
String* native_name,
|
||||
bool* is_potential_native,
|
||||
bool* has_pragma_annotation);
|
||||
|
||||
const String& DartSymbolPlain(StringIndex index) {
|
||||
return translation_helper_.DartSymbolPlain(index);
|
||||
|
|
|
@ -571,7 +571,6 @@ void Object::InitOnce(Isolate* isolate) {
|
|||
cls.set_type_arguments_field_offset_in_words(Class::kNoTypeArguments);
|
||||
cls.set_num_type_arguments(0);
|
||||
cls.set_num_own_type_arguments(0);
|
||||
cls.set_has_pragma(false);
|
||||
cls.set_num_native_fields(0);
|
||||
cls.InitEmptyFields();
|
||||
isolate->RegisterClass(cls);
|
||||
|
@ -2192,7 +2191,6 @@ RawClass* Class::New() {
|
|||
result.set_id(FakeObject::kClassId);
|
||||
result.set_num_type_arguments(0);
|
||||
result.set_num_own_type_arguments(0);
|
||||
result.set_has_pragma(false);
|
||||
result.set_num_native_fields(0);
|
||||
result.set_state_bits(0);
|
||||
if ((FakeObject::kClassId < kInstanceCid) ||
|
||||
|
@ -2228,24 +2226,10 @@ void Class::set_num_type_arguments(intptr_t value) const {
|
|||
}
|
||||
|
||||
void Class::set_num_own_type_arguments(intptr_t value) const {
|
||||
if (!Utils::IsUint(kNumOwnTypeArgumentsSize, value)) {
|
||||
if (!Utils::IsInt(16, value)) {
|
||||
ReportTooManyTypeArguments(*this);
|
||||
}
|
||||
StoreNonPointer(
|
||||
&raw_ptr()->has_pragma_and_num_own_type_arguments_,
|
||||
NumOwnTypeArguments::update(
|
||||
value, raw_ptr()->has_pragma_and_num_own_type_arguments_));
|
||||
}
|
||||
|
||||
void Class::set_has_pragma_and_num_own_type_arguments(uint16_t value) const {
|
||||
StoreNonPointer(&raw_ptr()->has_pragma_and_num_own_type_arguments_, value);
|
||||
}
|
||||
|
||||
void Class::set_has_pragma(bool value) const {
|
||||
StoreNonPointer(
|
||||
&raw_ptr()->has_pragma_and_num_own_type_arguments_,
|
||||
HasPragmaBit::update(value,
|
||||
raw_ptr()->has_pragma_and_num_own_type_arguments_));
|
||||
StoreNonPointer(&raw_ptr()->num_own_type_arguments_, value);
|
||||
}
|
||||
|
||||
// Initialize class fields of type Array with empty array.
|
||||
|
@ -3511,7 +3495,6 @@ RawClass* Class::NewCommon(intptr_t index) {
|
|||
result.set_id(index);
|
||||
result.set_num_type_arguments(kUnknownNumTypeArguments);
|
||||
result.set_num_own_type_arguments(kUnknownNumTypeArguments);
|
||||
result.set_has_pragma(false);
|
||||
result.set_num_native_fields(0);
|
||||
result.set_state_bits(0);
|
||||
result.InitEmptyFields();
|
||||
|
|
|
@ -1529,21 +1529,8 @@ class Class : public Object {
|
|||
// functions_hash_table is in use iff there are at least this many functions.
|
||||
static const intptr_t kFunctionLookupHashTreshold = 16;
|
||||
|
||||
enum HasPragmaAndNumOwnTypeArgumentsBits {
|
||||
kHasPragmaBit = 0,
|
||||
kNumOwnTypeArgumentsPos = 1,
|
||||
kNumOwnTypeArgumentsSize = 15
|
||||
};
|
||||
|
||||
class HasPragmaBit : public BitField<uint16_t, bool, kHasPragmaBit, 1> {};
|
||||
class NumOwnTypeArguments : public BitField<uint16_t,
|
||||
uint16_t,
|
||||
kNumOwnTypeArgumentsPos,
|
||||
kNumOwnTypeArgumentsSize> {};
|
||||
|
||||
// Initial value for the cached number of type arguments.
|
||||
static const intptr_t kUnknownNumTypeArguments =
|
||||
(1U << kNumOwnTypeArgumentsSize) - 1;
|
||||
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;
|
||||
|
@ -1551,22 +1538,11 @@ class Class : public Object {
|
|||
return OFFSET_OF(RawClass, num_type_arguments_);
|
||||
}
|
||||
|
||||
public:
|
||||
bool has_pragma() const {
|
||||
return HasPragmaBit::decode(
|
||||
raw_ptr()->has_pragma_and_num_own_type_arguments_);
|
||||
}
|
||||
void set_has_pragma(bool has_pragma) const;
|
||||
|
||||
private:
|
||||
uint16_t num_own_type_arguments() const {
|
||||
return NumOwnTypeArguments::decode(
|
||||
raw_ptr()->has_pragma_and_num_own_type_arguments_);
|
||||
int16_t num_own_type_arguments() const {
|
||||
return raw_ptr()->num_own_type_arguments_;
|
||||
}
|
||||
void set_num_own_type_arguments(intptr_t value) const;
|
||||
|
||||
void set_has_pragma_and_num_own_type_arguments(uint16_t value) const;
|
||||
|
||||
// Assigns empty array to all raw class array fields.
|
||||
void InitEmptyFields();
|
||||
|
||||
|
|
|
@ -4006,7 +4006,6 @@ void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) {
|
|||
method->has_external,
|
||||
method->has_native, // May change.
|
||||
current_class(), method->decl_begin_pos));
|
||||
func.set_has_pragma(IsPragmaAnnotation(method->metadata_pos));
|
||||
|
||||
ASSERT(innermost_function().IsNull());
|
||||
innermost_function_ = func.raw();
|
||||
|
@ -4812,7 +4811,6 @@ void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes,
|
|||
bool is_abstract = false;
|
||||
TokenPosition declaration_pos =
|
||||
metadata_pos.IsReal() ? metadata_pos : TokenPos();
|
||||
const bool is_pragma = IsPragmaAnnotation(metadata_pos);
|
||||
if (is_patch_source() && IsPatchAnnotation(metadata_pos)) {
|
||||
is_patch = true;
|
||||
metadata_pos = TokenPosition::kNoSource;
|
||||
|
@ -4861,9 +4859,6 @@ void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes,
|
|||
cls.set_token_pos(declaration_pos);
|
||||
}
|
||||
}
|
||||
if (is_pragma) {
|
||||
cls.set_has_pragma(true);
|
||||
}
|
||||
ASSERT(!cls.IsNull());
|
||||
ASSERT(cls.functions() == Object::empty_array().raw());
|
||||
set_current_class(cls);
|
||||
|
@ -5579,12 +5574,8 @@ bool Parser::IsPatchAnnotation(TokenPosition pos) {
|
|||
}
|
||||
TokenPosScope saved_pos(this);
|
||||
SetPosition(pos);
|
||||
while (CurrentToken() == Token::kAT) {
|
||||
ConsumeToken();
|
||||
if (IsSymbol(Symbols::Patch())) return true;
|
||||
SkipOneMetadata();
|
||||
}
|
||||
return false;
|
||||
ExpectToken(Token::kAT);
|
||||
return IsSymbol(Symbols::Patch());
|
||||
}
|
||||
|
||||
bool Parser::IsPragmaAnnotation(TokenPosition pos) {
|
||||
|
@ -5593,27 +5584,8 @@ bool Parser::IsPragmaAnnotation(TokenPosition pos) {
|
|||
}
|
||||
TokenPosScope saved_pos(this);
|
||||
SetPosition(pos);
|
||||
while (CurrentToken() == Token::kAT) {
|
||||
ConsumeToken();
|
||||
if (IsSymbol(Symbols::Pragma())) return true;
|
||||
SkipOneMetadata();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Parser::SkipOneMetadata() {
|
||||
ExpectIdentifier("identifier expected");
|
||||
if (CurrentToken() == Token::kPERIOD) {
|
||||
ConsumeToken();
|
||||
ExpectIdentifier("identifier expected");
|
||||
if (CurrentToken() == Token::kPERIOD) {
|
||||
ConsumeToken();
|
||||
ExpectIdentifier("identifier expected");
|
||||
}
|
||||
}
|
||||
if (CurrentToken() == Token::kLPAREN) {
|
||||
SkipToMatchingParenthesis();
|
||||
}
|
||||
ExpectToken(Token::kAT);
|
||||
return IsSymbol(Symbols::Pragma());
|
||||
}
|
||||
|
||||
TokenPosition Parser::SkipMetadata() {
|
||||
|
@ -5623,7 +5595,18 @@ TokenPosition Parser::SkipMetadata() {
|
|||
TokenPosition metadata_pos = TokenPos();
|
||||
while (CurrentToken() == Token::kAT) {
|
||||
ConsumeToken();
|
||||
SkipOneMetadata();
|
||||
ExpectIdentifier("identifier expected");
|
||||
if (CurrentToken() == Token::kPERIOD) {
|
||||
ConsumeToken();
|
||||
ExpectIdentifier("identifier expected");
|
||||
if (CurrentToken() == Token::kPERIOD) {
|
||||
ConsumeToken();
|
||||
ExpectIdentifier("identifier expected");
|
||||
}
|
||||
}
|
||||
if (CurrentToken() == Token::kLPAREN) {
|
||||
SkipToMatchingParenthesis();
|
||||
}
|
||||
}
|
||||
return metadata_pos;
|
||||
}
|
||||
|
|
|
@ -412,7 +412,6 @@ class Parser : public ValueObject {
|
|||
void SkipToMatching();
|
||||
void SkipToMatchingParenthesis();
|
||||
void SkipBlock();
|
||||
void SkipOneMetadata();
|
||||
TokenPosition SkipMetadata();
|
||||
bool IsPatchAnnotation(TokenPosition pos);
|
||||
bool IsPragmaAnnotation(TokenPosition pos);
|
||||
|
|
|
@ -789,12 +789,8 @@ class RawClass : public RawObject {
|
|||
int32_t next_field_offset_in_words_; // Offset of the next instance field.
|
||||
classid_t id_; // Class Id, also index in the class table.
|
||||
int16_t num_type_arguments_; // Number of type arguments in flattened vector.
|
||||
|
||||
// Bitfields with number of non-overlapping type arguments and 'has_pragma'
|
||||
// bit.
|
||||
uint16_t has_pragma_and_num_own_type_arguments_;
|
||||
|
||||
uint16_t num_native_fields_;
|
||||
int16_t num_own_type_arguments_; // Number of non-overlapping type arguments.
|
||||
uint16_t num_native_fields_; // Number of native fields in class.
|
||||
uint16_t state_bits_;
|
||||
NOT_IN_PRECOMPILED(intptr_t kernel_offset_);
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ RawClass* Class::ReadFrom(SnapshotReader* reader,
|
|||
}
|
||||
cls.set_type_arguments_field_offset_in_words(reader->Read<int32_t>());
|
||||
cls.set_num_type_arguments(reader->Read<int16_t>());
|
||||
cls.set_has_pragma_and_num_own_type_arguments(reader->Read<int16_t>());
|
||||
cls.set_num_own_type_arguments(reader->Read<int16_t>());
|
||||
cls.set_num_native_fields(reader->Read<uint16_t>());
|
||||
cls.set_token_pos(TokenPosition::SnapshotDecode(reader->Read<int32_t>()));
|
||||
cls.set_state_bits(reader->Read<uint16_t>());
|
||||
|
@ -114,7 +114,7 @@ void RawClass::WriteTo(SnapshotWriter* writer,
|
|||
}
|
||||
writer->Write<int32_t>(ptr()->type_arguments_field_offset_in_words_);
|
||||
writer->Write<uint16_t>(ptr()->num_type_arguments_);
|
||||
writer->Write<uint16_t>(ptr()->has_pragma_and_num_own_type_arguments_);
|
||||
writer->Write<uint16_t>(ptr()->num_own_type_arguments_);
|
||||
writer->Write<uint16_t>(ptr()->num_native_fields_);
|
||||
writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
|
||||
writer->Write<uint16_t>(ptr()->state_bits_);
|
||||
|
|
|
@ -458,7 +458,7 @@ class ObjectPointerVisitor;
|
|||
V(GrowRegExpStack, "_growRegExpStack") \
|
||||
V(DebugProcedureName, ":Eval") \
|
||||
V(DebugClassName, "#DebugClass") \
|
||||
V(vm_entry_point, "vm.entry-point")
|
||||
V(vm_entry_point, "vm.entry_point")
|
||||
|
||||
// Contains a list of frequently used strings in a canonicalized form. This
|
||||
// list is kept in the vm_isolate in order to share the copy across isolates
|
||||
|
|
|
@ -46,7 +46,6 @@ part of dart.cli;
|
|||
*/
|
||||
external void _waitForEvent(int timeoutMillis);
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
void Function(int) _getWaitForEvent() => _waitForEvent;
|
||||
|
||||
// This should be set from C++ code by the embedder to wire up waitFor() to the
|
||||
|
|
|
@ -248,7 +248,7 @@ const Object proxy = const _Proxy();
|
|||
* function foo is annotated with a pragma 'other-pragma' specific to OtherTool.
|
||||
*
|
||||
*/
|
||||
@pragma('vm.entry-point')
|
||||
@pragma('vm.entry_point')
|
||||
class pragma {
|
||||
/**
|
||||
* The name of the hint.
|
||||
|
|
|
@ -116,8 +116,6 @@ class CastError extends Error {}
|
|||
* Error thrown when attempting to throw [:null:].
|
||||
*/
|
||||
class NullThrownError extends Error {
|
||||
@pragma("vm.entry-point")
|
||||
NullThrownError();
|
||||
String toString() => "Throw of null.";
|
||||
}
|
||||
|
||||
|
@ -141,7 +139,6 @@ class ArgumentError extends Error {
|
|||
* If the `message` is not a [String], it is assumed to be a value instead
|
||||
* of a message.
|
||||
*/
|
||||
@pragma("vm.entry-point")
|
||||
ArgumentError([this.message])
|
||||
: invalidValue = null,
|
||||
_hasValue = false,
|
||||
|
@ -160,7 +157,6 @@ class ArgumentError extends Error {
|
|||
* names differ from the interface, it might be more useful to use the
|
||||
* interface method's argument name (or just rename arguments to match).
|
||||
*/
|
||||
@pragma("vm.entry-point")
|
||||
ArgumentError.value(value, [this.name, this.message])
|
||||
: invalidValue = value,
|
||||
_hasValue = true;
|
||||
|
@ -206,7 +202,6 @@ class RangeError extends ArgumentError {
|
|||
/**
|
||||
* Create a new [RangeError] with the given [message].
|
||||
*/
|
||||
@pragma("vm.entry-point")
|
||||
RangeError(var message)
|
||||
: start = null,
|
||||
end = null,
|
||||
|
@ -239,7 +234,6 @@ class RangeError extends ArgumentError {
|
|||
* invalid value, and the [message] can override the default error
|
||||
* description.
|
||||
*/
|
||||
@pragma("vm.entry-point")
|
||||
RangeError.range(num invalidValue, int minValue, int maxValue,
|
||||
[String name, String message])
|
||||
: start = minValue,
|
||||
|
@ -417,7 +411,6 @@ class IndexError extends ArgumentError implements RangeError {
|
|||
*/
|
||||
class FallThroughError extends Error {
|
||||
FallThroughError();
|
||||
@pragma("vm.entry-point")
|
||||
external FallThroughError._create(String url, int line);
|
||||
|
||||
external String toString();
|
||||
|
@ -488,7 +481,6 @@ class NoSuchMethodError extends Error {
|
|||
*/
|
||||
class UnsupportedError extends Error {
|
||||
final String message;
|
||||
@pragma("vm.entry-point")
|
||||
UnsupportedError(this.message);
|
||||
String toString() => "Unsupported operation: $message";
|
||||
}
|
||||
|
@ -546,7 +538,6 @@ class ConcurrentModificationError extends Error {
|
|||
}
|
||||
|
||||
class OutOfMemoryError implements Error {
|
||||
@pragma("vm.entry-point")
|
||||
const OutOfMemoryError();
|
||||
String toString() => "Out of Memory";
|
||||
|
||||
|
@ -554,7 +545,6 @@ class OutOfMemoryError implements Error {
|
|||
}
|
||||
|
||||
class StackOverflowError implements Error {
|
||||
@pragma("vm.entry-point")
|
||||
const StackOverflowError();
|
||||
String toString() => "Stack Overflow";
|
||||
|
||||
|
@ -570,7 +560,6 @@ class StackOverflowError implements Error {
|
|||
*/
|
||||
class CyclicInitializationError extends Error {
|
||||
final String variableName;
|
||||
@pragma("vm.entry-point")
|
||||
CyclicInitializationError([this.variableName]);
|
||||
String toString() => variableName == null
|
||||
? "Reading static variable during its initialization"
|
||||
|
|
|
@ -74,7 +74,6 @@ class FormatException implements Exception {
|
|||
* Optionally also supply the actual [source] with the incorrect format,
|
||||
* and the [offset] in the format where a problem was detected.
|
||||
*/
|
||||
@pragma("vm.entry-point")
|
||||
const FormatException([this.message = "", this.source, this.offset]);
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,5 +18,4 @@ external bool identical(Object a, Object b);
|
|||
*
|
||||
* This hash code is compatible with [identical].
|
||||
*/
|
||||
@pragma("vm.entry-point")
|
||||
external int identityHashCode(Object object);
|
||||
|
|
|
@ -104,7 +104,6 @@ class Object {
|
|||
*
|
||||
* The default behavior is to throw a [NoSuchMethodError].
|
||||
*/
|
||||
@pragma("vm.entry-point")
|
||||
external dynamic noSuchMethod(Invocation invocation);
|
||||
|
||||
/**
|
||||
|
|
|
@ -144,7 +144,6 @@ class Metrics {
|
|||
}
|
||||
|
||||
// ignore: unused_element, called from native code
|
||||
@pragma("vm.entry-point", !const bool.fromEnvironment("dart.vm.product"))
|
||||
static String _printMetrics() {
|
||||
var metrics = [];
|
||||
for (var metric in _metrics.values) {
|
||||
|
|
|
@ -64,7 +64,6 @@ class OSError {
|
|||
final int errorCode;
|
||||
|
||||
/** Creates an OSError object from a message and an errorCode. */
|
||||
@pragma("vm.entry-point")
|
||||
const OSError([this.message = "", this.errorCode = noErrorCode]);
|
||||
|
||||
/** Converts an OSError object to a string representation. */
|
||||
|
|
|
@ -126,7 +126,6 @@ abstract class Directory implements FileSystemEntity {
|
|||
* If [path] is an absolute path, it will be immune to changes to the
|
||||
* current working directory.
|
||||
*/
|
||||
@pragma("vm.entry-point")
|
||||
factory Directory(String path) {
|
||||
final IOOverrides overrides = IOOverrides.current;
|
||||
if (overrides == null) {
|
||||
|
|
|
@ -247,7 +247,6 @@ abstract class File implements FileSystemEntity {
|
|||
* If [path] is an absolute path, it will be immune to changes to the
|
||||
* current working directory.
|
||||
*/
|
||||
@pragma("vm.entry-point")
|
||||
factory File(String path) {
|
||||
final IOOverrides overrides = IOOverrides.current;
|
||||
if (overrides == null) {
|
||||
|
@ -980,7 +979,6 @@ class FileSystemException implements IOException {
|
|||
* [message], optional file system path [path] and optional OS error
|
||||
* [osError].
|
||||
*/
|
||||
@pragma("vm.entry-point")
|
||||
const FileSystemException([this.message = "", this.path = "", this.osError]);
|
||||
|
||||
String toString() {
|
||||
|
|
|
@ -12,7 +12,6 @@ abstract class Link implements FileSystemEntity {
|
|||
/**
|
||||
* Creates a Link object.
|
||||
*/
|
||||
@pragma("vm.entry-point")
|
||||
factory Link(String path) {
|
||||
final IOOverrides overrides = IOOverrides.current;
|
||||
if (overrides == null) {
|
||||
|
|
|
@ -19,6 +19,5 @@ abstract class _Namespace {
|
|||
// If it is not set up by the embedder, relative paths will be resolved
|
||||
// relative to the process's current working directory and absolute paths will
|
||||
// be left relative to the file system root.
|
||||
@pragma("vm.entry-point")
|
||||
external static void _setupNamespace(var namespace);
|
||||
}
|
||||
|
|
|
@ -378,7 +378,6 @@ abstract class RawSecureSocket implements RawSocket {
|
|||
* get the fields of the certificate.
|
||||
*/
|
||||
abstract class X509Certificate {
|
||||
@pragma("vm.entry-point")
|
||||
external factory X509Certificate._();
|
||||
|
||||
/// The DER encoded bytes of the certificate.
|
||||
|
@ -1257,7 +1256,6 @@ class TlsException implements IOException {
|
|||
final String message;
|
||||
final OSError osError;
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
const TlsException([String message = "", OSError osError = null])
|
||||
: this._("TlsException", message, osError);
|
||||
|
||||
|
@ -1283,7 +1281,6 @@ class TlsException implements IOException {
|
|||
* a secure network connection.
|
||||
*/
|
||||
class HandshakeException extends TlsException {
|
||||
@pragma("vm.entry-point")
|
||||
const HandshakeException([String message = "", OSError osError = null])
|
||||
: super._("HandshakeException", message, osError);
|
||||
}
|
||||
|
@ -1294,7 +1291,6 @@ class HandshakeException extends TlsException {
|
|||
* certificate.
|
||||
*/
|
||||
class CertificateException extends TlsException {
|
||||
@pragma("vm.entry-point")
|
||||
const CertificateException([String message = "", OSError osError = null])
|
||||
: super._("CertificateException", message, osError);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ part "capability.dart";
|
|||
class IsolateSpawnException implements Exception {
|
||||
/** Error message reported by the spawn operation. */
|
||||
final String message;
|
||||
@pragma("vm.entry-point")
|
||||
IsolateSpawnException(this.message);
|
||||
String toString() => "IsolateSpawnException: $message";
|
||||
}
|
||||
|
|
|
@ -455,7 +455,6 @@ abstract class ByteData implements TypedData {
|
|||
* Creates a [ByteData] of the specified length (in elements), all of
|
||||
* whose bytes are initially zero.
|
||||
*/
|
||||
@pragma("vm.entry-point")
|
||||
external factory ByteData(int length);
|
||||
|
||||
/**
|
||||
|
|
|
@ -696,13 +696,11 @@ class VMService extends MessageRouter {
|
|||
}
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point")
|
||||
RawReceivePort boot() {
|
||||
// Return the port we expect isolate control messages on.
|
||||
return isolateControlPort;
|
||||
}
|
||||
|
||||
@pragma("vm.entry-point", !const bool.fromEnvironment("dart.vm.product"))
|
||||
void _registerIsolate(int port_id, SendPort sp, String name) {
|
||||
var service = new VMService();
|
||||
service.runningIsolates.isolateStartup(port_id, sp, name);
|
||||
|
|
|
@ -41,6 +41,8 @@ void main(List<String> args) {
|
|||
'$buildDir/gen/runtime/bin/precompiler_entry_points.json',
|
||||
'--entry-points',
|
||||
'pkg/vm/lib/transformations/type_flow/entry_points_extra.json',
|
||||
'--entry-points',
|
||||
'pkg/vm/lib/transformations/type_flow/entry_points_extra_standalone.json',
|
||||
scriptPath,
|
||||
];
|
||||
runSync("pkg/vm/tool/gen_kernel${Platform.isWindows ? '.bat' : ''}", args);
|
||||
|
|
|
@ -1036,6 +1036,8 @@ abstract class VMKernelCompilerMixin {
|
|||
'${_configuration.buildDirectory}/gen/runtime/bin/precompiler_entry_points.json',
|
||||
'--entry-points',
|
||||
'${pkgVmDir}/lib/transformations/type_flow/entry_points_extra.json',
|
||||
'--entry-points',
|
||||
'${pkgVmDir}/lib/transformations/type_flow/entry_points_extra_standalone.json',
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue