Open Bug 1767995 Opened 3 years ago Updated 3 years ago

Simplify observable array helpers

Categories

(Core :: DOM: Bindings (WebIDL), task, P3)

task

Tracking

()

People

(Reporter: peterv, Unassigned)

References

Details

We generate a number of helper functions for manipulating the observable array backing objects. These contain a lot of boilerplate which we can probably simplify quite a bit.

For example the ElementAt function for document.adoptedStyleSheets does:

  MOZ_ASSERT(self);
  AutoJSAPI jsapi;
  jsapi.Init();
  JSContext* cx = jsapi.cx();
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
  // all we want is to wrap into _some_ scope and then unwrap to find
  // the reflector, and wrapping has no side-effects.
  JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible);
  if (!scope) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return nullptr;
  }
  JSAutoRealm tempRealm(cx, scope);
  JS::Rooted<JS::Value> v(cx);
  if(!ToJSValue(cx, self, &v)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return nullptr;
  }
  // This is a reflector, but due to trying to name things
  // similarly across method generators, it's called obj here.
  JS::Rooted<JSObject*> obj(cx);
  obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
  JSAutoRealm reflectorRealm(cx, obj);

  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetObservableArrayBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0),
          &backingObj, &created, AdoptedStyleSheets_Binding::ObservableArrayProxyHandler::getInstance())) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return nullptr;
  }
  if (created) {
    PreserveWrapper(self);
    js::SetProxyReservedSlot(backingObj,
                             OBSERVABLE_ARRAY_DOM_INTERFACE_SLOT,
                             JS::PrivateValue(self));
  }

I think this can be simplified to

  JSObject* reflector = self->GetWrapper();
  if (!reflector) {
    return nullptr;
  }
  JSAutoRealm reflectorRealm(cx, reflector);
  JS::Rooted<JS::Value> slotValue(aCx, JS::GetReservedSlot(reflector, DOM_INSTANCE_RESERVED_SLOTS + 0));
  if (slotValue.isUndefined()) {
   return nullptr;
  }

Given some arguments (slot index, native type of the elements) we might even have these as templated non-generated helper functions, and generate a simple inline function that calls them per backing object type.

Severity: -- → S3
Priority: -- → P3
You need to log in before you can comment on or make changes to this bug.