blob: 7c80ab28cd302943d7defe19c5fc733479393b39 [file] [log] [blame] [edit]
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:cfg/utils/arena.dart';
import 'package:test/test.dart';
void main() {
late Uint32Arena arena;
setUp(() {
arena = Uint32Arena();
});
test('allocate 0', () {
expect(arena.allocate(0), equals(ArenaPointer.Null));
expect(arena.allocate(42), isNot(equals(ArenaPointer.Null)));
expect(arena.allocate(0), equals(ArenaPointer.Null));
});
test('allocate and access', () {
final ptr1 = arena.allocate(3);
expect(arena[ptr1], equals(0));
expect(arena[ptr1 + 1], equals(0));
expect(arena[ptr1 + 2], equals(0));
arena[ptr1] = 0xabcdef01;
arena[ptr1 + 1] = 0xabcdef02;
arena[ptr1 + 2] = -3;
final ptr2 = arena.allocate(2);
expect(arena[ptr2], equals(0));
expect(arena[ptr2 + 1], equals(0));
arena[ptr2] = 0xf00d01;
arena[ptr2 + 1] = 0xf00d02;
expect(arena[ptr1], equals(0xabcdef01));
expect(arena[ptr1 + 1], equals(0xabcdef02));
expect(arena[ptr1 + 2], equals(0xfffffffd));
expect(arena[ptr2], equals(0xf00d01));
expect(arena[ptr2 + 1], equals(0xf00d02));
arena[ptr1 + 1] = 123;
expect(arena[ptr1], equals(0xabcdef01));
expect(arena[ptr1 + 1], equals(123));
expect(arena[ptr1 + 2], equals(0xfffffffd));
});
test('pointer arithmetic', () {
final p1 = arena.allocate(2000);
expect(p1 + 0, equals(p1));
final p2 = p1 + 1200;
final p3 = p2 + (-511);
final p4 = p3 + (-689);
expect(p4, equals(p1));
expect(p1 + 689, equals(p3));
expect((p1 + 17) + 1183, equals(p2));
expect((p1 + 1491).toInt(), equals((p2 + 291).toInt()));
});
test('expand', () {
final size1 = Uint32Arena.initialSize - 2;
final p1 = arena.allocate(Uint32Arena.initialSize - 2);
arena[p1] = 0x11111111;
arena[p1 + (size1 - 1)] = 0x22222222;
final p2 = arena.allocate(3);
arena[p2] = 0xf00d0001;
arena[p2 + 1] = 0xf00d0002;
arena[p2 + 2] = 0xf00d0003;
final size3 = Uint32Arena.initialSize << 3;
final p3 = arena.allocate(size3);
for (var i = 0; i < size3; ++i) {
arena[p3 + i] = i << 3;
}
expect(arena[p1], equals(0x11111111));
expect(arena[p1 + 1], equals(0));
expect(arena[p1 + (size1 ~/ 2)], equals(0));
expect(arena[p1 + (size1 - 2)], equals(0));
expect(arena[p1 + (size1 - 1)], equals(0x22222222));
expect(arena[p2], equals(0xf00d0001));
expect(arena[p2 + 1], equals(0xf00d0002));
expect(arena[p2 + 2], equals(0xf00d0003));
for (int i = size3 - 1; i >= 0; --i) {
expect(arena[p3 + i], equals(i << 3));
}
});
test('double linked list', () {
final n = 10;
final nodes = <ArenaPointer>[];
ArenaPointer prev = ArenaPointer.Null;
for (var i = 0; i < n; ++i) {
ArenaPointer node = arena.allocate(3); // 3 fields: payload, prev, next.
nodes.add(node);
arena[node] = i; // node.payload = i
arena[node + 1] = prev.toInt(); // node.prev = prev
arena[node + 2] = ArenaPointer.Null.toInt(); // node.next = null
if (prev != ArenaPointer.Null) {
arena[prev + 2] = node.toInt(); // prev.next = node
}
prev = node;
}
// Forward iteration.
var i = 0;
for (
ArenaPointer node = nodes.first;
node != ArenaPointer.Null;
node = ArenaPointer(arena[node + 2])
) {
expect(node, equals(nodes[i]));
expect(arena[node], equals(i));
++i;
}
expect(i, equals(n));
// Backwards iteration.
i = n;
for (
ArenaPointer node = nodes.last;
node != ArenaPointer.Null;
node = ArenaPointer(arena[node + 1])
) {
--i;
expect(node, equals(nodes[i]));
expect(arena[node], equals(i));
}
expect(i, equals(0));
});
}