Bug 1492737 - Part 1: Support passing name length to JS_GetOwnUCPropertyDescriptor and add JS_GetUCPropertyDescriptor. r=Waldo, a=pascalc
authorJan Varga <jan.varga@gmail.com>
Tue, 25 Sep 2018 11:53:39 +0200
changeset 490264 d43c7f7c0d15
parent 490263 a571fb22559a
child 490265 1c577d6a48f0
push id9969
push userryanvm@gmail.com
push dateThu, 11 Oct 2018 17:41:24 +0000
treeherdermozilla-beta@f439e5f9e3d3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersWaldo, pascalc
bugs1492737
milestone63.0
Bug 1492737 - Part 1: Support passing name length to JS_GetOwnUCPropertyDescriptor and add JS_GetUCPropertyDescriptor. r=Waldo, a=pascalc
dom/xbl/nsXBLBinding.cpp
dom/xbl/nsXBLProtoImpl.cpp
js/src/jsapi.cpp
js/src/jsapi.h
--- a/dom/xbl/nsXBLBinding.cpp
+++ b/dom/xbl/nsXBLBinding.cpp
@@ -977,17 +977,18 @@ nsXBLBinding::DoInitJSClass(JSContext *c
   js::AssertSameCompartment(holder, xblScope);
   JSAutoRealm ar(cx, holder);
 
   // Look up the class on the property holder. The only properties on the
   // holder should be class objects. If we don't find the class object, we need
   // to create and define it.
   JS::Rooted<JSObject*> proto(cx);
   JS::Rooted<JS::PropertyDescriptor> desc(cx);
-  if (!JS_GetOwnUCPropertyDescriptor(cx, holder, aClassName.get(), &desc)) {
+  if (!JS_GetOwnUCPropertyDescriptor(cx, holder, aClassName.get(),
+                                     aClassName.Length(), &desc)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
   *aNew = !desc.object();
   if (desc.object()) {
     proto = &desc.value().toObject();
     DebugOnly<nsXBLPrototypeBinding*> cachedBinding =
       GetProtoBindingFromClassObject(js::UncheckedUnwrap(proto));
     MOZ_ASSERT(cachedBinding == aProtoBinding);
--- a/dom/xbl/nsXBLProtoImpl.cpp
+++ b/dom/xbl/nsXBLProtoImpl.cpp
@@ -91,37 +91,42 @@ nsXBLProtoImpl::InstallImplementation(ns
   //
   // Note: If |targetIsNew| is false, we'll early-return above. However, that only
   // tells us if the content-side object is new, which may be the case even if
   // we've already set up the binding on the XBL side. For example, if we apply
   // a binding #foo to a <span> when we've already applied it to a <div>, we'll
   // end up with a different content prototype, but we'll already have a property
   // holder called |foo| in the XBL scope. Check for that to avoid wasteful and
   // weird property holder duplication.
-  const char16_t* className = aPrototypeBinding->ClassName().get();
+  const nsString& className = aPrototypeBinding->ClassName();
+  const char16_t* classNameChars = className.get();
+  const size_t classNameLen = className.Length();
+
   JS::Rooted<JSObject*> propertyHolder(cx);
   JS::Rooted<JS::PropertyDescriptor> existingHolder(cx);
   if (scopeObject != globalObject &&
-      !JS_GetOwnUCPropertyDescriptor(cx, scopeObject, className, &existingHolder)) {
+      !JS_GetOwnUCPropertyDescriptor(cx, scopeObject, classNameChars,
+                                     classNameLen, &existingHolder)) {
     return NS_ERROR_FAILURE;
   }
   bool propertyHolderIsNew = !existingHolder.object() || !existingHolder.value().isObject();
 
   if (!propertyHolderIsNew) {
     propertyHolder = &existingHolder.value().toObject();
   } else if (scopeObject != globalObject) {
 
     // This is just a property holder, so it doesn't need any special JSClass.
     propertyHolder = JS_NewObjectWithGivenProto(cx, nullptr, nullptr);
     NS_ENSURE_TRUE(propertyHolder, NS_ERROR_OUT_OF_MEMORY);
 
     // Define it as a property on the scopeObject, using the same name used on
     // the content side.
-    bool ok = JS_DefineUCProperty(cx, scopeObject, className, -1, propertyHolder,
-                                  JSPROP_PERMANENT | JSPROP_READONLY);
+    bool ok =
+      JS_DefineUCProperty(cx, scopeObject, classNameChars, classNameLen,
+                          propertyHolder, JSPROP_PERMANENT | JSPROP_READONLY);
     NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
   } else {
     propertyHolder = targetClassObject;
   }
 
   // Walk our member list and install each one in turn on the XBL scope object.
   if (propertyHolderIsNew) {
     for (nsXBLProtoImplMember* curr = mMembers;
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -2067,20 +2067,20 @@ JS_GetOwnPropertyDescriptor(JSContext* c
     JSAtom* atom = Atomize(cx, name, strlen(name));
     if (!atom)
         return false;
     RootedId id(cx, AtomToId(atom));
     return JS_GetOwnPropertyDescriptorById(cx, obj, id, desc);
 }
 
 JS_PUBLIC_API(bool)
-JS_GetOwnUCPropertyDescriptor(JSContext* cx, HandleObject obj, const char16_t* name,
+JS_GetOwnUCPropertyDescriptor(JSContext* cx, HandleObject obj, const char16_t* name, size_t namelen,
                               MutableHandle<PropertyDescriptor> desc)
 {
-    JSAtom* atom = AtomizeChars(cx, name, js_strlen(name));
+    JSAtom* atom = AtomizeChars(cx, name, namelen);
     if (!atom)
         return false;
     RootedId id(cx, AtomToId(atom));
     return JS_GetOwnPropertyDescriptorById(cx, obj, id, desc);
 }
 
 JS_PUBLIC_API(bool)
 JS_GetPropertyDescriptorById(JSContext* cx, HandleObject obj, HandleId id,
@@ -2093,17 +2093,29 @@ JS_GetPropertyDescriptorById(JSContext* 
 JS_PUBLIC_API(bool)
 JS_GetPropertyDescriptor(JSContext* cx, HandleObject obj, const char* name,
                          MutableHandle<PropertyDescriptor> desc)
 {
     JSAtom* atom = Atomize(cx, name, strlen(name));
     if (!atom)
         return false;
     RootedId id(cx, AtomToId(atom));
-    return atom && JS_GetPropertyDescriptorById(cx, obj, id, desc);
+    return JS_GetPropertyDescriptorById(cx, obj, id, desc);
+}
+
+JS_PUBLIC_API(bool)
+JS_GetUCPropertyDescriptor(JSContext* cx, HandleObject obj, const char16_t* name, size_t namelen,
+                           MutableHandle<PropertyDescriptor> desc)
+{
+    JSAtom* atom = AtomizeChars(cx, name, namelen);
+    if (!atom) {
+        return false;
+    }
+    RootedId id(cx, AtomToId(atom));
+    return JS_GetPropertyDescriptorById(cx, obj, id, desc);
 }
 
 static bool
 DefinePropertyByDescriptor(JSContext* cx, HandleObject obj, HandleId id,
                            Handle<PropertyDescriptor> desc, ObjectOpResult& result)
 {
     AssertHeapIsIdle();
     CHECK_REQUEST(cx);
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2200,33 +2200,37 @@ extern JS_PUBLIC_API(bool)
 JS_GetOwnPropertyDescriptorById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
                                 JS::MutableHandle<JS::PropertyDescriptor> desc);
 
 extern JS_PUBLIC_API(bool)
 JS_GetOwnPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* name,
                             JS::MutableHandle<JS::PropertyDescriptor> desc);
 
 extern JS_PUBLIC_API(bool)
-JS_GetOwnUCPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char16_t* name,
+JS_GetOwnUCPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
                               JS::MutableHandle<JS::PropertyDescriptor> desc);
 
 /**
  * Like JS_GetOwnPropertyDescriptorById, but also searches the prototype chain
  * if no own property is found directly on obj. The object on which the
  * property is found is returned in desc.object(). If the property is not found
  * on the prototype chain, this returns true with desc.object() set to null.
  */
 extern JS_PUBLIC_API(bool)
 JS_GetPropertyDescriptorById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
                              JS::MutableHandle<JS::PropertyDescriptor> desc);
 
 extern JS_PUBLIC_API(bool)
 JS_GetPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* name,
                          JS::MutableHandle<JS::PropertyDescriptor> desc);
 
+extern JS_PUBLIC_API(bool)
+JS_GetUCPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
+                           JS::MutableHandle<JS::PropertyDescriptor> desc);
+
 /**
  * Define a property on obj.
  *
  * This function uses JS::ObjectOpResult to indicate conditions that ES6
  * specifies as non-error failures. This is inconvenient at best, so use this
  * function only if you are implementing a proxy handler's defineProperty()
  * method. For all other purposes, use one of the many DefineProperty functions
  * below that throw an exception in all failure cases.