/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 | | }; |