-
Notifications
You must be signed in to change notification settings - Fork 25
/
handle.h
133 lines (120 loc) · 2.89 KB
/
handle.h
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/**
* handle.h
*
* A simple class that represents a handle managed by
* the v8 engine. Give it any object, and it will be
* either copied or moved and destructed when v8 no
* longer has any references to it.
*
* @copyright 2015 Copernica B.V.
*/
/**
* Include guard
*/
#pragma once
/**
* Dependencies
*/
#include <v8.h>
#include <utility>
#include <phpcpp.h>
#include "isolate.h"
#include "external.h"
/**
* Start namespace
*/
namespace JS {
/**
* Handle class
*/
class Handle
{
private:
/**
* The v8 handle to the object
* @var v8::Handle<v8::External>
*/
v8::Local<v8::External> _handle;
public:
/**
* Constructor
*
* @param object the object to handle
*/
Handle(Php::Value object)
{
/**
* Create a copy of the object and a persistent
* handle for it. Even though you won't find it
* anywhere in the documentation: the persistent
* handle _must_ stay in memory, because if it
* gets destructed it will forget that it was
* made weak. It won't forget to keep a reference
* alive though, resulting in memory leaks and
* - eventually - failing assertions from within
* v8 itself. Yes, it realises it made a mistake
* and rewards us by crashing.
*/
auto *copy= new External(std::move(object));
// create the v8 handle around it
_handle = v8::External::New(Isolate::get(), copy->get());
// initialize the persistent handle
copy->initialize(_handle);
}
/**
* Constructor
*
* @param handle the value handle to parse
*/
Handle(v8::Local<v8::Value> handle)
{
// cast and store the given handle
_handle = v8::Local<v8::External>::Cast(handle);
}
/**
* Cast to the v8 handle that can be registered
* with the v8 engine and tracked there.
*
* @return v8::Local<v8::Value>
*/
operator v8::Local<v8::Value> ()
{
// simply return the stored handle
return _handle;
}
/**
* Return a pointer to the managed object, so that
* methods and properties can be easily retrieved.
*
* @return The managed value
*/
Php::Value *operator->()
{
// retrieve the handled value and cast it
return static_cast<Php::Value*>(_handle->Value());
}
/**
* Cast the object to to the original object
*
* @return The original Php::Value
*/
Php::Value &operator*()
{
// retrieve the handled value and cast it
return *(operator->());
}
/**
* Cast the object to to the original object
*
* @return The Php::Value we are handling
*/
operator Php::Value &()
{
// retrieve the handled value and cast it
return *(operator->());
}
};
/**
* End namespace
*/
}