Skip to content

Commit

Permalink
[ddc] Add empty link methods to new ddc module format
Browse files Browse the repository at this point in the history
The link methods will contain all operations required to link class
hierarchies across library boundaries.

Change-Id: Iaa2bc566e17d215fd8bd9a20e6fc668679a2b58c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/380208
Reviewed-by: Mark Zhou <[email protected]>
Reviewed-by: Nate Biggs <[email protected]>
Commit-Queue: Mark Zhou <[email protected]>
  • Loading branch information
nshahan authored and Commit Queue committed Aug 30, 2024
1 parent c958bcc commit 3cc6105
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 4 deletions.
5 changes: 3 additions & 2 deletions pkg/dev_compiler/lib/js/ddc/ddc_module_loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -1325,8 +1325,9 @@ if (!self.deferred_loader) {
throw 'Library not defined: ' + libraryName + '. Failed to initialize.';
}
currentLibrary = initializer(currentLibrary);
// TODO(nshahan): Link the library when link methods are added to the
// compiled output.
// Link the library. This action will trigger the initialization and
// linking of dependency libraries as needed.
currentLibrary.link();
this.libraries[libraryName] = currentLibrary;
}
if (installFn != null) {
Expand Down
33 changes: 32 additions & 1 deletion pkg/dev_compiler/lib/src/kernel/compiler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -915,11 +915,33 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
_emitLibraryProcedures(library);
_emitTopLevelFields(library.fields);
}

if (_options.emitLibraryBundle) {
// TODO(nshahan): Remove when the Dart SDK can be compiled with the
// `LibraryBundleCompiler`.
_moduleItems.add(_emitEmptyLinkMethod(
_jsLibraryName(library), _emitLibraryName(library)));
}
_staticTypeContext.leaveLibrary(_currentLibrary!);
_currentLibrary = null;
}

/// Returns an empty placeholder link method for the libraries in the SDK.
///
/// This is a temporary solution to allow the Dart SDK to act like it was
/// compiled as a bundle of individual libraries.
// TODO(nshahan): Remove when the Dart SDK can be compiled with the
// `LibraryBundleCompiler`.
js_ast.Statement _emitEmptyLinkMethod(
String libraryName, js_ast.Identifier libraryId) {
assert(_options.emitLibraryBundle && _isBuildingSdk);
var functionName = _emitTemporaryId('link__$libraryName');
return js.statement('# = #', [
js_ast.PropertyAccess.field(libraryId, 'link'),
js_ast.NamedFunction(
functionName, js_ast.Fun(const [], js_ast.Block(const [])))
]);
}

void _emitExports(Library library) {
assert(_currentLibrary == null);
_currentLibrary = library;
Expand Down Expand Up @@ -8242,6 +8264,15 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
/// field of the result.
js_ast.Program _finishModule(List<js_ast.ModuleItem> items, String moduleName,
{List<js_ast.Comment> header = const []}) {
if (_options.emitLibraryBundle) {
assert(_isBuildingSdk);
// Manually add a link method for the runtime "dartx" library. It is
// synthetically created by DDC and doesn't have an associated kernel
// library node.
// TODO(nshahan): Remove when the Dart SDK can be compiled with the
// `LibraryBundleCompiler`.
_moduleItems.add(_emitEmptyLinkMethod('dartx', _extensionSymbolsModule));
}
// TODO(jmesserly): there's probably further consolidation we can do
// between DDC's two backends, by moving more code into this method, as the
// code between `startModule` and `finishModule` is very similar in both.
Expand Down
26 changes: 25 additions & 1 deletion pkg/dev_compiler/lib/src/kernel/compiler_new.dart
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,29 @@ class LibraryCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
return compiledLibrary;
}

/// Returns a method that will perform all class hierarchy operations for the
/// classes defined in this module.
///
/// At a high level this method performs the prototype stitching for all
/// `class A extends B` relationships but in practice will also include the
/// operations that implicitly depend on those relationships to be established
/// so they can walk the prototype chain.
js_ast.Statement _emitLibraryLinkMethod(Library library) {
var libraryName = _emitLibraryName(library);
var nameExpr = js_ast.PropertyAccess.field(libraryName, 'link');
var functionName = _emitTemporaryId('link__${_jsLibraryName(library)}');

var parameters = const <js_ast.Parameter>[];
var body = js_ast.Block([
// TODO(nshahan): Remove logging and add linking statements here.
js.statement(
'console.log("Linking library: ${_jsLibraryName(library)}")'),
]);
var function =
js_ast.NamedFunction(functionName, js_ast.Fun(parameters, body));
return js.statement('# = #', [nameExpr, function]);
}

/// Choose a canonical name from the [library] element.
String _jsLibraryName(Library library) {
return libraryUriToJsIdentifier(library.importUri);
Expand Down Expand Up @@ -998,7 +1021,8 @@ class LibraryCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
_emitLibraryProcedures(library);
_emitTopLevelFields(library.fields);
}

// Additional method used by the module system to link class hierarchies.
_moduleItems.add(_emitLibraryLinkMethod(library));
_staticTypeContext.leaveLibrary(_currentLibrary!);
}

Expand Down

0 comments on commit 3cc6105

Please sign in to comment.