[dart2wasm] Allow using experimental dart:ffi in deferred modules
The experimental `dart:ffi` support predates deferred loading implementation. Any use of FFI features would lazily import `ffi.memory` into the (fixed coded) main module. This CL now lazily imports the `ffi.memory` module into all modules that operate on the memory. => This will now allow a flutter app that is compiled with dart2wasm in deferred loading mode to possibly defer parts of flutter engine code that uses FFI into deferred modules. Issue https://github.com/dart-lang/sdk/issues/56952 Change-Id: Idf821ce2dd92c36ac1be9dae24307516a1ae86d9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/510760 Reviewed-by: Slava Egorov <vegorov@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
c5f9583eb3
commit
034b90af5d
@@ -1610,42 +1610,43 @@ class Intrinsifier {
|
||||
b.i32_add();
|
||||
offset = 0;
|
||||
}
|
||||
final memory = translator.ffiMemory(b.moduleBuilder);
|
||||
switch (intrinsic) {
|
||||
case StaticIntrinsic.loadInt8:
|
||||
b.i64_load8_s(translator.ffiMemory, offset);
|
||||
b.i64_load8_s(memory, offset);
|
||||
return w.NumType.i64;
|
||||
case StaticIntrinsic.loadUint8:
|
||||
b.i64_load8_u(translator.ffiMemory, offset);
|
||||
b.i64_load8_u(memory, offset);
|
||||
return w.NumType.i64;
|
||||
case StaticIntrinsic.loadInt16:
|
||||
b.i64_load16_s(translator.ffiMemory, offset);
|
||||
b.i64_load16_s(memory, offset);
|
||||
return w.NumType.i64;
|
||||
case StaticIntrinsic.loadUint16:
|
||||
b.i64_load16_u(translator.ffiMemory, offset);
|
||||
b.i64_load16_u(memory, offset);
|
||||
return w.NumType.i64;
|
||||
case StaticIntrinsic.loadInt32:
|
||||
b.i64_load32_s(translator.ffiMemory, offset);
|
||||
b.i64_load32_s(memory, offset);
|
||||
return w.NumType.i64;
|
||||
case StaticIntrinsic.loadUint32:
|
||||
b.i64_load32_u(translator.ffiMemory, offset);
|
||||
b.i64_load32_u(memory, offset);
|
||||
return w.NumType.i64;
|
||||
case StaticIntrinsic.loadInt64:
|
||||
case StaticIntrinsic.loadUint64:
|
||||
b.i64_load(translator.ffiMemory, offset);
|
||||
b.i64_load(memory, offset);
|
||||
return w.NumType.i64;
|
||||
case StaticIntrinsic.loadFloat:
|
||||
b.f32_load(translator.ffiMemory, offset);
|
||||
b.f32_load(memory, offset);
|
||||
b.f64_promote_f32();
|
||||
return w.NumType.f64;
|
||||
case StaticIntrinsic.loadFloatUnaligned:
|
||||
b.f32_load(translator.ffiMemory, offset, 0);
|
||||
b.f32_load(memory, offset, 0);
|
||||
b.f64_promote_f32();
|
||||
return w.NumType.f64;
|
||||
case StaticIntrinsic.loadDouble:
|
||||
b.f64_load(translator.ffiMemory, offset);
|
||||
b.f64_load(memory, offset);
|
||||
return w.NumType.f64;
|
||||
case StaticIntrinsic.loadDoubleUnaligned:
|
||||
b.f64_load(translator.ffiMemory, offset, 0);
|
||||
b.f64_load(memory, offset, 0);
|
||||
return w.NumType.f64;
|
||||
case StaticIntrinsic.storeInt8:
|
||||
case StaticIntrinsic.storeUint8:
|
||||
@@ -1653,7 +1654,7 @@ class Intrinsifier {
|
||||
node.arguments.positional[2],
|
||||
w.NumType.i64,
|
||||
);
|
||||
b.i64_store8(translator.ffiMemory, offset);
|
||||
b.i64_store8(memory, offset);
|
||||
b.ref_null(w.HeapType.none);
|
||||
return translator.topType;
|
||||
case StaticIntrinsic.storeInt16:
|
||||
@@ -1662,7 +1663,7 @@ class Intrinsifier {
|
||||
node.arguments.positional[2],
|
||||
w.NumType.i64,
|
||||
);
|
||||
b.i64_store16(translator.ffiMemory, offset);
|
||||
b.i64_store16(memory, offset);
|
||||
b.ref_null(w.HeapType.none);
|
||||
return translator.topType;
|
||||
case StaticIntrinsic.storeInt32:
|
||||
@@ -1671,7 +1672,7 @@ class Intrinsifier {
|
||||
node.arguments.positional[2],
|
||||
w.NumType.i64,
|
||||
);
|
||||
b.i64_store32(translator.ffiMemory, offset);
|
||||
b.i64_store32(memory, offset);
|
||||
b.ref_null(w.HeapType.none);
|
||||
return translator.topType;
|
||||
case StaticIntrinsic.storeInt64:
|
||||
@@ -1680,7 +1681,7 @@ class Intrinsifier {
|
||||
node.arguments.positional[2],
|
||||
w.NumType.i64,
|
||||
);
|
||||
b.i64_store(translator.ffiMemory, offset);
|
||||
b.i64_store(memory, offset);
|
||||
b.ref_null(w.HeapType.none);
|
||||
return translator.topType;
|
||||
case StaticIntrinsic.storeFloat:
|
||||
@@ -1689,7 +1690,7 @@ class Intrinsifier {
|
||||
w.NumType.f64,
|
||||
);
|
||||
b.f32_demote_f64();
|
||||
b.f32_store(translator.ffiMemory, offset);
|
||||
b.f32_store(memory, offset);
|
||||
b.ref_null(w.HeapType.none);
|
||||
return translator.topType;
|
||||
case StaticIntrinsic.storeFloatUnaligned:
|
||||
@@ -1698,7 +1699,7 @@ class Intrinsifier {
|
||||
w.NumType.f64,
|
||||
);
|
||||
b.f32_demote_f64();
|
||||
b.f32_store(translator.ffiMemory, offset, 0);
|
||||
b.f32_store(memory, offset, 0);
|
||||
b.ref_null(w.HeapType.none);
|
||||
return translator.topType;
|
||||
case StaticIntrinsic.storeDouble:
|
||||
@@ -1706,7 +1707,7 @@ class Intrinsifier {
|
||||
node.arguments.positional[2],
|
||||
w.NumType.f64,
|
||||
);
|
||||
b.f64_store(translator.ffiMemory, offset);
|
||||
b.f64_store(memory, offset);
|
||||
b.ref_null(w.HeapType.none);
|
||||
return translator.topType;
|
||||
case StaticIntrinsic.storeDoubleUnaligned:
|
||||
@@ -1714,7 +1715,7 @@ class Intrinsifier {
|
||||
node.arguments.positional[2],
|
||||
w.NumType.f64,
|
||||
);
|
||||
b.f64_store(translator.ffiMemory, offset, 0);
|
||||
b.f64_store(memory, offset, 0);
|
||||
b.ref_null(w.HeapType.none);
|
||||
return translator.topType;
|
||||
default:
|
||||
|
||||
@@ -204,16 +204,22 @@ class Translator with KernelNodes {
|
||||
w.StructType("void"),
|
||||
nullable: true,
|
||||
);
|
||||
// Lazily import FFI memory if used.
|
||||
late final w.Memory ffiMemory = mainModule.memories.import(
|
||||
"ffi",
|
||||
"memory",
|
||||
options.importSharedMemory,
|
||||
0,
|
||||
options.sharedMemoryMaxPages,
|
||||
);
|
||||
final Map<Procedure, w.Memory> _memories = {};
|
||||
|
||||
// Lazily import FFI memory if used.
|
||||
final _ffiMemoryImports = <w.ModuleBuilder, w.Memory>{};
|
||||
w.Memory ffiMemory(w.ModuleBuilder usingModule) {
|
||||
return _ffiMemoryImports.putIfAbsent(usingModule, () {
|
||||
return usingModule.memories.import(
|
||||
"ffi",
|
||||
"memory",
|
||||
options.importSharedMemory,
|
||||
0,
|
||||
options.sharedMemoryMaxPages,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Maps record shapes to the record class for the shape. Classes generated
|
||||
/// by `record_class_generator` library.
|
||||
final Map<RecordShape, Class> recordClasses;
|
||||
@@ -2192,10 +2198,7 @@ class Translator with KernelNodes {
|
||||
return _shouldInlineProcedureCall(target, signature, member as Procedure);
|
||||
}
|
||||
|
||||
InliningDecision _shouldInlineFieldAccessor(
|
||||
Reference target,
|
||||
Field field,
|
||||
) {
|
||||
InliningDecision _shouldInlineFieldAccessor(Reference target, Field field) {
|
||||
if (field.isInstanceMember) {
|
||||
// Implicit instance getters are just loads.
|
||||
if (target.isImplicitGetter) {
|
||||
|
||||
Reference in New Issue
Block a user