[vm/ffi] Check Array<T extends Struct> bounds on []
TEST=tests/ffi/inline_array_test.dart Bug: https://github.com/dart-lang/sdk/issues/54379 Change-Id: I2799056ce48fa8cfa590512b241fe72f61a07dbf Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/345060 Reviewed-by: Tess Strickland <sstrickl@google.com>
This commit is contained in:
committed by
Commit Queue
parent
d4f8f24dc8
commit
cd9eaef675
@@ -938,14 +938,43 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
|
||||
final constructor = clazz.constructors
|
||||
.firstWhere((c) => c.name == Name("#fromTypedDataBase"));
|
||||
|
||||
final typedDataBasePrime = typedDataBaseOffset(
|
||||
getArrayTypedDataBaseField(NullCheck(node.arguments.positional[0])),
|
||||
multiply(node.arguments.positional[1], inlineSizeOf(dartType)!),
|
||||
inlineSizeOf(dartType)!,
|
||||
dartType,
|
||||
node.fileOffset);
|
||||
final arrayVar = VariableDeclaration("#array",
|
||||
initializer: NullCheck(node.arguments.positional[0]),
|
||||
type: InterfaceType(arrayClass, Nullability.nonNullable),
|
||||
isSynthesized: true)
|
||||
..fileOffset = node.fileOffset;
|
||||
final indexVar = VariableDeclaration("#index",
|
||||
initializer: NullCheck(node.arguments.positional[1]),
|
||||
type: coreTypes.intNonNullableRawType,
|
||||
isSynthesized: true)
|
||||
..fileOffset = node.fileOffset;
|
||||
|
||||
return ConstructorInvocation(constructor, Arguments([typedDataBasePrime]));
|
||||
return BlockExpression(
|
||||
Block([
|
||||
arrayVar,
|
||||
indexVar,
|
||||
ExpressionStatement(InstanceInvocation(
|
||||
InstanceAccessKind.Instance,
|
||||
VariableGet(arrayVar),
|
||||
arrayCheckIndex.name,
|
||||
Arguments([VariableGet(indexVar)]),
|
||||
interfaceTarget: arrayCheckIndex,
|
||||
functionType: arrayCheckIndex.getterType as FunctionType,
|
||||
)),
|
||||
]),
|
||||
ConstructorInvocation(
|
||||
constructor,
|
||||
Arguments([
|
||||
typedDataBaseOffset(
|
||||
getArrayTypedDataBaseField(VariableGet(arrayVar)),
|
||||
multiply(VariableGet(indexVar), inlineSizeOf(dartType)!),
|
||||
inlineSizeOf(dartType)!,
|
||||
dartType,
|
||||
node.fileOffset,
|
||||
)
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Generates an expression that returns a new `Array<dartType>`.
|
||||
@@ -1031,12 +1060,13 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
|
||||
arrayVar,
|
||||
indexVar,
|
||||
ExpressionStatement(InstanceInvocation(
|
||||
InstanceAccessKind.Instance,
|
||||
VariableGet(arrayVar),
|
||||
arrayCheckIndex.name,
|
||||
Arguments([VariableGet(indexVar)]),
|
||||
interfaceTarget: arrayCheckIndex,
|
||||
functionType: arrayCheckIndex.getterType as FunctionType)),
|
||||
InstanceAccessKind.Instance,
|
||||
VariableGet(arrayVar),
|
||||
arrayCheckIndex.name,
|
||||
Arguments([VariableGet(indexVar)]),
|
||||
interfaceTarget: arrayCheckIndex,
|
||||
functionType: arrayCheckIndex.getterType as FunctionType,
|
||||
)),
|
||||
singleElementSizeVar,
|
||||
elementSizeVar,
|
||||
offsetVar
|
||||
|
||||
@@ -19,6 +19,8 @@ void main() {
|
||||
testToString();
|
||||
testRange();
|
||||
testRangeArrayOfPointer();
|
||||
testRangeArrayOfArray();
|
||||
testRangeArrayOfStruct();
|
||||
}
|
||||
|
||||
void testSizeOf() {
|
||||
@@ -109,3 +111,30 @@ final class StructWithArrayOfPointer extends Struct {
|
||||
@Array(8)
|
||||
external Array<Pointer<Uint8>> a0;
|
||||
}
|
||||
|
||||
void testRangeArrayOfArray() {
|
||||
final pointer = calloc<StructWithArrayArray>();
|
||||
final struct = pointer.ref;
|
||||
final array = struct.a0;
|
||||
array[0] = array[1];
|
||||
Expect.throws(() => array[-1]);
|
||||
Expect.throws(() => array[-1] = array[1]);
|
||||
Expect.throws(() => array[2]);
|
||||
Expect.throws(() => array[2] = array[1]);
|
||||
calloc.free(pointer);
|
||||
}
|
||||
|
||||
final class StructWithArrayArray extends Struct {
|
||||
@Array(2, 2)
|
||||
external Array<Array<Uint8>> a0;
|
||||
}
|
||||
|
||||
void testRangeArrayOfStruct() {
|
||||
final pointer = calloc<Struct4BytesInlineArrayMultiDimensionalInt>();
|
||||
final struct = pointer.ref;
|
||||
final array = struct.a0[0];
|
||||
print(array[0]);
|
||||
Expect.throws(() => array[-1]);
|
||||
Expect.throws(() => array[2]);
|
||||
calloc.free(pointer);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user