1/*
2 * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "JSNPMethod.h"
28
29#if ENABLE(NETSCAPE_PLUGIN_API)
30
31#include "JSNPObject.h"
32#include <JavaScriptCore/Error.h>
33#include <JavaScriptCore/FunctionPrototype.h>
34#include <JavaScriptCore/IsoSubspacePerVM.h>
35#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h>
36#include <JavaScriptCore/JSGlobalObject.h>
37#include <JavaScriptCore/JSObject.h>
38#include <WebCore/JSHTMLElement.h>
39#include <WebCore/JSPluginElementFunctions.h>
40
41namespace WebKit {
42using namespace JSC;
43using namespace WebCore;
44
45STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSNPMethod);
46
47const ClassInfo JSNPMethod::s_info = { "NPMethod", &InternalFunction::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSNPMethod) };
48
49static EncodedJSValue JSC_HOST_CALL callMethod(ExecState*);
50
51JSNPMethod::JSNPMethod(JSGlobalObject* globalObject, Structure* structure, NPIdentifier npIdentifier)
52 : InternalFunction(globalObject->vm(), structure, callMethod, nullptr)
53 , m_npIdentifier(npIdentifier)
54{
55}
56
57void JSNPMethod::finishCreation(VM& vm, const String& name)
58{
59 Base::finishCreation(vm, name);
60 ASSERT(inherits(vm, info()));
61}
62
63IsoSubspace* JSNPMethod::subspaceForImpl(VM& vm)
64{
65 static NeverDestroyed<IsoSubspacePerVM> perVM([] (VM& vm) { return ISO_SUBSPACE_PARAMETERS(vm.destructibleObjectHeapCellType.get(), JSNPMethod); });
66 return &perVM.get().forVM(vm);
67}
68
69static EncodedJSValue JSC_HOST_CALL callMethod(ExecState* exec)
70{
71 VM& vm = exec->vm();
72 auto scope = DECLARE_THROW_SCOPE(vm);
73
74 JSNPMethod* jsNPMethod = jsCast<JSNPMethod*>(exec->jsCallee());
75
76 JSValue thisValue = exec->thisValue();
77
78 // Check if we're calling a method on the plug-in script object.
79 if (thisValue.inherits<JSHTMLElement>(vm)) {
80 JSHTMLElement* element = jsCast<JSHTMLElement*>(asObject(thisValue));
81
82 // Try to get the script object from the element
83 if (JSObject* scriptObject = pluginScriptObject(exec, element))
84 thisValue = scriptObject;
85 }
86
87 if (thisValue.inherits<JSNPObject>(vm)) {
88 JSNPObject* jsNPObject = jsCast<JSNPObject*>(asObject(thisValue));
89
90 return JSValue::encode(jsNPObject->callMethod(exec, jsNPMethod->npIdentifier()));
91 }
92
93 return throwVMTypeError(exec, scope);
94}
95
96} // namespace WebKit
97
98#endif // ENABLE(NETSCAPE_PLUGIN_API)
99