| Index: tools/immic/lib/src/struct_layout.dart
|
| diff --git a/tools/immic/lib/src/struct_layout.dart b/tools/immic/lib/src/struct_layout.dart
|
| deleted file mode 100644
|
| index 57fcbaafa8e75c374b3401b24a340d45eb043a55..0000000000000000000000000000000000000000
|
| --- a/tools/immic/lib/src/struct_layout.dart
|
| +++ /dev/null
|
| @@ -1,206 +0,0 @@
|
| -// Copyright (c) 2015, the Dartino 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.
|
| -
|
| -library immic.struct_builder;
|
| -
|
| -import 'parser.dart';
|
| -import 'primitives.dart' as primitives;
|
| -
|
| -import 'dart:collection';
|
| -import 'dart:core' hide Type;
|
| -import 'dart:math' show max;
|
| -
|
| -const int POINTER_SIZE = 8;
|
| -
|
| -int _roundUp(int n, int alignment) {
|
| - return (n + alignment - 1) & ~(alignment - 1);
|
| -}
|
| -
|
| -class StructLayout {
|
| - final Map<String, StructSlot> _slots;
|
| - final int size;
|
| - final List<_StructHole> _holes;
|
| - StructLayout._(this._slots, this.size, this._holes);
|
| -
|
| - factory StructLayout(Struct struct) {
|
| - _StructBuilder builder = new _StructBuilder();
|
| -
|
| - struct.slots.forEach(builder.addSlot);
|
| - // TODO(zerny): Support unions in nodes.
|
| - if (struct.unions.isNotEmpty) {
|
| - builder.addUnionSlots(struct.unions.single);
|
| - }
|
| - return builder.finalize(0);
|
| - }
|
| -
|
| - factory StructLayout.forArguments(List<Formal> arguments) {
|
| - _StructBuilder builder = new _StructBuilder();
|
| - arguments.forEach(builder.addSlot);
|
| - return builder.finalize(POINTER_SIZE);
|
| - }
|
| -
|
| - Iterable<StructSlot> get slots => _slots.values;
|
| - StructSlot operator[](Formal slot) => _slots[slot.name];
|
| -}
|
| -
|
| -class StructSlot {
|
| - final Formal slot;
|
| - final int offset;
|
| - final int size;
|
| -
|
| - final Union union;
|
| - final int unionTag;
|
| -
|
| - StructSlot(this.slot, this.offset, this.size, this.union, this.unionTag);
|
| -
|
| - bool get isUnionSlot => union != null;
|
| -}
|
| -
|
| -class _StructRegion {
|
| - final int size;
|
| - final int alignment;
|
| -
|
| - final bool isUnion;
|
| - final owner;
|
| -
|
| - _StructRegion.forSlot(this.size, this.alignment, Formal this.owner)
|
| - : isUnion = false;
|
| -
|
| - _StructRegion.forUnion(this.size, this.alignment, Union this.owner)
|
| - : isUnion = true;
|
| -
|
| - Formal get slot {
|
| - assert(!isUnion);
|
| - return owner;
|
| - }
|
| -
|
| - Union get union {
|
| - assert(isUnion);
|
| - return owner;
|
| - }
|
| -}
|
| -
|
| -class _StructHole extends LinkedListEntry {
|
| - int begin;
|
| - int end;
|
| - _StructHole(this.begin, this.end);
|
| -
|
| - int get size => end - begin;
|
| -}
|
| -
|
| -class _StructBuilder {
|
| - final List<_StructRegion> regions = <_StructRegion>[];
|
| - final Map<String, StructSlot> slots = new LinkedHashMap<String, StructSlot>();
|
| - final LinkedList<_StructHole> holes = new LinkedList<_StructHole>();
|
| - int used = 0;
|
| -
|
| - StructLayout finalize(int minimum) {
|
| - // Sort the regions by size, so we get the largest regions first.
|
| - regions.sort((x, y) => y.size - x.size);
|
| -
|
| - for (_StructRegion region in regions) {
|
| - int offset = allocate(region.size, region.alignment);
|
| - if (region.isUnion) {
|
| - Union union = region.union;
|
| - int tag = 1;
|
| - union.slots.forEach((Formal slot) {
|
| - _defineSlot(slot, offset, computeSize(slot.type), union, tag++);
|
| - });
|
| - } else {
|
| - _defineSlot(region.slot, offset, region.size, null, -1);
|
| - }
|
| - }
|
| -
|
| - int size = max(allocate(0, POINTER_SIZE), minimum);
|
| - return new StructLayout._(slots, size, holes.toList());
|
| - }
|
| -
|
| - int allocate(int size, int alignment) {
|
| - int result = _allocateFromHole(size, alignment);
|
| - if (result >= 0) return result;
|
| -
|
| - result = _roundUp(used, alignment);
|
| - int padding = result - used;
|
| - if (padding > 0) {
|
| - holes.add(new _StructHole(result - padding, result));
|
| - }
|
| - used = result + size;
|
| - return result;
|
| - }
|
| -
|
| - int _allocateFromHole(int size, int alignment) {
|
| - if (size == 0) return -1;
|
| - for (_StructHole hole in holes) {
|
| - int offset = _roundUp(hole.begin, alignment);
|
| - if (offset + size <= hole.end) {
|
| - _splitHole(hole, offset, size);
|
| - return offset;
|
| - }
|
| - }
|
| - return -1;
|
| - }
|
| -
|
| - void _splitHole(_StructHole hole, int offset, int size) {
|
| - int end = hole.end;
|
| - if (offset + size < end) {
|
| - // Insert hole after.
|
| - hole.insertAfter(new _StructHole(offset + size, end));
|
| - }
|
| - // Shrink the hole before.
|
| - hole.end = offset;
|
| - if (hole.size == 0) holes.remove(hole);
|
| - }
|
| -
|
| - void addSlot(Formal slot) {
|
| - Type type = slot.type;
|
| - int size = computeSize(type);
|
| - int alignment = computeAlignment(type);
|
| - regions.add(new _StructRegion.forSlot(size, alignment, slot));
|
| - }
|
| -
|
| - void addUnionSlots(Union union) {
|
| - List<Formal> unionSlots = union.slots;
|
| - if (unionSlots.isEmpty) return;
|
| -
|
| - int unionSize = 0;
|
| - int unionAlignment = 0;
|
| - unionSlots.forEach((Formal slot) {
|
| - Type type = slot.type;
|
| - int size = computeSize(type);
|
| - if (size > unionSize) unionSize = size;
|
| - int alignment = computeAlignment(type);
|
| - if (alignment > unionAlignment) unionAlignment = alignment;
|
| - });
|
| -
|
| - regions.add(new _StructRegion.forUnion(unionSize, unionAlignment, union));
|
| - }
|
| -
|
| - void _defineSlot(Formal slot, int offset, int size, Union union, int tag) {
|
| - String name = slot.name;
|
| - if (slots.containsKey(name)) {
|
| - throw new UnsupportedError("Duplicate slot '$name' in struct.");
|
| - }
|
| - slots[name] = new StructSlot(slot, offset, size, union, tag);
|
| - }
|
| -
|
| - int computeSize(Type type) {
|
| - if (type.isPointer || type.isList || type.isString || type.isNode) {
|
| - return POINTER_SIZE;
|
| - }
|
| - if (type.isPrimitive) return primitives.size(type.primitiveType);
|
| -
|
| - Struct struct = type.resolved;
|
| - StructLayout layout = struct.layout;
|
| - for (_StructHole hole in layout._holes) {
|
| - holes.add(new _StructHole(hole.begin, hole.end));
|
| - }
|
| - return _roundUp(layout.size, POINTER_SIZE);
|
| - }
|
| -
|
| - int computeAlignment(Type type) {
|
| - return (type.isPrimitive && !type.isList && !type.isString)
|
| - ? primitives.size(type.primitiveType)
|
| - : POINTER_SIZE;
|
| - }
|
| -}
|
|
|