Bug 851917. Get rid of the classinfo for HTMLObjectElement, HTMLEmbedElement, HTMLAppletElement, and rip out nsHTMLPluginObjElementSH. r=peterv,johns
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 10 Apr 2013 13:49:05 -0400
changeset 128352 d1c30a97d22923761769a436aaf777a4e479f8c4
parent 128351 58cc5c8a4e01f389528524d15e7c5deda9dcf4d4
child 128353 35f95339c44c8101c7965dd52ab77ccc50806d74
push id24528
push userryanvm@gmail.com
push dateThu, 11 Apr 2013 19:19:41 +0000
treeherdermozilla-central@7b8ed29c6bc0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv, johns
bugs851917
milestone23.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 851917. Get rid of the classinfo for HTMLObjectElement, HTMLEmbedElement, HTMLAppletElement, and rip out nsHTMLPluginObjElementSH. r=peterv,johns
content/base/public/nsIObjectLoadingContent.idl
content/base/src/nsObjectLoadingContent.cpp
content/base/src/nsObjectLoadingContent.h
content/html/content/src/HTMLObjectElement.cpp
content/html/content/src/HTMLObjectElement.h
content/html/content/src/HTMLSharedObjectElement.cpp
content/html/content/src/HTMLSharedObjectElement.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
dom/base/nsDOMClassInfoClasses.h
--- a/content/base/public/nsIObjectLoadingContent.idl
+++ b/content/base/public/nsIObjectLoadingContent.idl
@@ -20,17 +20,17 @@ interface nsIURI;
 
 /**
  * This interface represents a content node that loads objects.
  *
  * Please make sure to update the MozObjectLoadingContent WebIDL
  * interface to mirror this interface when changing it.
  */
 
