2424
2525PyObject *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
3941bool 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+
96117bool 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