Skip to content

Commit 5f3466e

Browse files
alexmarkovCommit Queue
authored andcommitted
[vm,dyn_modules] Support deferred libraries
TEST=ci Change-Id: I0c9ba10b3220729aa9114ae965a4d3d2a4037a88 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,vm-dyn-mac-debug-arm64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/447761 Reviewed-by: Tess Strickland <[email protected]> Commit-Queue: Alexander Markov <[email protected]>
1 parent 5d84ffb commit 5f3466e

File tree

5 files changed

+102
-21
lines changed

5 files changed

+102
-21
lines changed

pkg/dart2bytecode/docs/bytecode.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,13 @@ type ConstantExternalCall extends ConstantPoolEntry {
805805
type ConstantFfiCall extends ConstantPoolEntry {
806806
Byte tag = 16;
807807
}
808+
809+
type ConstantDeferredLibraryPrefix extends ConstantPoolEntry {
810+
Byte tag = 17;
811+
PackedObject name;
812+
PackedObject enclosingLibrary;
813+
PackedObject targetLibrary;
814+
}
808815
```
809816

810817
### Exceptions table

pkg/dart2bytecode/lib/bytecode_generator.dart

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -909,9 +909,6 @@ class BytecodeGenerator extends RecursiveVisitor {
909909
libraryIndex.getTopLevelProcedure(
910910
'dart:_internal', '_boundsCheckForPartialInstantiation');
911911

912-
late Procedure futureValue =
913-
libraryIndex.getProcedure('dart:async', 'Future', 'value');
914-
915912
late Procedure throwLocalNotInitialized = libraryIndex.getProcedure(
916913
'dart:_internal', 'LateError', '_throwLocalNotInitialized');
917914

@@ -931,6 +928,12 @@ class BytecodeGenerator extends RecursiveVisitor {
931928
late Procedure allocateInvocationMirror = libraryIndex.getProcedure(
932929
'dart:core', '_InvocationMirror', '_allocateInvocationMirror');
933930

931+
late Procedure loadLibrary =
932+
libraryIndex.getTopLevelProcedure('dart:core', '_loadLibrary');
933+
934+
late Procedure checkLoaded =
935+
libraryIndex.getTopLevelProcedure('dart:core', '_checkLoaded');
936+
934937
late Procedure unsafeCast =
935938
libraryIndex.getTopLevelProcedure('dart:_internal', 'unsafeCast');
936939

@@ -3704,19 +3707,22 @@ class BytecodeGenerator extends RecursiveVisitor {
37043707
rhs is VariableGet ||
37053708
rhs is AsExpression;
37063709

3707-
void _genFutureNull() {
3708-
asm.emitPushNull();
3709-
_genDirectCall(futureValue, objectTable.getArgDescHandle(1), 1);
3710-
}
3711-
37123710
@override
37133711
void visitLoadLibrary(LoadLibrary node) {
3714-
_genFutureNull();
3712+
final dependency = node.import;
3713+
assert(dependency.isDeferred);
3714+
asm.emitPushConstant(cp.addDeferredLibraryPrefix(dependency.name!,
3715+
dependency.enclosingLibrary, dependency.targetLibrary));
3716+
_genDirectCall(loadLibrary, objectTable.getArgDescHandle(1), 1);
37153717
}
37163718

37173719
@override
37183720
void visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) {
3719-
_genFutureNull();
3721+
final dependency = node.import;
3722+
assert(dependency.isDeferred);
3723+
asm.emitPushConstant(cp.addDeferredLibraryPrefix(dependency.name!,
3724+
dependency.enclosingLibrary, dependency.targetLibrary));
3725+
_genDirectCall(checkLoaded, objectTable.getArgDescHandle(1), 1);
37203726
}
37213727

37223728
@override

pkg/dart2bytecode/lib/constant_pool.dart

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ enum ConstantTag {
3232
kDynamicCall,
3333
kExternalCall,
3434
kFfiCall,
35+
kDeferredLibraryPrefix,
3536
}
3637

3738
String constantTagToString(ConstantTag tag) =>
@@ -90,6 +91,8 @@ abstract class ConstantPoolEntry {
9091
return new ConstantExternalCall.read(reader);
9192
case ConstantTag.kFfiCall:
9293
return new ConstantFfiCall.read(reader);
94+
case ConstantTag.kDeferredLibraryPrefix:
95+
return new ConstantDeferredLibraryPrefix.read(reader);
9396
}
9497
throw 'Unexpected constant tag $tag';
9598
}
@@ -556,6 +559,45 @@ class ConstantFfiCall extends ConstantPoolEntry {
556559
bool operator ==(other) => identical(this, other);
557560
}
558561

562+
class ConstantDeferredLibraryPrefix extends ConstantPoolEntry {
563+
final ObjectHandle name;
564+
final ObjectHandle enclosingLibrary;
565+
final ObjectHandle targetLibrary;
566+
567+
ConstantDeferredLibraryPrefix(
568+
this.name, this.enclosingLibrary, this.targetLibrary);
569+
570+
@override
571+
ConstantTag get tag => ConstantTag.kDeferredLibraryPrefix;
572+
573+
@override
574+
void writeValue(BufferedWriter writer) {
575+
writer.writePackedObject(name);
576+
writer.writePackedObject(enclosingLibrary);
577+
writer.writePackedObject(targetLibrary);
578+
}
579+
580+
ConstantDeferredLibraryPrefix.read(BufferedReader reader)
581+
: name = reader.readPackedObject(),
582+
enclosingLibrary = reader.readPackedObject(),
583+
targetLibrary = reader.readPackedObject();
584+
585+
@override
586+
String toString() =>
587+
'DeferredLibraryPrefix $name, $enclosingLibrary -> $targetLibrary';
588+
589+
@override
590+
int get hashCode => _combineHashes(name.hashCode,
591+
_combineHashes(enclosingLibrary.hashCode, targetLibrary.hashCode));
592+
593+
@override
594+
bool operator ==(other) =>
595+
other is ConstantDeferredLibraryPrefix &&
596+
this.name == other.name &&
597+
this.enclosingLibrary == other.enclosingLibrary &&
598+
this.targetLibrary == other.targetLibrary;
599+
}
600+
559601
/// Reserved constant pool entry.
560602
class _ReservedConstantPoolEntry extends ConstantPoolEntry {
561603
const _ReservedConstantPoolEntry();
@@ -663,6 +705,14 @@ class ConstantPool {
663705

664706
int addEmptyTypeArguments() => _add(const ConstantEmptyTypeArguments());
665707

708+
int addDeferredLibraryPrefix(
709+
String name, Library enclosingLibrary, Library targetLibrary) =>
710+
_add(ConstantDeferredLibraryPrefix(
711+
objectTable.getConstStringHandle(name),
712+
objectTable.getHandle(enclosingLibrary)!,
713+
objectTable.getHandle(targetLibrary)!,
714+
));
715+
666716
int addObjectRef(Node? node) {
667717
// Constant objects should not depend on the type parameters of
668718
// the enclosing function.

pkg/dart2bytecode/testcases/deferred_lib.dart.expect

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,18 @@ Function 'callDeferred', static, reflectable, debuggable
1414
Bytecode {
1515
Entry 1
1616
CheckStack 0
17-
PushNull
18-
DirectCall CP#0, 1
17+
PushConstant CP#0
18+
DirectCall CP#1, 1
1919
PopLocal r0
20-
DirectCall CP#2, 0
20+
DirectCall CP#3, 0
2121
ReturnTOS
2222
}
2323
ConstantPool {
24-
[0] = DirectCall 'dart:async::Future::value (constructor)', ArgDesc num-args 1, num-type-args 0, names []
25-
[1] = Reserved
26-
[2] = DirectCall 'DART_SDK/pkg/dart2bytecode/testcases/hello.dart::main', ArgDesc num-args 0, num-type-args 0, names []
27-
[3] = Reserved
24+
[0] = DeferredLibraryPrefix 'lib', DART_SDK/pkg/dart2bytecode/testcases/deferred_lib.dart -> DART_SDK/pkg/dart2bytecode/testcases/hello.dart
25+
[1] = DirectCall 'dart:core::_checkLoaded', ArgDesc num-args 1, num-type-args 0, names []
26+
[2] = Reserved
27+
[3] = DirectCall 'DART_SDK/pkg/dart2bytecode/testcases/hello.dart::main', ArgDesc num-args 0, num-type-args 0, names []
28+
[4] = Reserved
2829
}
2930

3031

@@ -35,13 +36,14 @@ Function 'testLoadLibrary', static, reflectable, debuggable
3536
Bytecode {
3637
Entry 0
3738
CheckStack 0
38-
PushNull
39-
DirectCall CP#0, 1
39+
PushConstant CP#0
40+
DirectCall CP#1, 1
4041
ReturnTOS
4142
}
4243
ConstantPool {
43-
[0] = DirectCall 'dart:async::Future::value (constructor)', ArgDesc num-args 1, num-type-args 0, names []
44-
[1] = Reserved
44+
[0] = DeferredLibraryPrefix 'lib', DART_SDK/pkg/dart2bytecode/testcases/deferred_lib.dart -> DART_SDK/pkg/dart2bytecode/testcases/hello.dart
45+
[1] = DirectCall 'dart:core::_loadLibrary', ArgDesc num-args 1, num-type-args 0, names []
46+
[2] = Reserved
4547
}
4648

4749

runtime/vm/bytecode_reader.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,7 @@ intptr_t BytecodeReaderHelper::ReadConstantPool(const Function& function,
523523
kDynamicCall,
524524
kExternalCall,
525525
kFfiCall,
526+
kDeferredLibraryPrefix,
526527
};
527528

528529
Object& obj = Object::Handle(Z);
@@ -700,6 +701,21 @@ intptr_t BytecodeReaderHelper::ReadConstantPool(const Function& function,
700701
pool.SetRawValueAt(i, 0);
701702
continue;
702703
}
704+
case ConstantPoolTag::kDeferredLibraryPrefix: {
705+
name ^= ReadObject();
706+
ASSERT(name.IsSymbol());
707+
const auto& enclosing_library = Library::CheckedHandle(Z, ReadObject());
708+
const auto& target_library = Library::CheckedHandle(Z, ReadObject());
709+
obj = enclosing_library.LookupLocalLibraryPrefix(name);
710+
if (obj.IsNull()) {
711+
obj = Namespace::New(target_library, Object::null_array(),
712+
Object::null_array(), enclosing_library);
713+
obj = LibraryPrefix::New(name, Namespace::Cast(obj),
714+
/*deferred_load=*/true, enclosing_library);
715+
enclosing_library.AddObject(LibraryPrefix::Cast(obj), name);
716+
}
717+
ASSERT(LibraryPrefix::Cast(obj).GetLibrary(0) == target_library.ptr());
718+
} break;
703719
default:
704720
UNREACHABLE();
705721
}

0 commit comments

Comments
 (0)