Skip to content

Commit 0014762

Browse files
committed
py local ref-count
1 parent c1adeb6 commit 0014762

File tree

3 files changed

+49
-21
lines changed

3 files changed

+49
-21
lines changed

backend/Python/PyHelper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
// docs:
2323
// https://docs.python.org/3/c-api/index.html
2424
// https://docs.python.org/3/extending/embedding.html
25-
// https://docs.python.org/2/c-api/init.html#thread-state-and-the-global-interpreter-lock
25+
// https://docs.python.org/3.8/c-api/init.html#thread-state-and-the-global-interpreter-lock
2626

2727
SCRIPTX_BEGIN_INCLUDE_LIBRARY
2828
#ifndef PY_SSIZE_T_CLEAN

backend/Python/PyLocalReference.cc

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,37 @@
1515
* limitations under the License.
1616
*/
1717

18-
#include <ScriptX/ScriptX.h>
18+
#include "../../src/Native.hpp"
19+
#include "../../src/Reference.h"
20+
#include "../../src/Utils.h"
21+
#include "../../src/Value.h"
22+
#include "PyReference.hpp"
1923

2024
namespace script {
2125

22-
#define REF_IMPL_BASIC_FUNC(ValueType) \
23-
Local<ValueType>::Local(const Local<ValueType>& copy) : val_(copy.val_) {} \
24-
Local<ValueType>::Local(Local<ValueType>&& move) noexcept : val_(move.val_) {} \
25-
Local<ValueType>::~Local() {} \
26-
Local<ValueType>& Local<ValueType>::operator=(const Local& from) { \
27-
Local(from).swap(*this); \
28-
return *this; \
29-
} \
30-
Local<ValueType>& Local<ValueType>::operator=(Local&& move) noexcept { \
31-
Local(std::move(move)).swap(*this); \
32-
return *this; \
33-
} \
26+
namespace py_backend {
27+
void valueConstructorCheck(PyObject* value) {
28+
SCRIPTX_UNUSED(value);
29+
#ifndef NDEBUG
30+
if (!value) throw Exception("null reference");
31+
#endif
32+
}
33+
} // namespace py_backend
34+
35+
#define REF_IMPL_BASIC_FUNC(ValueType) \
36+
Local<ValueType>::Local(const Local<ValueType>& copy) : val_(py_backend::incRef(copy.val_)) {} \
37+
Local<ValueType>::Local(Local<ValueType>&& move) noexcept : val_(move.val_) { \
38+
move.val_ = nullptr; \
39+
} \
40+
Local<ValueType>::~Local() { py_backend::decRef(val_); } \
41+
Local<ValueType>& Local<ValueType>::operator=(const Local& from) { \
42+
Local(from).swap(*this); \
43+
return *this; \
44+
} \
45+
Local<ValueType>& Local<ValueType>::operator=(Local&& move) noexcept { \
46+
Local(std::move(move)).swap(*this); \
47+
return *this; \
48+
} \
3449
void Local<ValueType>::swap(Local& rhs) noexcept { std::swap(val_, rhs.val_); }
3550

3651
#define REF_IMPL_BASIC_EQUALS(ValueType) \
@@ -39,12 +54,14 @@ namespace script {
3954
}
4055

4156
#define REF_IMPL_BASIC_NOT_VALUE(ValueType) \
42-
Local<ValueType>::Local(InternalLocalRef val) : val_(val) {} \
57+
Local<ValueType>::Local(InternalLocalRef val) : val_(val) { \
58+
py_backend::valueConstructorCheck(val); \
59+
} \
4360
Local<String> Local<ValueType>::describe() const { return asValue().describe(); } \
4461
std::string Local<ValueType>::describeUtf8() const { return asValue().describeUtf8(); }
4562

4663
#define REF_IMPL_TO_VALUE(ValueType) \
47-
Local<Value> Local<ValueType>::asValue() const { return Local<Value>(/*TMPL: value*/); }
64+
Local<Value> Local<ValueType>::asValue() const { return Local<Value>(val_); }
4865

4966
REF_IMPL_BASIC_FUNC(Value)
5067

@@ -92,11 +109,14 @@ REF_IMPL_TO_VALUE(Unsupported)
92109

93110
Local<Value>::Local() noexcept : val_() {}
94111

95-
Local<Value>::Local(InternalLocalRef v8Local) : val_(v8Local) {}
112+
Local<Value>::Local(InternalLocalRef ref) : val_(ref) {}
96113

97-
bool Local<Value>::isNull() const { return false; }
114+
bool Local<Value>::isNull() const { return val_ == nullptr; }
98115

99-
void Local<Value>::reset() {}
116+
void Local<Value>::reset() {
117+
py_backend::decRef(val_);
118+
val_ = nullptr;
119+
}
100120

101121
ValueKind Local<Value>::getKind() const {
102122
if (isNull()) {
@@ -122,9 +142,9 @@ ValueKind Local<Value>::getKind() const {
122142

123143
bool Local<Value>::isString() const { return false; }
124144

125-
bool Local<Value>::isNumber() const { return false; }
145+
bool Local<Value>::isNumber() const { return PyNumber_Check(val_); }
126146

127-
bool Local<Value>::isBoolean() const { return false; }
147+
bool Local<Value>::isBoolean() const { return PyBool_Check(val_); }
128148

129149
bool Local<Value>::isFunction() const { return false; }
130150

backend/Python/PyReference.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
2020

2121
namespace script {
2222

23+
namespace py_backend {
24+
25+
inline PyObject* incRef(PyObject* ref) { return Py_XNewRef(ref); }
26+
27+
inline void decRef(PyObject* ref) { Py_XDECREF(ref); }
28+
29+
} // namespace py_backend
30+
2331
template <typename T>
2432
Global<T>::Global() noexcept : val_() {}
2533

0 commit comments

Comments
 (0)