-[scriptable, uuid(e2ef99fe-f7d3-422f-a7b4-834e8bdde710)]
+[scriptable, uuid(24a35de3-40e4-498e-9c1b-2fd0a2d4cae5)]
 interface nsIObjectLoadingContent : nsISupports
 {
   /**
    * See notes in nsObjectLoadingContent.h
    */
   const unsigned long TYPE_LOADING  = 0;
   const unsigned long TYPE_IMAGE    = 1;
   const unsigned long TYPE_PLUGIN   = 2;
@@ -145,26 +145,16 @@ interface nsIObjectLoadingContent : nsIS
    * This assumes:
    *  - This tag has not begun loading yet
    *  - This channel has not yet hit OnStartRequest
    *  - The caller will continue to pass channel events to us as a listener
    */
   [noscript] void initializeFromChannel(in nsIRequest request);
 
   /**
-   * Requests the plugin instance for scripting, attempting to spawn it if
-   * appropriate.
-   *
-   * The first time content js tries to access a pre-empted plugin
-   * (click-to-play or play preview), an event is dispatched.
-   */
-  [noscript] nsNPAPIPluginInstancePtr
-    scriptRequestPluginInstance(in bool callerIsContentJS);
-
-  /**
    * The URL of the data/src loaded in the object. This may be null (i.e.
    * an <embed> with no src).
    */
   readonly attribute nsIURI srcURI;
 
   readonly attribute unsigned long pluginFallbackType;
 
   /**
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -70,16 +70,17 @@
 #include "GeckoProfiler.h"
 #include "nsObjectFrame.h"
 #include "nsDOMClassInfo.h"
 #include "nsWrapperCacheInlines.h"
 
 #include "nsWidgetsCID.h"
 #include "nsContentCID.h"
 #include "mozilla/dom/BindingUtils.h"
+#include "mozilla/Telemetry.h"
 
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo*
@@ -2340,29 +2341,40 @@ nsObjectLoadingContent::PluginCrashed(ns
                              submittedCrashReport);
   nsresult rv = NS_DispatchToCurrentThread(ev);
   if (NS_FAILED(rv)) {
     NS_WARNING("failed to dispatch nsPluginCrashedEvent");
   }
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsObjectLoadingContent::ScriptRequestPluginInstance(bool aCallerIsContentJS,
+nsresult
+nsObjectLoadingContent::ScriptRequestPluginInstance(JSContext* aCx,
                                                     nsNPAPIPluginInstance **aResult)
 {
+  // The below methods pull the cx off the stack, so make sure they match.
+  //
+  // NB: Sometimes there's a null cx on the stack, in which case |cx| is the
+  // safe JS context. But in that case, IsCallerChrome() will return true,
+  // so the ensuing expression is short-circuited.
+  MOZ_ASSERT_IF(nsContentUtils::GetCurrentJSContext(),
+                aCx == nsContentUtils::GetCurrentJSContext());
+  bool callerIsContentJS = (!nsContentUtils::IsCallerChrome() &&
+                            !nsContentUtils::IsCallerXBL() &&
+                            js::IsContextRunningJS(aCx));
+
   nsCOMPtr<nsIContent> thisContent =
     do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
 
   *aResult = nullptr;
 
   // The first time content script attempts to access placeholder content, fire
   // an event.  Fallback types >= eFallbackClickToPlay are plugin-replacement
   // types, see header.
-  if (aCallerIsContentJS && !mScriptRequested &&
+  if (callerIsContentJS && !mScriptRequested &&
       InActiveDocument(thisContent) && mType == eType_Null &&
       mFallbackType >= eFallbackClickToPlay) {
     nsCOMPtr<nsIRunnable> ev =
       new nsSimplePluginEvent(thisContent,
                               NS_LITERAL_STRING("PluginScripted"));
     nsresult rv = NS_DispatchToCurrentThread(ev);
     if (NS_FAILED(rv)) {
       NS_NOTREACHED("failed to dispatch PluginScripted event");
@@ -2623,37 +2635,17 @@ nsObjectLoadingContent::NotifyContentObj
 
   JSObject *obj = thisContent->GetWrapper();
   if (!obj) {
     // Nothing to do here if there's no wrapper for mContent. The proto
     // chain will be fixed appropriately when the wrapper is created.
     return;
   }
 
-  JSAutoCompartment ac(cx, obj);
-
-  nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
-  JSObject* canonicalPrototype = nullptr;
-  if (thisContent->IsDOMBinding()) {
-    canonicalPrototype =
-      GetCanonicalPrototype(cx, JS_GetGlobalForObject(cx, obj));
-  } else{
-    nsContentUtils::XPConnect()->
-      GetWrappedNativeOfNativeObject(cx, sgo->GetGlobalJSObject(), thisContent,
-                                     NS_GET_IID(nsISupports),
-                                     getter_AddRefs(wrapper));
-  }
-
-  nsHTMLPluginObjElementSH::SetupProtoChain(cx, obj, wrapper, canonicalPrototype);
-}
-
-JSObject*
-nsObjectLoadingContent::GetCanonicalPrototype(JSContext* aCx, JSObject* aGlobal)
-{
-  return nullptr;
+  SetupProtoChain(cx, obj);
 }
 
 NS_IMETHODIMP
 nsObjectLoadingContent::PlayPlugin()
 {
   if (!nsContentUtils::IsCallerChrome())
     return NS_OK;
 
@@ -2869,58 +2861,207 @@ nsObjectLoadingContent::LegacyCall(JSCon
     }
   }
 
   if (!JS_WrapValue(aCx, &aThisVal)) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return JS::UndefinedValue();
   }
 
-  JS::Value retval;
-  bool otherRetval;
-  nsresult rv =
-    nsHTMLPluginObjElementSH::DoCall(nullptr, aCx, obj, args.Length(),
-                                     args.Elements(), &retval, aThisVal,
-                                     &otherRetval);
+  nsRefPtr<nsNPAPIPluginInstance> pi;
+  nsresult rv = ScriptRequestPluginInstance(aCx, getter_AddRefs(pi));
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return JS::UndefinedValue();
   }
 
-  if (!otherRetval) {
+  // if there's no plugin around for this object, throw.
+  if (!pi) {
+    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+    return JS::UndefinedValue();
+  }
+
+  JSObject *pi_obj;
+  JSObject *pi_proto;
+
+  rv = GetPluginJSObject(aCx, obj, pi, &pi_obj, &pi_proto);
+  if (NS_FAILED(rv)) {
+    aRv.Throw(rv);
+    return JS::UndefinedValue();
+  }
+
+  if (!pi_obj) {
+    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+    return JS::UndefinedValue();
+  }
+
+  JS::Value retval;
+  bool ok = ::JS::Call(aCx, aThisVal, pi_obj, args.Length(),
+                       args.Elements(), &retval);
+  if (!ok) {
     aRv.Throw(NS_ERROR_FAILURE);
     return JS::UndefinedValue();
   }
+
+  Telemetry::Accumulate(Telemetry::PLUGIN_CALLED_DIRECTLY, true);
   return retval;
 }
 
 void
 nsObjectLoadingContent::SetupProtoChain(JSContext* aCx, JSObject* aObject)
 {
+  MOZ_ASSERT(nsCOMPtr<nsIContent>(do_QueryInterface(
+    static_cast<nsIObjectLoadingContent*>(this)))->IsDOMBinding());
+
+  if (mType != eType_Plugin) {
+    return;
+  }
+
+  if (!nsContentUtils::IsSafeToRunScript()) {
+    // This may be null if the JS context is not a DOM context. That's ok, we'll
+    // use the safe context from XPConnect in the runnable.
+    nsCOMPtr<nsIScriptContext> scriptContext = GetScriptContextFromJSContext(aCx);
+
+    nsRefPtr<SetupProtoChainRunner> runner =
+      new SetupProtoChainRunner(scriptContext, this);
+    nsContentUtils::AddScriptRunner(runner);
+    return;
+  }
+
   // We get called on random compartments here for some reason
   // (perhaps because WrapObject can happen on a random compartment?)
   // so make sure to enter the compartment of aObject.
+  MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
+
+  JSAutoRequest ar(aCx);
   JSAutoCompartment ac(aCx, aObject);
-  MOZ_ASSERT(nsCOMPtr<nsIContent>(do_QueryInterface(
-    static_cast<nsIObjectLoadingContent*>(this)))->IsDOMBinding());
-  if (nsContentUtils::IsSafeToRunScript()) {
-    nsHTMLPluginObjElementSH::SetupProtoChain(aCx, aObject, nullptr,
-                                              GetCanonicalPrototype(aCx,
-                                                                    JS_GetGlobalForObject(aCx, aObject)));
+
+  nsRefPtr<nsNPAPIPluginInstance> pi;
+  nsresult rv = ScriptRequestPluginInstance(aCx, getter_AddRefs(pi));
+  if (NS_FAILED(rv)) {
+    return;
+  }
+
+  if (!pi) {
+    // No plugin around for this object.
+    return;
+  }
+
+  JSObject *pi_obj; // XPConnect-wrapped peer object, when we get it.
+  JSObject *pi_proto; // 'pi.__proto__'
+
+  rv = GetPluginJSObject(aCx, aObject, pi, &pi_obj, &pi_proto);
+  if (NS_FAILED(rv)) {
+    return;
+  }
+
+  if (!pi_obj) {
+    // Didn't get a plugin instance JSObject, nothing we can do then.
+    return;
+  }
+
+  // If we got an xpconnect-wrapped plugin object, set obj's
+  // prototype's prototype to the scriptable plugin.
+
+  JSObject *my_proto =
+    GetDOMClass(aObject)->mGetProto(aCx, JS_GetGlobalForObject(aCx, aObject));
+  MOZ_ASSERT(my_proto);
+
+  // Set 'this.__proto__' to pi
+  if (!::JS_SetPrototype(aCx, aObject, pi_obj)) {
+    return;
+  }
+
+  if (pi_proto && js::GetObjectClass(pi_proto) != &js::ObjectClass) {
+    // The plugin wrapper has a proto that's not Object.prototype, set
+    // 'pi.__proto__.__proto__' to the original 'this.__proto__'
+    if (pi_proto != my_proto && !::JS_SetPrototype(aCx, pi_proto, my_proto)) {
+      return;
+    }
   } else {
-    // This may be null if the JS context is not a DOM context. That's ok, we'll
-    // use the safe context from XPConnect in the runnable.
-    nsCOMPtr<nsIScriptContext> scriptContext = GetScriptContextFromJSContext(aCx);
-
-    nsRefPtr<nsHTMLPluginObjElementSH::SetupProtoChainRunner> runner =
-      new nsHTMLPluginObjElementSH::SetupProtoChainRunner(nullptr,
-                                                          scriptContext,
-                                                          this);
-    nsContentUtils::AddScriptRunner(runner);
+    // 'pi' didn't have a prototype, or pi's proto was
+    // 'Object.prototype' (i.e. pi is an NPRuntime wrapped JS object)
+    // set 'pi.__proto__' to the original 'this.__proto__'
+    if (!::JS_SetPrototype(aCx, pi_obj, my_proto)) {
+      return;
+    }
   }
+
+  // Before this proto dance the objects involved looked like this:
+  //
+  // this.__proto__.__proto__
+  //   ^      ^         ^
+  //   |      |         |__ Object.prototype
+  //   |      |
+  //   |      |__ WebIDL prototype (shared)
+  //   |
+  //   |__ WebIDL object
+  //
+  // pi.__proto__
+  // ^      ^
+  // |      |__ Object.prototype or some other object
+  // |
+  // |__ Plugin NPRuntime JS object wrapper
+  //
+  // Now, after the above prototype setup the prototype chain should
+  // look like this if pi.__proto__ was Object.prototype:
+  //
+  // this.__proto__.__proto__.__proto__
+  //   ^      ^         ^         ^
+  //   |      |         |         |__ Object.prototype
+  //   |      |         |
+  //   |      |         |__ WebIDL prototype (shared)
+  //   |      |
+  //   |      |__ Plugin NPRuntime JS object wrapper
+  //   |
+  //   |__ WebIDL object
+  //
+  // or like this if pi.__proto__ was some other object:
+  //
+  // this.__proto__.__proto__.__proto__.__proto__
+  //   ^      ^         ^         ^         ^
+  //   |      |         |         |         |__ Object.prototype
+  //   |      |         |         |
+  //   |      |         |         |__ WebIDL prototype (shared)
+  //   |      |         |
+  //   |      |         |__ old pi.__proto__
+  //   |      |
+  //   |      |__ Plugin NPRuntime JS object wrapper
+  //   |
+  //   |__ WebIDL object
+  //
+}
+
+// static
+nsresult
+nsObjectLoadingContent::GetPluginJSObject(JSContext *cx, JSObject *obj,
+                                          nsNPAPIPluginInstance *plugin_inst,
+                                          JSObject **plugin_obj,
+                                          JSObject **plugin_proto)
+{
+  *plugin_obj = nullptr;
+  *plugin_proto = nullptr;
+
+  JSAutoRequest ar(cx);
+
+  // NB: We need an AutoEnterCompartment because we can be called from
+  // nsObjectFrame when the plugin loads after the JS object for our content
+  // node has been created.
+  JSAutoCompartment ac(cx, obj);
+
+  if (plugin_inst) {
+    plugin_inst->GetJSObject(cx, plugin_obj);
+    if (*plugin_obj) {
+      if (!::JS_GetPrototype(cx, *plugin_obj, plugin_proto)) {
+        return NS_ERROR_UNEXPECTED;
+      }
+    }
+  }
+
+  return NS_OK;
 }
 
 void
 nsObjectLoadingContent::TeardownProtoChain()
 {
   nsCOMPtr<nsIContent> thisContent =
     do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
 
@@ -2965,20 +3106,50 @@ nsObjectLoadingContent::TeardownProtoCha
 
 bool
 nsObjectLoadingContent::DoNewResolve(JSContext* aCx, JSHandleObject aObject,
                                      JSHandleId aId, unsigned aFlags,
                                      JSMutableHandleObject aObjp)
 {
   // We don't resolve anything; we just try to make sure we're instantiated
 
-  bool callerIsContentJS = (!nsContentUtils::IsCallerChrome() &&
-                            !nsContentUtils::IsCallerXBL() &&
-                            js::IsContextRunningJS(aCx));
-
   nsRefPtr<nsNPAPIPluginInstance> pi;
-  nsresult rv = ScriptRequestPluginInstance(callerIsContentJS,
-                                            getter_AddRefs(pi));
+  nsresult rv = ScriptRequestPluginInstance(aCx, getter_AddRefs(pi));
   if (NS_FAILED(rv)) {
     return mozilla::dom::Throw<true>(aCx, rv);
   }
   return true;
 }
+
+// SetupProtoChainRunner implementation
+nsObjectLoadingContent::SetupProtoChainRunner::SetupProtoChainRunner(
+    nsIScriptContext* scriptContext,
+    nsObjectLoadingContent* aContent)
+  : mContext(scriptContext)
+  , mContent(aContent)
+{
+}
+
+NS_IMETHODIMP
+nsObjectLoadingContent::SetupProtoChainRunner::Run()
+{
+  // XXXbz Does it really matter what JSContext we use here?  Seems
+  // like we could just always use the safe context....
+  nsCxPusher pusher;
+  JSContext* cx = mContext ? mContext->GetNativeContext()
+                           : nsContentUtils::GetSafeJSContext();
+  pusher.Push(cx);
+
+  nsCOMPtr<nsIContent> content;
+  CallQueryInterface(mContent.get(), getter_AddRefs(content));
+  JSObject* obj = content->GetWrapper();
+  if (!obj) {
+    // No need to set up our proto chain if we don't even have an object
+    return NS_OK;
+  }
+  nsObjectLoadingContent* objectLoadingContent =
+    static_cast<nsObjectLoadingContent*>(mContent.get());
+  objectLoadingContent->SetupProtoChain(cx, obj);
+  return NS_OK;
+}
+
+NS_IMPL_ISUPPORTS1(nsObjectLoadingContent::SetupProtoChainRunner, nsIRunnable)
+
--- a/content/base/src/nsObjectLoadingContent.h
+++ b/content/base/src/nsObjectLoadingContent.h
@@ -131,32 +131,23 @@ class nsObjectLoadingContent : public ns
     void NotifyOwnerDocumentActivityChanged();
 
     /**
      * When a plug-in is instantiated, it can create a scriptable
      * object that the page wants to interact with.  We expose this
      * object by placing it on the prototype chain of our element,
      * between the element itself and its most-derived DOM prototype.
      *
-     * GetCanonicalPrototype returns this most-derived DOM prototype.
-     *
      * SetupProtoChain handles actually inserting the plug-in
      * scriptable object into the proto chain if needed.
      *
      * DoNewResolve is a hook that allows us to find out when the web
      * page is looking up a property name on our object and make sure
      * that our plug-in, if any, is instantiated.
      */
-
-    /**
-     * Get the canonical prototype for this content for the given global.  Only
-     * returns non-null for objects that are on WebIDL bindings.
-     */
-    virtual JSObject* GetCanonicalPrototype(JSContext* aCx, JSObject* aGlobal);
-
     // Helper for WebIDL node wrapping
     void SetupProtoChain(JSContext* aCx, JSObject* aObject);
 
     // Remove plugin from protochain
     void TeardownProtoChain();
 
     // Helper for WebIDL newResolve
     bool DoNewResolve(JSContext* aCx, JSHandleObject aObject, JSHandleId aId,
@@ -438,16 +429,44 @@ class nsObjectLoadingContent : public ns
     ObjectType GetTypeOfContent(const nsCString& aMIMEType);
 
     /**
      * Gets the frame that's associated with this content node.
      * Does not flush.
      */
     nsObjectFrame* GetExistingFrame();
 
+    // Helper class for SetupProtoChain
+    class SetupProtoChainRunner MOZ_FINAL : public nsIRunnable
+    {
+    public:
+      NS_DECL_ISUPPORTS
+
+      SetupProtoChainRunner(nsIScriptContext* scriptContext,
+                            nsObjectLoadingContent* aContent);
+
+      NS_IMETHOD Run();
+
+    private:
+      nsCOMPtr<nsIScriptContext> mContext;
+      // We store an nsIObjectLoadingContent because we can
+      // unambiguously refcount that.
+      nsRefPtr<nsIObjectLoadingContent> mContent;
+    };
+
+    // Utility getter for getting our nsNPAPIPluginInstance in a safe way.
+    nsresult ScriptRequestPluginInstance(JSContext* aCx,
+                                         nsNPAPIPluginInstance** aResult);
+
+    // Utility method for getting our plugin JSObject
+    static nsresult GetPluginJSObject(JSContext *cx, JSObject *obj,
+                                      nsNPAPIPluginInstance *plugin_inst,
+                                      JSObject **plugin_obj,
+                                      JSObject **plugin_proto);
+
     // The final listener for mChannel (uriloader, pluginstreamlistener, etc.)
     nsCOMPtr<nsIStreamListener> mFinalListener;
 
     // Frame loader, for content documents we load.
     nsRefPtr<nsFrameLoader>     mFrameLoader;
 
     // Track if we have a pending AsyncInstantiateEvent
     nsCOMPtr<nsIRunnable>       mPendingInstantiateEvent;
--- a/content/html/content/src/HTMLObjectElement.cpp
+++ b/content/html/content/src/HTMLObjectElement.cpp
@@ -91,17 +91,17 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION
     NS_INTERFACE_TABLE_ENTRY(HTMLObjectElement, imgIOnloadBlocker)
     NS_INTERFACE_TABLE_ENTRY(HTMLObjectElement, nsIInterfaceRequestor)
     NS_INTERFACE_TABLE_ENTRY(HTMLObjectElement, nsIChannelEventSink)
     NS_INTERFACE_TABLE_ENTRY(HTMLObjectElement, nsIConstraintValidation)
     NS_INTERFACE_TABLE_ENTRY(HTMLObjectElement, nsIDOMGetSVGDocument)
   NS_OFFSET_AND_INTERFACE_TABLE_END
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(HTMLObjectElement,
                                                nsGenericHTMLFormElement)
-NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLObjectElement)
+NS_HTML_CONTENT_INTERFACE_MAP_END
 
 NS_IMPL_ELEMENT_CLONE(HTMLObjectElement)
 
 // nsIConstraintValidation
 NS_IMPL_NSICONSTRAINTVALIDATION(HTMLObjectElement)
 
 NS_IMETHODIMP
 HTMLObjectElement::GetForm(nsIDOMHTMLFormElement **aForm)
@@ -458,20 +458,12 @@ HTMLObjectElement::WrapNode(JSContext* a
   JSObject* obj = HTMLObjectElementBinding::Wrap(aCx, aScope, this);
   if (!obj) {
     return nullptr;
   }
   SetupProtoChain(aCx, obj);
   return obj;
 }
 
-JSObject*
-HTMLObjectElement::GetCanonicalPrototype(JSContext* aCx, JSObject* aGlobal)
-{
-  return HTMLObjectElementBinding::GetProtoObject(aCx, aGlobal);
-}
-
 } // namespace dom
 } // namespace mozilla
 
