this repo has no description
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com)
2#include "api-handle.h"
3#include "runtime.h"
4
5namespace py {
6
7PY_EXPORT int PyWeakref_Check_Func(PyObject* obj) {
8 return ApiHandle::asObject(ApiHandle::fromPyObject(obj)).isWeakRef();
9}
10
11PY_EXPORT void PyObject_ClearWeakRefs(PyObject* /* obj */) {
12 // Do nothing and delegated to the garbage collector.
13}
14
15PY_EXPORT PyObject* PyWeakref_GET_OBJECT_Func(PyObject* ref) {
16 Thread* thread = Thread::current();
17 HandleScope scope(thread);
18 // ref is assumed to be a WeakRef already
19 WeakRef weakref(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(ref)));
20 return ApiHandle::borrowedReference(thread->runtime(), weakref.referent());
21}
22
23PY_EXPORT PyObject* PyWeakref_GetObject(PyObject* ref) {
24 Thread* thread = Thread::current();
25 if (ref == nullptr) {
26 thread->raiseWithFmt(LayoutId::kSystemError,
27 "PyWeakref_GetObject expected non-null ref");
28 return nullptr;
29 }
30 HandleScope scope(thread);
31 Object obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(ref)));
32 if (!obj.isWeakRef()) {
33 thread->raiseWithFmt(LayoutId::kSystemError,
34 "PyWeakref_GetObject expected weakref");
35 return nullptr;
36 }
37 WeakRef weakref(&scope, *obj);
38 return ApiHandle::borrowedReference(thread->runtime(), weakref.referent());
39}
40
41PY_EXPORT PyObject* PyWeakref_NewProxy(PyObject* ob, PyObject* callback) {
42 Thread* thread = Thread::current();
43 HandleScope scope(thread);
44 Object referent(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(ob)));
45 Object callback_obj(&scope, NoneType::object());
46 if (callback != nullptr) {
47 callback_obj = ApiHandle::asObject(ApiHandle::fromPyObject(callback));
48 }
49 Object result_obj(&scope, thread->invokeFunction2(ID(_weakref), ID(proxy),
50 referent, callback_obj));
51 if (result_obj.isError()) {
52 return nullptr;
53 }
54 return ApiHandle::newReferenceWithManaged(thread->runtime(), *result_obj);
55}
56
57PY_EXPORT PyObject* PyWeakref_NewRef(PyObject* obj, PyObject* callback) {
58 Thread* thread = Thread::current();
59 HandleScope scope(thread);
60 Object referent(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj)));
61 Object callback_obj(&scope, NoneType::object());
62 if (callback != nullptr) {
63 callback_obj = ApiHandle::asObject(ApiHandle::fromPyObject(callback));
64 }
65 Runtime* runtime = thread->runtime();
66 WeakRef ref(&scope, runtime->newWeakRef(thread, referent));
67 if (callback_obj.isNoneType()) {
68 ref.setCallback(*callback_obj);
69 return ApiHandle::newReferenceWithManaged(runtime, *ref);
70 }
71 if (runtime->isCallable(thread, callback_obj)) {
72 ref.setCallback(runtime->newBoundMethod(callback_obj, ref));
73 return ApiHandle::newReferenceWithManaged(runtime, *ref);
74 }
75 thread->raiseWithFmt(LayoutId::kTypeError, "callback is not callable");
76 return nullptr;
77}
78
79} // namespace py