summaryrefslogtreecommitdiff
path: root/deps/v8/src/builtins/torque-internal.tq
blob: 48a08deb0aa2070dbf8beb89252f8f7f056fd1f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

namespace torque_internal {
  // TODO(gsps): Synthesize SizeOf<T> in the compiler

  macro SizeOf<T: type>(): constexpr int31;
  SizeOf<Object>(): constexpr int31 {
    return kTaggedSize;
  }
  SizeOf<float64>(): constexpr int31 {
    return kDoubleSize;
  }

  // Unsafe is a marker that we require to be passed when calling internal APIs
  // that might lead to unsoundness when used incorrectly. Unsafe markers should
  // therefore not be instantiated anywhere outside of this namespace.
  struct Unsafe {}

  struct Reference<T: type> {
    const object: HeapObject;
    const offset: intptr;
    unsafeMarker: Unsafe;
  }

  macro UnsafeNewReference<T: type>(object: HeapObject, offset: intptr):&T {
    return Reference<T>{
      object: object,
      offset: offset,
      unsafeMarker: Unsafe {}
    };
  }

  struct Slice<T: type> {
    TryAtIndex(index: intptr):&T labels OutOfBounds {
      if (Convert<uintptr>(index) < Convert<uintptr>(this.length)) {
        return UnsafeNewReference<T>(
            this.object, this.offset + index * SizeOf<T>());
      } else {
        goto OutOfBounds;
      }
    }

    AtIndex(index: intptr):&T {
      return this.TryAtIndex(index) otherwise unreachable;
    }

    AtIndex(index: constexpr int31):&T {
      const i: intptr = Convert<intptr>(index);
      return this.TryAtIndex(i) otherwise unreachable;
    }

    AtIndex(index: Smi):&T {
      const i: intptr = Convert<intptr>(index);
      return this.TryAtIndex(i) otherwise unreachable;
    }

    Iterator(): SliceIterator<T> {
      const end = this.offset + this.length * SizeOf<T>();
      return SliceIterator<T>{
        object: this.object,
        start: this.offset,
        end: end,
        unsafeMarker: Unsafe {}
      };
    }

    const object: HeapObject;
    const offset: intptr;
    const length: intptr;
    unsafeMarker: Unsafe;
  }

  macro UnsafeNewSlice<T: type>(
      object: HeapObject, offset: intptr, length: intptr): Slice<T> {
    return Slice<T>{
      object: object,
      offset: offset,
      length: length,
      unsafeMarker: Unsafe {}
    };
  }

  struct SliceIterator<T: type> {
    Empty(): bool {
      return this.start == this.end;
    }

    Next():&T labels NoMore {
      if (this.Empty()) {
        goto NoMore;
      } else {
        const result = UnsafeNewReference<T>(this.object, this.start);
        this.start += SizeOf<T>();
        return result;
      }
    }

    object: HeapObject;
    start: intptr;
    end: intptr;
    unsafeMarker: Unsafe;
  }

}  // namespace torque_internal