cpp

Coverage Report

Created: 2022-09-21 22:22

/home/andy/git/oilshell/oil/mycpp/smartptr.h
Line
Count
Source (jump to first uncovered line)
1
// OLD UNUSED CODE
2
3
#include <assert.h>
4
5
#include "mycpp/runtime.h"
6
7
template <typename T>
8
class Local {
9
  // We can garbage collect at any Alloc() invocation, so we need a level of
10
  // indirection for locals / pointers directly on the stack.  Pointers on the
11
  // heap are updated by the Cheney GC algorithm.
12
13
 public:
14
  Local() : raw_pointer_(nullptr) {
15
  }
16
17
  // IMPLICIT conversion.  No 'explicit'.
18
0
  explicit Local(T* raw_pointer) : raw_pointer_(raw_pointer) {
19
    // TODO(Jesse): Does this get called?
20
    // Is this NotImplemented() or InvalidCodePath() ??
21
0
    assert(0);
22
    // gHeap.PushRoot(this);
23
0
  }
24
25
  // Copy constructor, e.g. f(mylocal) where f(Local<T> param);
26
  explicit Local(const Local& other) : raw_pointer_(other.raw_pointer_) {
27
    // TODO(Jesse): Does this get called?
28
    // Is this NotImplemented() or InvalidCodePath() ??
29
    assert(0);
30
    // gHeap.PushRoot(this);
31
  }
32
33
  void operator=(const Local& other) {  // Assignment operator
34
    raw_pointer_ = other.raw_pointer_;
35
36
    // Note: we could try to avoid PushRoot() as an optimization.  Example:
37
    //
38
    // Local<Str> a = StrFromC("foo");
39
    // Local<Str> b;
40
    // b = a;  // invokes operator=, it's already a root
41
    //
42
    // Local<Str> c = myfunc();  // T* constructor takes care of PushRoot()
43
44
    // log("operator=");
45
46
    // However the problem is that then we'll have an unbalanced PopRoot().
47
    // So we keep it for now.
48
    gHeap.PushRoot(this);
49
  }
50
51
0
  ~Local() {
52
0
    gHeap.PopRoot();
53
0
  }
54
55
  // This cast operator overload allows:
56
  //
57
  // Local<Str> s = StrFromC("foo");
58
  // node->mystr = s;  // convert from Local to raw
59
  //
60
  // As well as:
61
  //
62
  // Local<List<Str*>> strings = Alloc<List<Str*>>();
63
  // strings->append(StrFromC("foo"));  // convert from local to raw
64
  //
65
  // The heap should NOT have locals!  List<Str> and not List<Local<Str>>.
66
  //
67
  // Note: This could be considered dangerous if we don't maintain
68
  // discipline.
69
  //
70
  // https://www.informit.com/articles/article.aspx?p=31529&seqNum=7
71
  //
72
  // Putting .get() at the call site in mycpp is more explicit. The
73
  // readability of the generated code is important!
74
#if 1
75
0
  operator T*() {
76
0
    return raw_pointer_;
77
0
  }
78
#endif
79
80
  // Allows ref->field and ref->method()
81
0
  T* operator->() const {
82
    // log("operator->");
83
0
    return raw_pointer_;
84
0
  }
85
  T* Get() const {
86
    return raw_pointer_;
87
  }
88
  // called by the garbage collector when moved to a new location!
89
  void Update(T* moved) {
90
    raw_pointer_ = moved;
91
  }
92
93
  // Dereference to get the real value.  Doesn't seem like we need this.
94
#if 0
95
  T operator*() const {
96
    //log("operator*");
97
    return *raw_pointer_;
98
  }
99
#endif
100
101
  T* raw_pointer_;
102
};
103
104
template <typename T>
105
class Param : public Local<T> {
106
  // This could be an optimization like SpiderMonkey's Handle<T> vs Rooted<T>.
107
  // We use the names Param<T> and Local<T>.
108
109
 public:
110
  // hm this is awkward, I think we should NOT inherit!  We should only
111
  // convert.
112
  explicit Param(const Local<T>& other) : Local<T>(nullptr) {
113
    this->raw_pointer_ = other.raw_pointer_;
114
  }
115
116
  ~Param() {  // do not PopRoot()
117
  }
118
119
  // Construct from T* -- PushRoot()
120
  // Construct from Local<T> -- we don't need to PushRoot()
121
  // operator= -- I don't think we need to PushRoot()
122
};