-DOMCI_NODE_DATA(HTMLObjectElement, mozilla::dom::HTMLObjectElement)
-
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Object)
--- a/content/html/content/src/HTMLObjectElement.h
+++ b/content/html/content/src/HTMLObjectElement.h
@@ -91,18 +91,16 @@ public:
 
   nsresult CopyInnerTo(Element* aDest);
 
   void StartObjectLoad() { StartObjectLoad(true); }
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLObjectElement,
                                            nsGenericHTMLFormElement)
 
-  virtual nsXPCClassInfo* GetClassInfo();
-
   virtual nsIDOMNode* AsDOMNode() { return this; }
 
   // Web IDL binding methods
   // XPCOM GetData is ok; note that it's a URI attribute with a weird base URI
   void SetData(const nsAString& aValue, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::data, aValue, aRv);
   }
@@ -241,18 +239,16 @@ private:
    * value. This is used to know the default tabindex value.
    */
   bool IsFocusableForTabIndex();
   
   virtual void GetItemValueText(nsAString& text);
   virtual void SetItemValueText(const nsAString& text);
 
   virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope) MOZ_OVERRIDE;
-  virtual JSObject* GetCanonicalPrototype(JSContext* aCx,
-                                          JSObject* aGlobal) MOZ_OVERRIDE;
 
   bool mIsDoneAddingChildren;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_HTMLObjectElement_h
