[vm,dyn_modules] Support pragmas on local functions in bytecode
Pragmas on local functions are used internally by FFI. TEST=ci Change-Id: I3ffb9984d8fcd943b22a98746faa915b2ce7c9fa Cq-Include-Trybots: luci.dart.try:vm-aot-dyn-linux-debug-x64-try,vm-aot-dyn-linux-product-x64-try,vm-dyn-linux-debug-x64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/446121 Reviewed-by: Tess Strickland <sstrickl@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
committed by
Commit Queue
parent
6157e8d741
commit
a3038b85f8
@@ -647,7 +647,7 @@ type ClosureDeclaration {
|
||||
UInt flags = (hasOptionalPositionalParams, hasOptionalNamedParams,
|
||||
hasTypeParams, hasSourcePositions,
|
||||
isAsync, isAsyncStar, isSyncStar, isDebuggable,
|
||||
hasParameterFlags)
|
||||
hasParameterFlags, hasAnnotations, hasPragma)
|
||||
|
||||
// Member or Closure.
|
||||
PackedObject parent;
|
||||
@@ -672,6 +672,11 @@ type ClosureDeclaration {
|
||||
List<UInt> parameterFlags;
|
||||
|
||||
PackedObject returnType;
|
||||
|
||||
if hasAnnotations
|
||||
// Offset of closure annotations in ‘annotations’ section of
|
||||
// component, followed by parameter annotations.
|
||||
UInt annotationsOffset;
|
||||
}
|
||||
|
||||
type ClosureCode {
|
||||
|
||||
@@ -403,23 +403,22 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
// section. Return the annotations for the function only. The bytecode reader
|
||||
// will implicitly find the parameter annotations by reading N packed objects
|
||||
// after reading the function's annotations, one for each parameter.
|
||||
Annotations getFunctionAnnotations(Member member) {
|
||||
final functionNodes = member.annotations;
|
||||
Annotations getFunctionAnnotations(
|
||||
List<Expression> annotations, FunctionNode function) {
|
||||
final parameterNodeLists = <List<Expression>>[];
|
||||
for (VariableDeclaration variable
|
||||
in member.function!.positionalParameters) {
|
||||
for (VariableDeclaration variable in function.positionalParameters) {
|
||||
parameterNodeLists.add(variable.annotations);
|
||||
}
|
||||
for (VariableDeclaration variable in member.function!.namedParameters) {
|
||||
for (VariableDeclaration variable in function.namedParameters) {
|
||||
parameterNodeLists.add(variable.annotations);
|
||||
}
|
||||
|
||||
if (functionNodes.isEmpty &&
|
||||
if (annotations.isEmpty &&
|
||||
parameterNodeLists.every((nodes) => nodes.isEmpty)) {
|
||||
return const Annotations(null, false);
|
||||
}
|
||||
|
||||
List<Constant> functionConstants = functionNodes.map(_getConstant).toList();
|
||||
List<Constant> functionConstants = annotations.map(_getConstant).toList();
|
||||
bool hasPragma = functionConstants.any(_isPragma);
|
||||
if (!options.emitAnnotations && !hasPragma) {
|
||||
return const Annotations(null, false);
|
||||
@@ -677,7 +676,8 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
}
|
||||
endPosition = member.fileEndOffset;
|
||||
}
|
||||
final Annotations annotations = getFunctionAnnotations(member);
|
||||
final Annotations annotations =
|
||||
getFunctionAnnotations(member.annotations, function);
|
||||
if (annotations.object != null) {
|
||||
flags |= FunctionDeclaration.hasAnnotationsFlag;
|
||||
if (annotations.hasPragma) {
|
||||
@@ -2548,6 +2548,18 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
flags |= ClosureDeclaration.hasParameterFlagsFlag;
|
||||
}
|
||||
|
||||
final Annotations annotations = getFunctionAnnotations(
|
||||
node is ast.FunctionDeclaration
|
||||
? node.variable.annotations
|
||||
: const <Expression>[],
|
||||
function);
|
||||
if (annotations.object != null) {
|
||||
flags |= ClosureDeclaration.hasAnnotationsFlag;
|
||||
if (annotations.hasPragma) {
|
||||
flags |= ClosureDeclaration.hasPragmaFlag;
|
||||
}
|
||||
}
|
||||
|
||||
return new ClosureDeclaration(
|
||||
flags,
|
||||
objectTable.getHandle(parent)!,
|
||||
@@ -2559,7 +2571,8 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
function.namedParameters.length,
|
||||
parameters,
|
||||
parameterFlags,
|
||||
objectTable.getHandle(function.returnType)!);
|
||||
objectTable.getHandle(function.returnType)!,
|
||||
annotations.object);
|
||||
}
|
||||
|
||||
void _genAllocateClosureInstance(
|
||||
|
||||
@@ -947,6 +947,8 @@ class ClosureDeclaration {
|
||||
static const isSyncStarFlag = 1 << 6;
|
||||
static const isDebuggableFlag = 1 << 7;
|
||||
static const hasParameterFlagsFlag = 1 << 8;
|
||||
static const hasAnnotationsFlag = 1 << 9;
|
||||
static const hasPragmaFlag = 1 << 10;
|
||||
|
||||
int flags;
|
||||
final ObjectHandle parent;
|
||||
@@ -960,6 +962,7 @@ class ClosureDeclaration {
|
||||
// Only contains the required flag for named parameters when present.
|
||||
final List<int>? parameterFlags;
|
||||
final ObjectHandle returnType;
|
||||
final AnnotationsDeclaration? annotations;
|
||||
ClosureCode? code;
|
||||
|
||||
ClosureDeclaration(
|
||||
@@ -973,7 +976,8 @@ class ClosureDeclaration {
|
||||
this.numNamedParams,
|
||||
this.parameters,
|
||||
this.parameterFlags,
|
||||
this.returnType);
|
||||
this.returnType,
|
||||
this.annotations);
|
||||
|
||||
void write(BufferedWriter writer) {
|
||||
writer.writePackedUInt30(flags);
|
||||
@@ -1006,6 +1010,9 @@ class ClosureDeclaration {
|
||||
}
|
||||
}
|
||||
writer.writePackedObject(returnType);
|
||||
if ((flags & hasAnnotationsFlag) != 0) {
|
||||
writer.writeLinkOffset(annotations!);
|
||||
}
|
||||
}
|
||||
|
||||
factory ClosureDeclaration.read(BufferedReader reader) {
|
||||
@@ -1043,6 +1050,9 @@ class ClosureDeclaration {
|
||||
numParameterFlags, (_) => reader.readPackedUInt30());
|
||||
}
|
||||
final ObjectHandle returnType = reader.readPackedObject();
|
||||
final annotations = ((flags & hasAnnotationsFlag) != 0)
|
||||
? reader.readLinkOffset<AnnotationsDeclaration>()
|
||||
: null;
|
||||
return new ClosureDeclaration(
|
||||
flags,
|
||||
parent,
|
||||
@@ -1054,7 +1064,8 @@ class ClosureDeclaration {
|
||||
numNamedParams,
|
||||
parameters,
|
||||
parameterFlags,
|
||||
returnType);
|
||||
returnType,
|
||||
annotations);
|
||||
}
|
||||
|
||||
void _writeParamsToBuffer(
|
||||
@@ -1088,6 +1099,9 @@ class ClosureDeclaration {
|
||||
if (position != TreeNode.noOffset) {
|
||||
sb.write(' pos = $position, end-pos = $endPosition');
|
||||
}
|
||||
if ((flags & hasAnnotationsFlag) != 0) {
|
||||
sb.write(' annotations $annotations\n');
|
||||
}
|
||||
if ((flags & hasTypeParamsFlag) != 0) {
|
||||
sb.write(' type-params $typeParameters');
|
||||
}
|
||||
|
||||
@@ -322,8 +322,11 @@ void BytecodeReaderHelper::ReadClosureDeclaration(const Function& function,
|
||||
const int kIsSyncStarFlag = 1 << 6;
|
||||
const int kIsDebuggableFlag = 1 << 7;
|
||||
const int kHasParameterFlagsFlag = 1 << 8;
|
||||
const int kHasAnnotationsFlag = 1 << 9;
|
||||
const int kHasPragmaFlag = 1 << 10;
|
||||
|
||||
const intptr_t flags = reader_.ReadUInt();
|
||||
const bool has_pragma = (flags & kHasPragmaFlag) != 0;
|
||||
|
||||
Object& parent = Object::Handle(Z, ReadObject());
|
||||
if (!parent.IsFunction()) {
|
||||
@@ -359,6 +362,7 @@ void BytecodeReaderHelper::ReadClosureDeclaration(const Function& function,
|
||||
closure.set_is_inlinable(false);
|
||||
}
|
||||
closure.set_is_debuggable((flags & kIsDebuggableFlag) != 0);
|
||||
closure.set_has_pragma(has_pragma);
|
||||
|
||||
closures_->SetAt(closureIndex, closure);
|
||||
|
||||
@@ -371,6 +375,11 @@ void BytecodeReaderHelper::ReadClosureDeclaration(const Function& function,
|
||||
(flags & kHasParameterFlagsFlag) != 0);
|
||||
|
||||
closure.SetSignature(signature);
|
||||
|
||||
if ((flags & kHasAnnotationsFlag) != 0) {
|
||||
ReadAnnotations(Class::Handle(Z, Function::Cast(parent).Owner()), closure,
|
||||
has_pragma);
|
||||
}
|
||||
}
|
||||
|
||||
FunctionTypePtr BytecodeReaderHelper::ReadFunctionSignature(
|
||||
|
||||
Reference in New Issue
Block a user