[vm/shared] Perform deeply-immutable initialization runtime check.
When an initial value is assigned into a class tagged as deeply-immutable, perform runtime check of that value. This is needed to support proper initialization of the closures as part of deeply-immutable classes. BUG=https://github.com/dart-lang/sdk/issues/61962 TEST=run_isolate_group_run_test Change-Id: I550746c0d22ca06ffb89959e8384cc9e6d28d590 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/468200 Commit-Queue: Alexander Aprelev <aam@google.com> Reviewed-by: Slava Egorov <vegorov@google.com>
This commit is contained in:
committed by
Commit Queue
parent
fc3ce5a24e
commit
eb75c53d95
@@ -141,6 +141,8 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
int maxSourcePosition = 0;
|
||||
Member? dynModuleEntryPoint;
|
||||
|
||||
bool isInDeeplyImmutableClass = false;
|
||||
|
||||
BytecodeGenerator(
|
||||
ast.Component component,
|
||||
CoreTypes coreTypes,
|
||||
@@ -196,6 +198,9 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
|
||||
@override
|
||||
void visitClass(Class node) {
|
||||
isInDeeplyImmutableClass =
|
||||
pragmaParser.parsedPragmas<ParsedVmDeeplyImmutablePragma>(
|
||||
node.annotations).isNotEmpty;
|
||||
startMembers();
|
||||
visitList(node.constructors, this);
|
||||
visitList(node.procedures, this);
|
||||
@@ -323,6 +328,11 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
flags |= ClassDeclaration.hasAnnotationsFlag;
|
||||
if (annotations.hasPragma) {
|
||||
flags |= ClassDeclaration.hasPragmaFlag;
|
||||
if (pragmaParser
|
||||
.parsedPragmas<ParsedVmDeeplyImmutablePragma>(cls.annotations)
|
||||
.isNotEmpty) {
|
||||
flags |= ClassDeclaration.isDeeplyImmutableFlag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,6 +1056,10 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
? ffiLibraryIndex.getTopLevelProcedure('dart:ffi', '_ffiCall')
|
||||
: null;
|
||||
|
||||
late Procedure ensureDeeplyImmutable =
|
||||
libraryIndex.getTopLevelProcedure('dart:_internal',
|
||||
'_ensureDeeplyImmutable');
|
||||
|
||||
// Selector for implicit dynamic calls 'foo(...)' where
|
||||
// variable 'foo' has type 'dynamic'.
|
||||
late final implicitCallName = Name('implicit:call');
|
||||
@@ -1136,6 +1150,12 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
_generateNode(initializer);
|
||||
|
||||
final int cpIndex = cp.addInstanceField(field);
|
||||
if (isInDeeplyImmutableClass) {
|
||||
// TODO(dartbug.com/61078): Use static type to avoid runtime check.
|
||||
_genDirectCall(
|
||||
ensureDeeplyImmutable, objectTable.getArgDescHandle(1), 1);
|
||||
}
|
||||
|
||||
asm.emitStoreFieldTOS(cpIndex);
|
||||
|
||||
initializedFields.add(field);
|
||||
|
||||
@@ -100,6 +100,7 @@ class ClassDeclaration extends BytecodeDeclaration {
|
||||
static const isBaseClassFlag = 1 << 11;
|
||||
static const isInterfaceFlag = 1 << 12;
|
||||
static const isFinalFlag = 1 << 13;
|
||||
static const isDeeplyImmutableFlag = 1 << 14;
|
||||
|
||||
ObjectHandle? name;
|
||||
final int flags;
|
||||
@@ -200,6 +201,9 @@ class ClassDeclaration extends BytecodeDeclaration {
|
||||
if ((flags & hasPragmaFlag) != 0) {
|
||||
sb.write(', has-pragma');
|
||||
}
|
||||
if ((flags & isDeeplyImmutableFlag) != 0) {
|
||||
sb.write(', deeply-immutable');
|
||||
}
|
||||
if ((flags & hasSourcePositionsFlag) != 0) {
|
||||
sb.write(', pos = $position, end-pos = $endPosition');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user