--- a/content/html/content/src/HTMLSharedObjectElement.cpp
+++ b/content/html/content/src/HTMLSharedObjectElement.cpp
@@ -15,19 +15,16 @@
 #include "nsThreadUtils.h"
 #include "nsIDOMSVGDocument.h"
 #include "nsIScriptError.h"
 #include "nsIWidget.h"
 #include "nsContentUtils.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(SharedObject)
 
-DOMCI_DATA(HTMLAppletElement, mozilla::dom::HTMLSharedObjectElement)
-DOMCI_DATA(HTMLEmbedElement, mozilla::dom::HTMLSharedObjectElement)
-
 namespace mozilla {
 namespace dom {
 
 HTMLSharedObjectElement::HTMLSharedObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                                                  FromParser aFromParser)
   : nsGenericHTMLElement(aNodeInfo),
     mIsDoneAddingChildren(mNodeInfo->Equals(nsGkAtoms::embed) || !aFromParser)
 {
@@ -89,28 +86,16 @@ HTMLSharedObjectElement::DoneAddingChild
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLSharedObjectElement,
                                                   nsGenericHTMLElement)
   nsObjectLoadingContent::Traverse(tmp, cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(HTMLSharedObjectElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLSharedObjectElement, Element)
 
-nsIClassInfo*
-HTMLSharedObjectElement::GetClassInfoInternal()
-{
-  if (mNodeInfo->Equals(nsGkAtoms::applet)) {
-    return NS_GetDOMClassInfoInstance(eDOMClassInfo_HTMLAppletElement_id);
-  }
-  if (mNodeInfo->Equals(nsGkAtoms::embed)) {
-    return NS_GetDOMClassInfoInstance(eDOMClassInfo_HTMLEmbedElement_id);
-  }
-  return nullptr;
-}
-
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLSharedObjectElement)
   NS_HTML_CONTENT_INTERFACE_TABLE_AMBIGUOUS_BEGIN(HTMLSharedObjectElement,
                                                   nsIDOMHTMLAppletElement)
     NS_INTERFACE_TABLE_ENTRY(HTMLSharedObjectElement, nsIRequestObserver)
     NS_INTERFACE_TABLE_ENTRY(HTMLSharedObjectElement, nsIStreamListener)
     NS_INTERFACE_TABLE_ENTRY(HTMLSharedObjectElement, nsIFrameLoaderOwner)
     NS_INTERFACE_TABLE_ENTRY(HTMLSharedObjectElement, nsIObjectLoadingContent)
     NS_INTERFACE_TABLE_ENTRY(HTMLSharedObjectElement, imgINotificationObserver)
@@ -120,17 +105,16 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION
     NS_INTERFACE_TABLE_ENTRY(HTMLSharedObjectElement, nsIChannelEventSink)
   NS_OFFSET_AND_INTERFACE_TABLE_END
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE_AMBIGUOUS(HTMLSharedObjectElement,
                                                          nsGenericHTMLElement,
                                                          nsIDOMHTMLAppletElement)
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLAppletElement, applet)
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLEmbedElement, embed)
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMGetSVGDocument, embed)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_GETTER(GetClassInfoInternal)
 NS_HTML_CONTENT_INTERFACE_MAP_END
 
 NS_IMPL_ELEMENT_CLONE(HTMLSharedObjectElement)
 
 nsresult
 HTMLSharedObjectElement::BindToTree(nsIDocument *aDocument,
                                     nsIContent *aParent,
                                     nsIContent *aBindingParent,
@@ -377,20 +361,10 @@ HTMLSharedObjectElement::WrapNode(JSCont
   }
   if (!obj) {
     return nullptr;
   }
   SetupProtoChain(aCx, obj);
   return obj;
 }
 
