Skip to content

Commit 252f72b

Browse files
committed
Merge branch 'Xmader/fix/Object.values' into j0ashm:feat/object-datatype-tests
2 parents 1e04787 + 8b55f8e commit 252f72b

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

include/PyProxyHandler.hh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ public:
150150

151151
bool getOwnPropertyDescriptor(
152152
JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
153-
JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc) const override {};
153+
JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc
154+
) const override;
154155

155156
bool defineProperty(JSContext *cx, JS::HandleObject proxy,
156157
JS::HandleId id,
@@ -186,4 +187,9 @@ public:
186187
*/
187188
PyObject *idToKey(JSContext *cx, JS::HandleId id);
188189

190+
/**
191+
* @brief Convert Python dict key to jsid
192+
*/
193+
bool keyToId(PyObject *key, JS::MutableHandleId idp);
194+
189195
#endif

src/PyProxyHandler.cc

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,18 @@
2424

2525
PyObject *idToKey(JSContext *cx, JS::HandleId id) {
2626
JS::RootedValue idv(cx, js::IdToValue(id));
27-
JSString *idStr;
27+
JS::RootedString idStr(cx);
2828
if (!id.isSymbol()) { // `JS::ToString` returns `nullptr` for JS symbols
2929
idStr = JS::ToString(cx, idv);
3030
} else {
3131
// TODO (Tom Tang): Revisit this once we have Symbol coercion support
3232
// FIXME (Tom Tang): key collision for symbols without a description string, or pure strings look like "Symbol(xxx)"
3333
idStr = JS_ValueToSource(cx, idv);
3434
}
35+
3536
// We convert all types of property keys to string
36-
return StrType(cx, idStr).getPyObject();
37+
auto chars = JS_EncodeStringToUTF8(cx, idStr);
38+
return PyUnicode_FromString(chars.get());
3739
}
3840

3941
bool idToIndex(JSContext *cx, JS::HandleId id, Py_ssize_t *index) {
@@ -56,10 +58,10 @@ bool PyProxyHandler::ownPropertyKeys(JSContext *cx, JS::HandleObject proxy, JS::
5658

5759
for (size_t i = 0; i < length; i++) {
5860
PyObject *key = PyList_GetItem(keys, i);
59-
JS::RootedValue jsKey(cx, jsTypeFactory(cx, key));
6061
JS::RootedId jsId(cx);
61-
if (!JS_ValueToId(cx, jsKey, &jsId)) {
62-
// @TODO (Caleb Aikens) raise exception
62+
if (!keyToId(key, &jsId)) {
63+
// TODO (Caleb Aikens): raise exception here
64+
return false; // key is not a str or int
6365
}
6466
props.infallibleAppend(jsId);
6567
}
@@ -93,6 +95,25 @@ bool PyProxyHandler::get(JSContext *cx, JS::HandleObject proxy,
9395
return true;
9496
}
9597

98+
bool PyProxyHandler::getOwnPropertyDescriptor(
99+
JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
100+
JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc
101+
) const {
102+
PyObject *attrName = idToKey(cx, id);
103+
PyObject *item = PyDict_GetItemWithError(pyObject, attrName);
104+
if (!item) { // NULL if the key is not present
105+
desc.set(mozilla::Nothing()); // JS objects return undefined for nonpresent keys
106+
} else {
107+
desc.set(mozilla::Some(
108+
JS::PropertyDescriptor::Data(
109+
jsTypeFactory(cx, item),
110+
{JS::PropertyAttribute::Writable, JS::PropertyAttribute::Enumerable}
111+
)
112+
));
113+
}
114+
return true;
115+
}
116+
96117
bool PyProxyHandler::set(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
97118
JS::HandleValue v, JS::HandleValue receiver,
98119
JS::ObjectOpResult &result) const {

0 commit comments

Comments
 (0)