forked from Distributive-Network/PythonMonkey
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJSObjectIterProxy.cc
More file actions
122 lines (100 loc) · 3.47 KB
/
JSObjectIterProxy.cc
File metadata and controls
122 lines (100 loc) · 3.47 KB
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
/**
* @file JSObjectIterProxy.cc
* @author Philippe Laporte (philippe@distributive.network)
* @brief JSObjectIterProxy is a custom C-implemented python type that derives from list iterator
* @date 2024-01-17
*
* Copyright (c) 2024 Distributive Corp.
*
*/
#include "include/JSObjectIterProxy.hh"
#include "include/JSObjectProxy.hh"
#include "include/modules/pythonmonkey/pythonmonkey.hh"
#include "include/pyTypeFactory.hh"
#include "include/PyDictProxyHandler.hh"
#include <jsapi.h>
#include <jsfriendapi.h>
#include <Python.h>
void JSObjectIterProxyMethodDefinitions::JSObjectIterProxy_dealloc(JSObjectIterProxy *self)
{
delete self->it.props;
PyObject_GC_UnTrack(self);
Py_XDECREF(self->it.di_dict);
PyObject_GC_Del(self);
}
int JSObjectIterProxyMethodDefinitions::JSObjectIterProxy_traverse(JSObjectIterProxy *self, visitproc visit, void *arg) {
Py_VISIT(self->it.di_dict);
return 0;
}
PyObject *JSObjectIterProxyMethodDefinitions::JSObjectIterProxy_iter(JSObjectIterProxy *self) {
Py_INCREF(&self->it);
return (PyObject *)&self->it;
}
PyObject *JSObjectIterProxyMethodDefinitions::JSObjectIterProxy_nextkey(JSObjectIterProxy *self) {
PyDictObject *dict = self->it.di_dict;
if (dict == NULL) {
return NULL;
}
if (self->it.reversed) {
if (self->it.it_index >= 0) {
JS::HandleId id = (*(self->it.props))[(self->it.it_index)--];
PyObject *key = idToKey(GLOBAL_CX, id);
PyObject *value;
if (self->it.kind != KIND_KEYS) {
JS::RootedObject *global = new JS::RootedObject(GLOBAL_CX, JS::GetNonCCWObjectGlobal(((JSObjectProxy *)(self->it.di_dict))->jsObject));
JS::RootedValue *jsVal = new JS::RootedValue(GLOBAL_CX);
JS_GetPropertyById(GLOBAL_CX, ((JSObjectProxy *)(self->it.di_dict))->jsObject, id, jsVal);
value = pyTypeFactory(GLOBAL_CX, global, jsVal)->getPyObject();
}
PyObject *ret;
if (self->it.kind == KIND_ITEMS) {
ret = PyTuple_Pack(2, key, value);
}
else if (self->it.kind == KIND_VALUES) {
ret = value;
}
else {
ret = key;
}
Py_INCREF(ret);
return ret;
}
} else {
if (self->it.it_index < JSObjectProxyMethodDefinitions::JSObjectProxy_length((JSObjectProxy *)dict)) {
JS::HandleId id = (*(self->it.props))[(self->it.it_index)++];
PyObject *key = idToKey(GLOBAL_CX, id);
PyObject *value;
if (self->it.kind != KIND_KEYS) {
JS::RootedObject *global = new JS::RootedObject(GLOBAL_CX, JS::GetNonCCWObjectGlobal(((JSObjectProxy *)(self->it.di_dict))->jsObject));
JS::RootedValue *jsVal = new JS::RootedValue(GLOBAL_CX);
JS_GetPropertyById(GLOBAL_CX, ((JSObjectProxy *)(self->it.di_dict))->jsObject, id, jsVal);
value = pyTypeFactory(GLOBAL_CX, global, jsVal)->getPyObject();
}
PyObject *ret;
if (self->it.kind == KIND_ITEMS) {
ret = PyTuple_Pack(2, key, value);
}
else if (self->it.kind == KIND_VALUES) {
ret = value;
}
else {
ret = key;
}
Py_INCREF(ret);
return ret;
}
}
self->it.di_dict = NULL;
Py_DECREF(dict);
return NULL;
}
PyObject *JSObjectIterProxyMethodDefinitions::JSObjectIterProxy_len(JSObjectIterProxy *self) {
Py_ssize_t len;
if (self->it.di_dict) {
len = JSObjectProxyMethodDefinitions::JSObjectProxy_length((JSObjectProxy *)self->it.di_dict) - self->it.it_index;
if (len >= 0) {
return PyLong_FromSsize_t(len);
}
}
return PyLong_FromLong(0);
}