-JSObject*
-HTMLSharedObjectElement::GetCanonicalPrototype(JSContext* aCx, JSObject* aGlobal)
-{
-  if (mNodeInfo->Equals(nsGkAtoms::applet)) {
-    return HTMLAppletElementBinding::GetProtoObject(aCx, aGlobal);
-  }
-  MOZ_ASSERT(mNodeInfo->Equals(nsGkAtoms::embed));
-  return HTMLEmbedElementBinding::GetProtoObject(aCx, aGlobal);
-}
-
 } // namespace dom
 } // namespace mozilla
--- a/content/html/content/src/HTMLSharedObjectElement.h
+++ b/content/html/content/src/HTMLSharedObjectElement.h
@@ -89,22 +89,16 @@ public:
 
   nsresult CopyInnerTo(Element* aDest);
 
   void StartObjectLoad() { StartObjectLoad(true); }
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(HTMLSharedObjectElement,
                                                      nsGenericHTMLElement)
 
-  virtual nsXPCClassInfo* GetClassInfo()
-  {
-    return static_cast<nsXPCClassInfo*>(GetClassInfoInternal());
-  }
-  nsIClassInfo* GetClassInfoInternal();
-
   virtual nsIDOMNode* AsDOMNode()
   {
     return static_cast<nsIDOMHTMLAppletElement*>(this);
   }
 
   // WebIDL API for <applet>
   void GetAlign(DOMString& aValue)
   {
@@ -241,16 +235,14 @@ private:
   // mIsDoneAddingChildren is only really used for <applet>.  This boolean is
   // always true for <embed>, per the documentation in nsIContent.h.
   bool mIsDoneAddingChildren;
 
   virtual void GetItemValueText(nsAString& text);
   virtual void SetItemValueText(const nsAString& text);
 
   virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope) MOZ_OVERRIDE;
-  virtual JSObject* GetCanonicalPrototype(JSContext* aCx,
-                                          JSObject* aGlobal) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_HTMLSharedObjectElement_h
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -114,22 +114,16 @@
 #include "nsHTMLDocument.h"
 
 // Constraint Validation API helper includes
 #include "nsIDOMValidityState.h"
 
 // HTMLSelectElement helper includes
 #include "nsIDOMHTMLSelectElement.h"
 
-// HTMLEmbed/ObjectElement helper includes
-#include "nsNPAPIPluginInstance.h"
-#include "nsIObjectFrame.h"
-#include "nsObjectLoadingContent.h"
-#include "nsIPluginHost.h"
-
 #include "nsIDOMHTMLOptionElement.h"
 
 // Event related includes
 #include "nsEventListenerManager.h"
 #include "nsIDOMEventTarget.h"
 
 // CSS related includes
 #include "nsCSSRules.h"
@@ -187,22 +181,19 @@
 #include "nsIDOMNotifyAudioAvailableEvent.h"
 #include "nsIDOMScrollAreaEvent.h"
 #include "nsIDOMTransitionEvent.h"
 #include "nsIDOMAnimationEvent.h"
 #include "nsIDOMDocumentXBL.h"
 #include "nsIDOMElementCSSInlineStyle.h"
 #include "nsIDOMLinkStyle.h"
 #include "nsIDOMHTMLDocument.h"
-#include "nsIDOMHTMLAppletElement.h"
 #include "nsIDOMHTMLCanvasElement.h"
-#include "nsIDOMHTMLEmbedElement.h"
 #include "nsIDOMHTMLIFrameElement.h"
 #include "nsIDOMHTMLInputElement.h"
-#include "nsIDOMHTMLObjectElement.h"
 #include "nsIDOMCSSCharsetRule.h"
 #include "nsIDOMCSSImportRule.h"
 #include "nsIDOMCSSMediaRule.h"
 #include "nsIDOMCSSFontFaceRule.h"
 #include "nsIDOMCSSMozDocumentRule.h"
 #include "nsIDOMCSSSupportsRule.h"
 #include "nsIDOMMozCSSKeyframeRule.h"
 #include "nsIDOMMozCSSKeyframesRule.h"
@@ -413,24 +404,16 @@ static const char kDOMStringBundleURL[] 
 // the classinfo since XBL can be used to dynamically implement new
 // unknown interfaces on elements, accessibility relies on this being
 // possible.
 
 #define ELEMENT_SCRIPTABLE_FLAGS                                              \
   ((NODE_SCRIPTABLE_FLAGS & ~nsIXPCScriptable::CLASSINFO_INTERFACES_ONLY) |   \
    nsIXPCScriptable::WANT_POSTCREATE)
 
