this repo has no description
at trunk 226 lines 7.4 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "cpython-func.h" 3 4#include "api-handle.h" 5#include "runtime.h" 6#include "set-builtins.h" 7 8namespace py { 9 10PY_EXPORT int PyAnySet_Check_Func(PyObject* arg) { 11 DCHECK(arg != nullptr, "obj must not be nullptr"); 12 Thread* thread = Thread::current(); 13 Runtime* runtime = thread->runtime(); 14 RawObject obj = ApiHandle::asObject(ApiHandle::fromPyObject(arg)); 15 return runtime->isInstanceOfSet(obj) || runtime->isInstanceOfFrozenSet(obj); 16} 17 18PY_EXPORT int PyAnySet_CheckExact_Func(PyObject* arg) { 19 DCHECK(arg != nullptr, "obj must not be nullptr"); 20 RawObject obj = ApiHandle::asObject(ApiHandle::fromPyObject(arg)); 21 return obj.isSet() || obj.isFrozenSet(); 22} 23 24PY_EXPORT int PyFrozenSet_Check_Func(PyObject* obj) { 25 DCHECK(obj != nullptr, "obj must not be nullptr"); 26 return Thread::current()->runtime()->isInstanceOfFrozenSet( 27 ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 28} 29 30PY_EXPORT int PyFrozenSet_CheckExact_Func(PyObject* obj) { 31 DCHECK(obj != nullptr, "obj must not be nullptr"); 32 return ApiHandle::asObject(ApiHandle::fromPyObject(obj)).isFrozenSet(); 33} 34 35PY_EXPORT PyObject* PyFrozenSet_New(PyObject* iterable) { 36 Thread* thread = Thread::current(); 37 Runtime* runtime = thread->runtime(); 38 if (iterable == nullptr) { 39 return ApiHandle::newReferenceWithManaged(runtime, 40 runtime->emptyFrozenSet()); 41 } 42 HandleScope scope(thread); 43 Object obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(iterable))); 44 FrozenSet set(&scope, runtime->newFrozenSet()); 45 Object result(&scope, setUpdate(thread, set, obj)); 46 if (result.isError()) { 47 return nullptr; 48 } 49 return ApiHandle::newReferenceWithManaged(runtime, *set); 50} 51 52PY_EXPORT PyTypeObject* PyFrozenSet_Type_Ptr() { 53 Runtime* runtime = Thread::current()->runtime(); 54 return reinterpret_cast<PyTypeObject*>(ApiHandle::borrowedReference( 55 runtime, runtime->typeAt(LayoutId::kFrozenSet))); 56} 57 58PY_EXPORT PyTypeObject* PySetIter_Type_Ptr() { 59 Runtime* runtime = Thread::current()->runtime(); 60 return reinterpret_cast<PyTypeObject*>(ApiHandle::borrowedReference( 61 runtime, runtime->typeAt(LayoutId::kSetIterator))); 62} 63 64PY_EXPORT int PySet_Add(PyObject* anyset, PyObject* key) { 65 Thread* thread = Thread::current(); 66 Runtime* runtime = thread->runtime(); 67 HandleScope scope(thread); 68 69 Object set_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(anyset))); 70 71 // TODO(T28454727): add FrozenSet 72 if (!runtime->isInstanceOfSet(*set_obj)) { 73 thread->raiseBadInternalCall(); 74 return -1; 75 } 76 77 Set set(&scope, *set_obj); 78 Object key_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(key))); 79 Object hash_obj(&scope, Interpreter::hash(thread, key_obj)); 80 if (hash_obj.isErrorException()) { 81 return -1; 82 } 83 word hash = SmallInt::cast(*hash_obj).value(); 84 85 setAdd(thread, set, key_obj, hash); 86 return 0; 87} 88 89PY_EXPORT int PySet_Check_Func(PyObject* obj) { 90 return Thread::current()->runtime()->isInstanceOfSet( 91 ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 92} 93 94PY_EXPORT int _PySet_NextEntry(PyObject* pyset, Py_ssize_t* ppos, 95 PyObject** pkey, Py_hash_t* phash) { 96 Thread* thread = Thread::current(); 97 HandleScope scope(thread); 98 Object set_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(pyset))); 99 Runtime* runtime = thread->runtime(); 100 if (!runtime->isInstanceOfSetBase(*set_obj)) { 101 thread->raiseBadInternalCall(); 102 return -1; 103 } 104 SetBase set(&scope, *set_obj); 105 Object value(&scope, NoneType::object()); 106 DCHECK(phash != nullptr, "phash must not be null"); 107 DCHECK(pkey != nullptr, "pkey must not be null"); 108 if (!setNextItemHash(set, ppos, &value, phash)) { 109 return false; 110 } 111 *pkey = ApiHandle::borrowedReference(runtime, *value); 112 return true; 113} 114 115PY_EXPORT int PySet_Clear(PyObject* anyset) { 116 Thread* thread = Thread::current(); 117 Runtime* runtime = thread->runtime(); 118 HandleScope scope(thread); 119 Object set_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(anyset))); 120 if (!runtime->isInstanceOfSetBase(*set_obj)) { 121 thread->raiseBadInternalCall(); 122 return -1; 123 } 124 SetBase set(&scope, *set_obj); 125 set.setNumItems(0); 126 set.setData(runtime->emptyTuple()); 127 return 0; 128} 129 130PY_EXPORT int PySet_Contains(PyObject* anyset, PyObject* key) { 131 Thread* thread = Thread::current(); 132 Runtime* runtime = thread->runtime(); 133 HandleScope scope(thread); 134 135 Object set_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(anyset))); 136 137 if (!runtime->isInstanceOfSetBase(*set_obj)) { 138 thread->raiseBadInternalCall(); 139 return -1; 140 } 141 142 SetBase set(&scope, *set_obj); 143 Object key_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(key))); 144 Object hash_obj(&scope, Interpreter::hash(thread, key_obj)); 145 if (hash_obj.isErrorException()) { 146 return -1; 147 } 148 word hash = SmallInt::cast(*hash_obj).value(); 149 return setIncludes(thread, set, key_obj, hash); 150} 151 152PY_EXPORT int PySet_Discard(PyObject* pyset, PyObject* pykey) { 153 Thread* thread = Thread::current(); 154 Runtime* runtime = thread->runtime(); 155 HandleScope scope(thread); 156 Object set_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(pyset))); 157 if (!runtime->isInstanceOfSet(*set_obj)) { 158 thread->raiseBadInternalCall(); 159 return -1; 160 } 161 Set set(&scope, *set_obj); 162 Object key(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(pykey))); 163 Object hash_obj(&scope, Interpreter::hash(thread, key)); 164 if (hash_obj.isErrorException()) { 165 return -1; 166 } 167 word hash = SmallInt::cast(*hash_obj).value(); 168 return setRemove(thread, set, key, hash); 169} 170 171PY_EXPORT PyObject* PySet_New(PyObject* iterable) { 172 Thread* thread = Thread::current(); 173 Runtime* runtime = thread->runtime(); 174 if (iterable == nullptr) { 175 return ApiHandle::newReferenceWithManaged(runtime, runtime->newSet()); 176 } 177 178 HandleScope scope(thread); 179 Object obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(iterable))); 180 Set set(&scope, runtime->newSet()); 181 182 Object result(&scope, setUpdate(thread, set, obj)); 183 if (result.isError()) { 184 return nullptr; 185 } 186 187 return ApiHandle::newReferenceWithManaged(runtime, *set); 188} 189 190PY_EXPORT PyObject* PySet_Pop(PyObject* pyset) { 191 Thread* thread = Thread::current(); 192 Runtime* runtime = thread->runtime(); 193 HandleScope scope(thread); 194 Object set_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(pyset))); 195 if (!runtime->isInstanceOfSet(*set_obj)) { 196 thread->raiseBadInternalCall(); 197 return nullptr; 198 } 199 Set set(&scope, *set_obj); 200 Object result(&scope, setPop(thread, set)); 201 if (result.isErrorException()) return nullptr; 202 return ApiHandle::newReference(runtime, *result); 203} 204 205PY_EXPORT Py_ssize_t PySet_Size(PyObject* anyset) { 206 Thread* thread = Thread::current(); 207 Runtime* runtime = thread->runtime(); 208 HandleScope scope(thread); 209 210 Object set_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(anyset))); 211 if (!runtime->isInstanceOfSetBase(*set_obj)) { 212 thread->raiseBadInternalCall(); 213 return -1; 214 } 215 216 SetBase set(&scope, *set_obj); 217 return set.numItems(); 218} 219 220PY_EXPORT PyTypeObject* PySet_Type_Ptr() { 221 Runtime* runtime = Thread::current()->runtime(); 222 return reinterpret_cast<PyTypeObject*>( 223 ApiHandle::borrowedReference(runtime, runtime->typeAt(LayoutId::kSet))); 224} 225 226} // namespace py