2424
2525const char PyObjectProxyHandler::family = 0 ;
2626
27- bool PyObjectProxyHandler::object_toString (JSContext *cx, unsigned argc, JS::Value *vp) {
28- JS::CallArgs args = JS::CallArgsFromVp (argc, vp);
29-
30- args.rval ().setString (JS_NewStringCopyZ (cx, " [object Object]" ));
31- return true ;
32- }
33-
34- bool PyObjectProxyHandler::object_toLocaleString (JSContext *cx, unsigned argc, JS::Value *vp) {
35- return object_toString (cx, argc, vp);
36- }
37-
38- bool PyObjectProxyHandler::object_valueOf (JSContext *cx, unsigned argc, JS::Value *vp) {
39- JS::CallArgs args = JS::CallArgsFromVp (argc, vp);
40-
41- JS::RootedObject proxy (cx, JS::ToObject (cx, args.thisv ()));
42- if (!proxy) {
43- return false ;
44- }
45- PyObject *self = JS::GetMaybePtrFromReservedSlot<PyObject>(proxy, PyObjectSlot);
46-
47- // return ref to self
48- args.rval ().set (jsTypeFactory (cx, self));
49- return true ;
50- }
51-
52- JSMethodDef PyObjectProxyHandler::object_methods[] = {
53- {" toString" , PyObjectProxyHandler::object_toString, 0 },
54- {" toLocaleString" , PyObjectProxyHandler::object_toLocaleString, 0 },
55- {" valueOf" , PyObjectProxyHandler::object_valueOf, 0 },
56- {NULL , NULL , 0 }
57- };
58-
5927bool PyObjectProxyHandler::handleOwnPropertyKeys (JSContext *cx, PyObject *keys, size_t length, JS::MutableHandleIdVector props) {
6028 if (!props.reserve (length)) {
6129 return false ; // out of memory
@@ -76,24 +44,29 @@ bool PyObjectProxyHandler::handleGetOwnPropertyDescriptor(JSContext *cx, JS::Han
7644 JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc, PyObject *item) {
7745 // see if we're calling a function
7846 if (id.isString ()) {
79- for (size_t index = 0 ;; index++) {
80- bool isThatFunction;
81- const char *methodName = object_methods[index].name ;
82- if (methodName == NULL ) {
83- break ;
47+ JS::RootedString idString (cx, id.toString ());
48+ const char *methodName = JS_EncodeStringToUTF8 (cx, idString).get ();
49+ if (!strcmp (methodName, " toString" ) || !strcmp (methodName, " toLocaleString" ) || !strcmp (methodName, " valueOf" )) {
50+ JS::RootedObject objectPrototype (cx);
51+ if (!JS_GetClassPrototype (cx, JSProto_Object, &objectPrototype)) {
52+ return false ;
8453 }
85- else if (JS_StringEqualsAscii (cx, id.toString (), methodName, &isThatFunction) && isThatFunction) {
86- JSFunction *newFunction = JS_NewFunction (cx, object_methods[index].call , object_methods[index].nargs , 0 , NULL );
87- if (!newFunction) return false ;
88- JS::RootedObject funObj (cx, JS_GetFunctionObject (newFunction));
89- desc.set (mozilla::Some (
90- JS::PropertyDescriptor::Data (
91- JS::ObjectValue (*funObj),
92- {JS::PropertyAttribute::Enumerable}
93- )
94- ));
95- return true ;
54+
55+ JS::RootedValue Object_Prototype_Method (cx);
56+ if (!JS_GetProperty (cx, objectPrototype, methodName, &Object_Prototype_Method)) {
57+ return false ;
9658 }
59+
60+ JS::RootedObject rootedObjectPrototypeConstructor (cx, Object_Prototype_Method.toObjectOrNull ());
61+
62+ desc.set (mozilla::Some (
63+ JS::PropertyDescriptor::Data (
64+ JS::ObjectValue (*rootedObjectPrototypeConstructor),
65+ {JS::PropertyAttribute::Enumerable}
66+ )
67+ ));
68+
69+ return true ;
9770 }
9871 }
9972
0 commit comments