-#define EXTERNAL_OBJ_SCRIPTABLE_FLAGS                                         \
-  ((ELEMENT_SCRIPTABLE_FLAGS &                                                \
-    ~nsIXPCScriptable::USE_JSSTUB_FOR_SETPROPERTY) |                          \
-   nsIXPCScriptable::WANT_POSTCREATE |                                        \
-   nsIXPCScriptable::WANT_GETPROPERTY |                                       \
-   nsIXPCScriptable::WANT_SETPROPERTY |                                       \
-   nsIXPCScriptable::WANT_CALL)
-
 #define DOCUMENT_SCRIPTABLE_FLAGS                                             \
   (NODE_SCRIPTABLE_FLAGS |                                                    \
    nsIXPCScriptable::WANT_POSTCREATE |                                        \
    nsIXPCScriptable::WANT_ENUMERATE)
 
 #define ARRAY_SCRIPTABLE_FLAGS                                                \
   (DOM_DEFAULT_SCRIPTABLE_FLAGS       |                                       \
    nsIXPCScriptable::WANT_GETPROPERTY |                                       \
@@ -651,30 +634,24 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(DeviceRotationRate, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   // Misc HTML classes
   NS_DEFINE_CLASSINFO_DATA(HTMLDocument, nsHTMLDocumentSH,
                            DOCUMENT_SCRIPTABLE_FLAGS |
                            nsIXPCScriptable::WANT_GETPROPERTY)
   // HTML element classes
-  NS_DEFINE_CLASSINFO_DATA(HTMLAppletElement, nsHTMLPluginObjElementSH,
-                           EXTERNAL_OBJ_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(HTMLEmbedElement, nsHTMLPluginObjElementSH,
-                           EXTERNAL_OBJ_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLFormElement, nsHTMLFormElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS |
                            nsIXPCScriptable::WANT_GETPROPERTY |
                            nsIXPCScriptable::WANT_NEWENUMERATE)
   NS_DEFINE_CLASSINFO_DATA(HTMLIFrameElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLInputElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(HTMLObjectElement, nsHTMLPluginObjElementSH,
-                           EXTERNAL_OBJ_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLSelectElement, nsHTMLSelectElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS |
                            nsIXPCScriptable::WANT_SETPROPERTY |
                            nsIXPCScriptable::WANT_GETPROPERTY)
 
   // Constraint Validation API classes
   NS_DEFINE_CLASSINFO_DATA(ValidityState, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -1945,27 +1922,16 @@ nsDOMClassInfo::Init()
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLDocument, nsIDOMHTMLDocument)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLDocument)
     DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIDocumentRegister,
                                         nsDocument::RegisterEnabled())
     DOM_CLASSINFO_DOCUMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN(HTMLAppletElement, nsIDOMHTMLAppletElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLAppletElement)
-    DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
-  DOM_CLASSINFO_MAP_END
-
-  DOM_CLASSINFO_MAP_BEGIN(HTMLEmbedElement, nsIDOMHTMLEmbedElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLEmbedElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMGetSVGDocument)
-    DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
-  DOM_CLASSINFO_MAP_END
-
   DOM_CLASSINFO_MAP_BEGIN(HTMLFormElement, nsIDOMHTMLFormElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLFormElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLIFrameElement, nsIDOMHTMLIFrameElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLIFrameElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMGetSVGDocument)
@@ -1973,22 +1939,16 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLInputElement, nsIDOMHTMLInputElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLInputElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN(HTMLObjectElement, nsIDOMHTMLObjectElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLObjectElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMGetSVGDocument)
-    DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
-  DOM_CLASSINFO_MAP_END
-
   DOM_CLASSINFO_MAP_BEGIN(HTMLSelectElement, nsIDOMHTMLSelectElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLSelectElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(ValidityState, nsIDOMValidityState)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMValidityState)
   DOM_CLASSINFO_MAP_END
@@ -7367,415 +7327,16 @@ nsHTMLSelectElementSH::SetProperty(nsIXP
 
     nsresult rv = SetOption(cx, vp, n, options);
     return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING;
   }
 
   return NS_OK;
 }
 
-
-// HTMLObject/EmbedElement helper
-// Keep in mind that it is OK for this to fail to return an instance. Don't return a
-// failure result unless something truly exceptional has happened.
-// static
-nsresult
-nsHTMLPluginObjElementSH::GetPluginInstanceIfSafe(nsIXPConnectWrappedNative *wrapper,
-                                                  JSObject *obj,
-                                                  JSContext *cx,
-                                                  nsNPAPIPluginInstance **_result)
-{
-  *_result = nullptr;
-
-  nsCOMPtr<nsIContent> content;
-  if (wrapper) {
-    content = do_QueryWrappedNative(wrapper, obj);
-  } else {
-    nsISupports* supports;
-    if (XPCConvert::GetISupportsFromJSObject(obj, &supports)) {
-      content = do_QueryInterface(supports);
-    }
-  }
-  NS_ENSURE_TRUE(content, NS_ERROR_UNEXPECTED);
-
-  nsCOMPtr<nsIObjectLoadingContent> objlc(do_QueryInterface(content));
-  NS_ASSERTION(objlc, "Object nodes must implement nsIObjectLoadingContent");
-
-  // The below methods pull the cx off the stack, so make sure they match.
-  //
-  // NB: Sometimes there's a null cx on the stack, in which case |cx| is the
-  // safe JS context. But in that case, IsCallerChrome() will return true,
-  // so the ensuing expression is short-circuited.
-  MOZ_ASSERT_IF(nsContentUtils::GetCurrentJSContext(),
-                cx == nsContentUtils::GetCurrentJSContext());
-
-  bool callerIsContentJS = (!nsContentUtils::IsCallerChrome() &&
-                            !nsContentUtils::IsCallerXBL() &&
-                            js::IsContextRunningJS(cx));
-  return objlc->ScriptRequestPluginInstance(callerIsContentJS,
-                                            _result);
-}
-
-nsHTMLPluginObjElementSH::SetupProtoChainRunner::SetupProtoChainRunner(
-    nsIXPConnectWrappedNative* aWrapper,
-    nsIScriptContext* aScriptContext,
-    nsObjectLoadingContent* aContent)
-  : mWrapper(aWrapper)
-  , mContext(aScriptContext)
-  , mContent(aContent)
-{
-}
-
-NS_IMETHODIMP
-nsHTMLPluginObjElementSH::SetupProtoChainRunner::Run()
-{
-  nsCxPusher pusher;
-  JSContext* cx = mContext ? mContext->GetNativeContext()
-                           : nsContentUtils::GetSafeJSContext();
-  pusher.Push(cx);
-
-  JSObject* obj = nullptr;
-  JSObject* canonicalProto = nullptr;
-  if (mWrapper) {
-    mWrapper->GetJSObject(&obj);
-    NS_ASSERTION(obj, "Should never be null");
-  } else {
-    MOZ_ASSERT(mContent, "Must have mContent if no mWrapper");
-    nsCOMPtr<nsIContent> content;
-    CallQueryInterface(mContent.get(), getter_AddRefs(content));
-    obj = content->GetWrapper();
-    if (!obj) {
-      // No need to set up our proto chain if we don't even have an object
-      return NS_OK;
-    }
-    JSAutoCompartment ac(cx, obj);
-    canonicalProto = static_cast<nsObjectLoadingContent*>(mContent.get())->
-      GetCanonicalPrototype(cx, JS_GetGlobalForObject(cx, obj));
-  }
-  nsHTMLPluginObjElementSH::SetupProtoChain(cx, obj, mWrapper, canonicalProto);
-  return NS_OK;
-}
-
-NS_IMPL_ISUPPORTS1(nsHTMLPluginObjElementSH::SetupProtoChainRunner, nsIRunnable)
-
-// static
-nsresult
-nsHTMLPluginObjElementSH::SetupProtoChain(JSContext *cx,
-                                          JSObject *obj,
-                                          nsIXPConnectWrappedNative *wrapper,
-                                          JSObject* aCanonicalPrototype)
-{
-  NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),
-               "Shouldn't have gotten in here");
-  MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
-
-  JSAutoRequest ar(cx);
-  JSAutoCompartment ac(cx, obj);
-
-  nsRefPtr<nsNPAPIPluginInstance> pi;
-  nsresult rv = GetPluginInstanceIfSafe(wrapper, obj, cx, getter_AddRefs(pi));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (!pi) {
-    // No plugin around for this object.
-
-    return NS_OK;
-  }
-
-  JSObject *pi_obj = nullptr; // XPConnect-wrapped peer object, when we get it.
-  JSObject *pi_proto = nullptr; // 'pi.__proto__'
-
-  rv = GetPluginJSObject(cx, obj, pi, &pi_obj, &pi_proto);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (!pi_obj) {
-    // Didn't get a plugin instance JSObject, nothing we can do then.
-    return NS_OK;
-  }
-
-  // If we got an xpconnect-wrapped plugin object, set obj's
-  // prototype's prototype to the scriptable plugin.
-
-  JSObject *my_proto = nullptr;
-
-  if (wrapper) {
-    // Get 'this.__proto__'
-    rv = wrapper->GetJSObjectPrototype(&my_proto);
-    NS_ENSURE_SUCCESS(rv, rv);
-  } else {
-    my_proto = aCanonicalPrototype;
-  }
-  MOZ_ASSERT(my_proto);
-
-  // Set 'this.__proto__' to pi
-  if (!::JS_SetPrototype(cx, obj, pi_obj)) {
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  if (pi_proto && JS_GetClass(pi_proto) != sObjectClass) {
-    // The plugin wrapper has a proto that's not Object.prototype, set
-    // 'pi.__proto__.__proto__' to the original 'this.__proto__'
-    if (pi_proto != my_proto && !::JS_SetPrototype(cx, pi_proto, my_proto)) {
-      return NS_ERROR_UNEXPECTED;
-    }
-  } else {
-    // 'pi' didn't have a prototype, or pi's proto was
-    // 'Object.prototype' (i.e. pi is an NPRuntime wrapped JS object)
-    // set 'pi.__proto__' to the original 'this.__proto__'
-    if (!::JS_SetPrototype(cx, pi_obj, my_proto)) {
-      return NS_ERROR_UNEXPECTED;
-    }
-  }
-
-  // Before this proto dance the objects involved looked like this:
-  //
-  // this.__proto__.__proto__
-  //   ^      ^         ^
-  //   |      |         |__ Object.prototype
-  //   |      |
-  //   |      |__ xpc embed wrapper proto (shared)
-  //   |
-  //   |__ xpc wrapped native embed node
-  //
-  // pi.__proto__
-  // ^      ^
-  // |      |__ Object.prototype
-  // |
-  // |__ Plugin NPRuntime JS object wrapper
-  //
-  // Now, after the above prototype setup the prototype chain should
-  // look like this:
-  //
-  // this.__proto__.__proto__.__proto__
-  //   ^      ^         ^         ^
-  //   |      |         |         |__ Object.prototype
-  //   |      |         |
-  //   |      |         |__ xpc embed wrapper proto (shared)
-  //   |      |
-  //   |      |__ Plugin NPRuntime JS object wrapper
-  //   |
-  //   |__ xpc wrapped native embed node
-  //
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsHTMLPluginObjElementSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
-                                    JSObject *globalObj, JSObject **parentObj)
-{
-  nsresult rv = nsElementSH::PreCreate(nativeObj, cx, globalObj, parentObj);
-
-  // For now we don't support slim wrappers for plugins.
-  return rv == NS_SUCCESS_ALLOW_SLIM_WRAPPERS ? NS_OK : rv;
-}
-
-NS_IMETHODIMP
-nsHTMLPluginObjElementSH::PostCreate(nsIXPConnectWrappedNative *wrapper,
-                                     JSContext *cx, JSObject *obj)
-{
-  if (nsContentUtils::IsSafeToRunScript()) {
-#ifdef DEBUG
-    nsresult rv =
-#endif
-      SetupProtoChain(cx, obj, wrapper);
-
-    // If SetupProtoChain failed then we're in real trouble. We're about to fail
-    // PostCreate but it's more than likely that we handed our (now invalid)
-    // wrapper to someone already. Bug 429442 is an example of the kind of crash
-    // that can result from such a situation. We'll return NS_OK for the time
-    // being and hope for the best.
-    NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "SetupProtoChain failed!");
-  }
-  else {
-    // This may be null if the JS context is not a DOM context. That's ok, we'll
-    // use the safe context from XPConnect in the runnable.
-    nsCOMPtr<nsIScriptContext> scriptContext = GetScriptContextFromJSContext(cx);
-
-    nsRefPtr<SetupProtoChainRunner> runner =
-      new SetupProtoChainRunner(wrapper, scriptContext, nullptr);
-    nsContentUtils::AddScriptRunner(runner);
-  }
-
-  return nsElementSH::PostCreate(wrapper, cx, obj);
-}
-
-NS_IMETHODIMP
-nsHTMLPluginObjElementSH::PostTransplant(nsIXPConnectWrappedNative *wrapper,
-                                         JSContext *cx, JSObject *obj)
-{
-  // Call through to PostCreate to do the prototype setup all over again. We
-  // may reuse the same prototype, in which case our prototype will be a wrapped
-  // version of the original.
-  nsresult rv = PostCreate(wrapper, cx, obj);
-  if (NS_FAILED(rv)) {
-      NS_WARNING("Calling PostCreate during PostTransplant for plugin element failed.");
-  }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsHTMLPluginObjElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
-                                      JSContext *cx, JSObject *obj, jsid id,
-                                      jsval *vp, bool *_retval)
-{
-  JSAutoRequest ar(cx);
-
-  JSObject *pi_obj;
-  if (!::JS_GetPrototype(cx, obj, &pi_obj)) {
-    return NS_ERROR_UNEXPECTED;
-  }
-  if (MOZ_UNLIKELY(!pi_obj)) {
-    return NS_OK;
-  }
-
-  JSBool found = false;
-
-  if (!ObjectIsNativeWrapper(cx, obj)) {
-    *_retval = ::JS_HasPropertyById(cx, pi_obj, id, &found);
-    if (!*_retval) {
-      return NS_ERROR_UNEXPECTED;
-    }
-  }
-
-  if (found) {
-    *_retval = ::JS_GetPropertyById(cx, pi_obj, id, vp);
-    return *_retval ? NS_SUCCESS_I_DID_SOMETHING : NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsHTMLPluginObjElementSH::SetProperty(nsIXPConnectWrappedNative *wrapper,
-                                      JSContext *cx, JSObject *obj, jsid id,
-                                      jsval *vp, bool *_retval)
-{
-  JSAutoRequest ar(cx);
-
-  JSObject *pi_obj;
-  if (!::JS_GetPrototype(cx, obj, &pi_obj)) {
-    return NS_ERROR_UNEXPECTED;
-  }
-  if (MOZ_UNLIKELY(!pi_obj)) {
-    return NS_OK;
-  }
-
-  JSBool found = false;
-
-  if (!ObjectIsNativeWrapper(cx, obj)) {
-    *_retval = ::JS_HasPropertyById(cx, pi_obj, id, &found);
-    if (!*_retval) {
-      return NS_ERROR_UNEXPECTED;
-    }
-  }
-
-  if (found) {
-    *_retval = ::JS_SetPropertyById(cx, pi_obj, id, vp);
-    return *_retval ? NS_SUCCESS_I_DID_SOMETHING : NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsHTMLPluginObjElementSH::Call(nsIXPConnectWrappedNative *wrapper,
-                               JSContext *cx, JSObject *obj, uint32_t argc,
-                               jsval *argv, jsval *vp, bool *_retval)
-{
-  // XPConnect passes us the XPConnect wrapper JSObject as obj, and
-  // not the 'this' parameter that the JS engine passes in. Pass in
-  // the real this parameter from JS (argv[-1]) here.
-  return DoCall(wrapper, cx, obj, argc, argv, vp, argv[-1], _retval);
-}
-
-nsresult
-nsHTMLPluginObjElementSH::DoCall(nsIXPConnectWrappedNative *wrapper,
-                                 JSContext *cx, JSObject *obj, uint32_t argc,
-                                 jsval *argv, jsval *vp, jsval thisVal,
-                                 bool *_retval)
-{
-  nsRefPtr<nsNPAPIPluginInstance> pi;
-  nsresult rv = GetPluginInstanceIfSafe(wrapper, obj, cx, getter_AddRefs(pi));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // If obj is a native wrapper, or if there's no plugin around for
-  // this object, throw.
-  if (ObjectIsNativeWrapper(cx, obj) || !pi) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  JSObject *pi_obj = nullptr;
-  JSObject *pi_proto = nullptr;
-
-  rv = GetPluginJSObject(cx, obj, pi, &pi_obj, &pi_proto);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (!pi) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  // XPConnect passes us the XPConnect wrapper JSObject as obj, and
-  // not the 'this' parameter that the JS engine passes in. Pass in
-  // the real this parameter from JS (argv[-1]) here.
-  JSAutoRequest ar(cx);
-  *_retval = ::JS::Call(cx, thisVal, pi_obj, argc, argv, vp);
-  if (*_retval) {
-    Telemetry::Accumulate(Telemetry::PLUGIN_CALLED_DIRECTLY, true);
-  }
-
-  return NS_OK;
-}
-
-
-nsresult
-nsHTMLPluginObjElementSH::GetPluginJSObject(JSContext *cx, JSObject *obj,
-                                            nsNPAPIPluginInstance *plugin_inst,
-                                            JSObject **plugin_obj,
-                                            JSObject **plugin_proto)
-{
-  *plugin_obj = nullptr;
-  *plugin_proto = nullptr;
-
-  JSAutoRequest ar(cx);
-
-  // NB: We need an AutoEnterCompartment because we can be called from
-  // nsObjectFrame when the plugin loads after the JS object for our content
-  // node has been created.
-  JSAutoCompartment ac(cx, obj);
-
-  if (plugin_inst) {
-    plugin_inst->GetJSObject(cx, plugin_obj);
-    if (*plugin_obj) {
-      if (!::JS_GetPrototype(cx, *plugin_obj, plugin_proto)) {
-        return NS_ERROR_UNEXPECTED;
-      }
-    }
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsHTMLPluginObjElementSH::NewResolve(nsIXPConnectWrappedNative *wrapper,
-                                     JSContext *cx, JSObject *obj, jsid id,
-                                     uint32_t flags, JSObject **objp,
-                                     bool *_retval)
-{
-  // Make sure the plugin instance is loaded and instantiated, if
-  // possible.
-
-  nsRefPtr<nsNPAPIPluginInstance> pi;
-  nsresult rv = GetPluginInstanceIfSafe(wrapper, obj, cx, getter_AddRefs(pi));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return nsElementSH::NewResolve(wrapper, cx, obj, id, flags, objp,
-                                 _retval);
-}
-
 // Plugin helper
 
 nsISupports*
 nsPluginSH::GetItemAt(nsISupports *aNative, uint32_t aIndex,
                       nsWrapperCache **aCache, nsresult *aResult)
 {
   nsPluginElement* plugin = nsPluginElement::FromSupports(aNative);
 
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -760,99 +760,16 @@ public:
                             nsIDOMHTMLOptionsCollection *aOptCollection);
 
   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   {
     return new nsHTMLSelectElementSH(aData);
   }
 };
 
-
-// HTMLEmbed/Object/AppletElement helper
-
-class nsHTMLPluginObjElementSH : public nsElementSH
-{
-protected:
-  nsHTMLPluginObjElementSH(nsDOMClassInfoData* aData)
-    : nsElementSH(aData)
-  {
-  }
-
-  virtual ~nsHTMLPluginObjElementSH()
-  {
-  }
-
-  // Passing a null aWrapper is fine for WebIDL objects
-  static nsresult GetPluginInstanceIfSafe(nsIXPConnectWrappedNative *aWrapper,
-                                          JSObject *obj,
-                                          JSContext *cx,
-                                          nsNPAPIPluginInstance **aResult);
-
-  static nsresult GetPluginJSObject(JSContext *cx, JSObject *obj,
-                                    nsNPAPIPluginInstance *plugin_inst,
-                                    JSObject **plugin_obj,
-                                    JSObject **plugin_proto);
-
-public:
-  NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                        JSObject *obj, jsid id, uint32_t flags,
-                        JSObject **objp, bool *_retval);
-  NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
-                       JSObject *globalObj, JSObject **parentObj);
-  NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                        JSObject *obj);
-  NS_IMETHOD PostTransplant(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                            JSObject *obj);
-  NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                         JSObject *obj, jsid id, jsval *vp, bool *_retval);
-  NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                         JSObject *obj, jsid id, jsval *vp, bool *_retval);
-  NS_IMETHOD Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                  JSObject *obj, uint32_t argc, jsval *argv, jsval *vp,
-                  bool *_retval);
-
-
-  static nsresult SetupProtoChain(JSContext *cx, JSObject *obj,
-                                  nsIXPConnectWrappedNative *wrapper = nullptr,
-                                  JSObject *aCanonicalProto = nullptr);
-
-  // The actual implementation of Call.  This allows the caller to
-  // pass in an explicit "this" value and does not make any
-  // assumptions about negative indices into argv.
-  static nsresult DoCall(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                         JSObject *obj, uint32_t argc, jsval *argv, jsval *vp,
-                         jsval thisVal, bool *_retval);
-
-  static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
-  {
-    return new nsHTMLPluginObjElementSH(aData);
-  }
-
-  class SetupProtoChainRunner MOZ_FINAL : public nsIRunnable
-  {
-  public:
-    NS_DECL_ISUPPORTS
-
-    // wrapper can be null, but then aContent must be non-null
-    SetupProtoChainRunner(nsIXPConnectWrappedNative* aWrapper,
-                          nsIScriptContext* aScriptContext,
-                          nsObjectLoadingContent* aContent);
-
-    NS_IMETHOD Run();
-
-  private:
-    nsCOMPtr<nsIXPConnectWrappedNative> mWrapper;
-    nsCOMPtr<nsIScriptContext> mContext;
-    // We store an nsIObjectLoadingContent because we can
-    // unambiguously refcount that.
-    nsRefPtr<nsIObjectLoadingContent> mContent;
-  };
-};
-
-
 // Plugin helper
 
 class nsPluginSH : public nsNamedArraySH
 {
 protected:
   nsPluginSH(nsDOMClassInfoData* aData) : nsNamedArraySH(aData)
   {
   }
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -40,22 +40,19 @@ DOMCI_CLASS(CompositionEvent)
 DOMCI_CLASS(DeviceMotionEvent)
 DOMCI_CLASS(DeviceAcceleration)
 DOMCI_CLASS(DeviceRotationRate)
 
 // HTML classes
 DOMCI_CLASS(HTMLDocument)
 
 // HTML element classes
-DOMCI_CLASS(HTMLAppletElement)
-DOMCI_CLASS(HTMLEmbedElement)
 DOMCI_CLASS(HTMLFormElement)
 DOMCI_CLASS(HTMLIFrameElement)
 DOMCI_CLASS(HTMLInputElement)
-DOMCI_CLASS(HTMLObjectElement)
 DOMCI_CLASS(HTMLSelectElement)
 DOMCI_CLASS(ValidityState)
 
 // CSS classes
 DOMCI_CLASS(CSSStyleRule)
 DOMCI_CLASS(CSSCharsetRule)
 DOMCI_CLASS(CSSImportRule)
 DOMCI_CLASS(CSSMediaRule)