blob: d21f7e410ecc90f139586150b0058691fea13801 [file] [log] [blame]
andersca@apple.com861e84a2010-07-27 19:29:45 +00001/*
2 * Copyright (C) 2010 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
laszlo.1.gombos@nokia.com48183962011-01-28 05:37:44 +000026#include "config.h"
andersca@apple.com861e84a2010-07-27 19:29:45 +000027#include "NPJSObject.h"
28
aestes@apple.com022b3782012-05-16 03:55:58 +000029#if ENABLE(NETSCAPE_PLUGIN_API)
30
andersca@apple.com21fcac32010-08-02 18:28:07 +000031#include "JSNPObject.h"
andersca@apple.com861e84a2010-07-27 19:29:45 +000032#include "NPRuntimeObjectMap.h"
33#include "NPRuntimeUtilities.h"
andersca@apple.com5b2497c2010-07-28 21:30:11 +000034#include <JavaScriptCore/JSLock.h>
andersca@apple.com861e84a2010-07-27 19:29:45 +000035#include <JavaScriptCore/JSObject.h>
ggaren@apple.com7746b2e2011-10-02 00:54:56 +000036#include <JavaScriptCore/StrongInlines.h>
andersca@apple.com861e84a2010-07-27 19:29:45 +000037#include <WebCore/Frame.h>
38#include <WebCore/IdentifierRep.h>
weinig@apple.com7bf96832010-08-16 23:00:34 +000039#include <wtf/text/WTFString.h>
andersca@apple.com861e84a2010-07-27 19:29:45 +000040
41using namespace JSC;
42using namespace WebCore;
43
44namespace WebKit {
45
oliver@apple.com8d857052011-02-15 23:54:06 +000046NPJSObject* NPJSObject::create(JSGlobalData& globalData, NPRuntimeObjectMap* objectMap, JSObject* jsObject)
andersca@apple.com861e84a2010-07-27 19:29:45 +000047{
andersca@apple.com21fcac32010-08-02 18:28:07 +000048 // We should never have a JSNPObject inside an NPJSObject.
49 ASSERT(!jsObject->inherits(&JSNPObject::s_info));
50
andersca@apple.com861e84a2010-07-27 19:29:45 +000051 NPJSObject* npJSObject = toNPJSObject(createNPObject(0, npClass()));
oliver@apple.com8d857052011-02-15 23:54:06 +000052 npJSObject->initialize(globalData, objectMap, jsObject);
andersca@apple.com861e84a2010-07-27 19:29:45 +000053
54 return npJSObject;
55}
56
57NPJSObject::NPJSObject()
58 : m_objectMap(0)
59{
60}
61
62NPJSObject::~NPJSObject()
63{
64 m_objectMap->npJSObjectDestroyed(this);
65}
66
67bool NPJSObject::isNPJSObject(NPObject* npObject)
68{
69 return npObject->_class == npClass();
70}
71
oliver@apple.com8d857052011-02-15 23:54:06 +000072void NPJSObject::initialize(JSGlobalData& globalData, NPRuntimeObjectMap* objectMap, JSObject* jsObject)
andersca@apple.com861e84a2010-07-27 19:29:45 +000073{
74 ASSERT(!m_objectMap);
75 ASSERT(!m_jsObject);
76
77 m_objectMap = objectMap;
oliver@apple.com8d857052011-02-15 23:54:06 +000078 m_jsObject.set(globalData, jsObject);
andersca@apple.com861e84a2010-07-27 19:29:45 +000079}
80
81static Identifier identifierFromIdentifierRep(ExecState* exec, IdentifierRep* identifierRep)
82{
83 ASSERT(identifierRep->isString());
84
85 const char* string = identifierRep->string();
86 int length = strlen(string);
87
88 return Identifier(exec, String::fromUTF8WithLatin1Fallback(string, length).impl());
89}
90
andersca@apple.come6509332010-07-28 23:03:25 +000091bool NPJSObject::hasMethod(NPIdentifier methodName)
92{
93 IdentifierRep* identifierRep = static_cast<IdentifierRep*>(methodName);
94
95 if (!identifierRep->isString())
96 return false;
97
98 ExecState* exec = m_objectMap->globalExec();
99 if (!exec)
100 return false;
101
mhahnenberg@apple.come16f8092012-06-27 23:08:26 +0000102 JSLockHolder lock(exec);
andersca@apple.come6509332010-07-28 23:03:25 +0000103
104 JSValue value = m_jsObject->get(exec, identifierFromIdentifierRep(exec, identifierRep));
105 exec->clearException();
andersca@apple.come6509332010-07-28 23:03:25 +0000106
107 CallData callData;
andersca@apple.come8bdca22010-07-28 23:38:24 +0000108 return getCallData(value, callData) != CallTypeNone;
109}
110
111bool NPJSObject::invoke(NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
112{
113 IdentifierRep* identifierRep = static_cast<IdentifierRep*>(methodName);
114
115 if (!identifierRep->isString())
116 return false;
117
118 ExecState* exec = m_objectMap->globalExec();
119 if (!exec)
120 return false;
121
mhahnenberg@apple.come16f8092012-06-27 23:08:26 +0000122 JSLockHolder lock(exec);
andersca@apple.come8bdca22010-07-28 23:38:24 +0000123
124 JSValue function = m_jsObject->get(exec, identifierFromIdentifierRep(exec, identifierRep));
andersca@apple.com8f8a7d52010-07-29 19:31:06 +0000125 return invoke(exec, m_objectMap->globalObject(), function, arguments, argumentCount, result);
andersca@apple.come40da102010-07-29 00:14:08 +0000126}
127
andersca@apple.com1039e402010-07-30 21:43:48 +0000128bool NPJSObject::invokeDefault(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
andersca@apple.come40da102010-07-29 00:14:08 +0000129{
130 ExecState* exec = m_objectMap->globalExec();
131 if (!exec)
andersca@apple.come8bdca22010-07-28 23:38:24 +0000132 return false;
133
mhahnenberg@apple.come16f8092012-06-27 23:08:26 +0000134 JSLockHolder lock(exec);
andersca@apple.come8bdca22010-07-28 23:38:24 +0000135
oliver@apple.com8d857052011-02-15 23:54:06 +0000136 JSValue function = m_jsObject.get();
andersca@apple.com8f8a7d52010-07-29 19:31:06 +0000137 return invoke(exec, m_objectMap->globalObject(), function, arguments, argumentCount, result);
andersca@apple.come6509332010-07-28 23:03:25 +0000138}
139
andersca@apple.com861e84a2010-07-27 19:29:45 +0000140bool NPJSObject::hasProperty(NPIdentifier identifier)
141{
142 IdentifierRep* identifierRep = static_cast<IdentifierRep*>(identifier);
143
144 ExecState* exec = m_objectMap->globalExec();
145 if (!exec)
146 return false;
147
mhahnenberg@apple.come16f8092012-06-27 23:08:26 +0000148 JSLockHolder lock(exec);
andersca@apple.come6509332010-07-28 23:03:25 +0000149
andersca@apple.com861e84a2010-07-27 19:29:45 +0000150 bool result;
151 if (identifierRep->isString())
152 result = m_jsObject->hasProperty(exec, identifierFromIdentifierRep(exec, identifierRep));
153 else
154 result = m_jsObject->hasProperty(exec, identifierRep->number());
155
156 exec->clearException();
andersca@apple.com861e84a2010-07-27 19:29:45 +0000157 return result;
158}
159
andersca@apple.com5b2497c2010-07-28 21:30:11 +0000160bool NPJSObject::getProperty(NPIdentifier propertyName, NPVariant* result)
andersca@apple.com861e84a2010-07-27 19:29:45 +0000161{
andersca@apple.com5b2497c2010-07-28 21:30:11 +0000162 IdentifierRep* identifierRep = static_cast<IdentifierRep*>(propertyName);
163
164 ExecState* exec = m_objectMap->globalExec();
165 if (!exec)
166 return false;
167
mhahnenberg@apple.come16f8092012-06-27 23:08:26 +0000168 JSLockHolder lock(exec);
andersca@apple.com5b2497c2010-07-28 21:30:11 +0000169 JSValue jsResult;
170 if (identifierRep->isString())
171 jsResult = m_jsObject->get(exec, identifierFromIdentifierRep(exec, identifierRep));
172 else
173 jsResult = m_jsObject->get(exec, identifierRep->number());
174
175 m_objectMap->convertJSValueToNPVariant(exec, jsResult, *result);
176 exec->clearException();
177 return true;
andersca@apple.com861e84a2010-07-27 19:29:45 +0000178}
179
andersca@apple.com6429f942010-07-29 22:42:17 +0000180bool NPJSObject::setProperty(NPIdentifier propertyName, const NPVariant* value)
181{
182 IdentifierRep* identifierRep = static_cast<IdentifierRep*>(propertyName);
183
184 ExecState* exec = m_objectMap->globalExec();
185 if (!exec)
186 return false;
187
mhahnenberg@apple.come16f8092012-06-27 23:08:26 +0000188 JSLockHolder lock(exec);
andersca@apple.com6429f942010-07-29 22:42:17 +0000189
190 JSValue jsValue = m_objectMap->convertNPVariantToJSValue(exec, m_objectMap->globalObject(), *value);
191 if (identifierRep->isString()) {
192 PutPropertySlot slot;
mhahnenberg@apple.com39512782011-10-26 00:56:55 +0000193 m_jsObject->methodTable()->put(m_jsObject.get(), exec, identifierFromIdentifierRep(exec, identifierRep), jsValue, slot);
andersca@apple.com6429f942010-07-29 22:42:17 +0000194 } else
barraclough@apple.comb1db28d82012-03-06 07:23:21 +0000195 m_jsObject->methodTable()->putByIndex(m_jsObject.get(), exec, identifierRep->number(), jsValue, false);
andersca@apple.com6429f942010-07-29 22:42:17 +0000196 exec->clearException();
197
198 return true;
199}
200
andersca@apple.com01dbfa02010-08-01 21:02:46 +0000201bool NPJSObject::removeProperty(NPIdentifier propertyName)
202{
203 IdentifierRep* identifierRep = static_cast<IdentifierRep*>(propertyName);
204
205 ExecState* exec = m_objectMap->globalExec();
206 if (!exec)
207 return false;
208
mhahnenberg@apple.come16f8092012-06-27 23:08:26 +0000209 JSLockHolder lock(exec);
andersca@apple.com01dbfa02010-08-01 21:02:46 +0000210 if (identifierRep->isString()) {
211 Identifier identifier = identifierFromIdentifierRep(exec, identifierRep);
212
213 if (!m_jsObject->hasProperty(exec, identifier)) {
214 exec->clearException();
215 return false;
216 }
217
mhahnenberg@apple.comc0f87c12011-10-26 01:49:00 +0000218 m_jsObject->methodTable()->deleteProperty(m_jsObject.get(), exec, identifier);
andersca@apple.com01dbfa02010-08-01 21:02:46 +0000219 } else {
220 if (!m_jsObject->hasProperty(exec, identifierRep->number())) {
221 exec->clearException();
222 return false;
223 }
224
mhahnenberg@apple.comc0f87c12011-10-26 01:49:00 +0000225 m_jsObject->methodTable()->deletePropertyByIndex(m_jsObject.get(), exec, identifierRep->number());
andersca@apple.com01dbfa02010-08-01 21:02:46 +0000226 }
227
228 exec->clearException();
229 return true;
230}
231
andersca@apple.com022916b2010-07-29 22:21:43 +0000232bool NPJSObject::enumerate(NPIdentifier** identifiers, uint32_t* identifierCount)
233{
234 ExecState* exec = m_objectMap->globalExec();
235 if (!exec)
236 return false;
237
mhahnenberg@apple.come16f8092012-06-27 23:08:26 +0000238 JSLockHolder lock(exec);
andersca@apple.com022916b2010-07-29 22:21:43 +0000239
240 PropertyNameArray propertyNames(exec);
mhahnenberg@apple.com2358ae12011-11-04 01:32:18 +0000241 m_jsObject->methodTable()->getPropertyNames(m_jsObject.get(), exec, propertyNames, ExcludeDontEnumProperties);
andersca@apple.com022916b2010-07-29 22:21:43 +0000242
andersca@apple.coma1247b72010-11-02 21:18:18 +0000243 NPIdentifier* nameIdentifiers = npnMemNewArray<NPIdentifier>(propertyNames.size());
andersca@apple.com022916b2010-07-29 22:21:43 +0000244
245 for (size_t i = 0; i < propertyNames.size(); ++i)
benjamin@webkit.orgc9b7a202012-09-08 05:46:29 +0000246 nameIdentifiers[i] = static_cast<NPIdentifier>(IdentifierRep::get(propertyNames[i].string().utf8().data()));
andersca@apple.com022916b2010-07-29 22:21:43 +0000247
248 *identifiers = nameIdentifiers;
249 *identifierCount = propertyNames.size();
250
251 return true;
252}
253
andersca@apple.com1039e402010-07-30 21:43:48 +0000254bool NPJSObject::construct(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
andersca@apple.come40da102010-07-29 00:14:08 +0000255{
256 ExecState* exec = m_objectMap->globalExec();
257 if (!exec)
258 return false;
259
mhahnenberg@apple.come16f8092012-06-27 23:08:26 +0000260 JSLockHolder lock(exec);
andersca@apple.come40da102010-07-29 00:14:08 +0000261
262 ConstructData constructData;
oliver@apple.com8d857052011-02-15 23:54:06 +0000263 ConstructType constructType = getConstructData(m_jsObject.get(), constructData);
andersca@apple.come40da102010-07-29 00:14:08 +0000264 if (constructType == ConstructTypeNone)
265 return false;
266
267 // Convert the passed in arguments.
268 MarkedArgumentBuffer argumentList;
269 for (uint32_t i = 0; i < argumentCount; ++i)
andersca@apple.com8f8a7d52010-07-29 19:31:06 +0000270 argumentList.append(m_objectMap->convertNPVariantToJSValue(exec, m_objectMap->globalObject(), arguments[i]));
andersca@apple.come40da102010-07-29 00:14:08 +0000271
272 exec->globalData().timeoutChecker.start();
oliver@apple.com8d857052011-02-15 23:54:06 +0000273 JSValue value = JSC::construct(exec, m_jsObject.get(), constructType, constructData, argumentList);
andersca@apple.come40da102010-07-29 00:14:08 +0000274 exec->globalData().timeoutChecker.stop();
275
276 // Convert and return the new object.
277 m_objectMap->convertJSValueToNPVariant(exec, value, *result);
278 exec->clearException();
279
280 return true;
281}
282
andersca@apple.com8f8a7d52010-07-29 19:31:06 +0000283bool NPJSObject::invoke(ExecState* exec, JSGlobalObject* globalObject, JSValue function, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
andersca@apple.come40da102010-07-29 00:14:08 +0000284{
285 CallData callData;
286 CallType callType = getCallData(function, callData);
287 if (callType == CallTypeNone)
288 return false;
289
290 // Convert the passed in arguments.
291 MarkedArgumentBuffer argumentList;
292 for (uint32_t i = 0; i < argumentCount; ++i)
andersca@apple.com8f8a7d52010-07-29 19:31:06 +0000293 argumentList.append(m_objectMap->convertNPVariantToJSValue(exec, globalObject, arguments[i]));
andersca@apple.come40da102010-07-29 00:14:08 +0000294
295 exec->globalData().timeoutChecker.start();
mhahnenberg@apple.comc93887c2011-10-27 17:01:38 +0000296 JSValue value = JSC::call(exec, function, callType, callData, m_jsObject->methodTable()->toThisObject(m_jsObject.get(), exec), argumentList);
andersca@apple.come40da102010-07-29 00:14:08 +0000297 exec->globalData().timeoutChecker.stop();
298
299 // Convert and return the result of the function call.
300 m_objectMap->convertJSValueToNPVariant(exec, value, *result);
301 exec->clearException();
302
303 return true;
304}
305
andersca@apple.com861e84a2010-07-27 19:29:45 +0000306NPClass* NPJSObject::npClass()
307{
308 static NPClass npClass = {
309 NP_CLASS_STRUCT_VERSION,
310 NP_Allocate,
311 NP_Deallocate,
andersca@apple.com861e84a2010-07-27 19:29:45 +0000312 0,
andersca@apple.come6509332010-07-28 23:03:25 +0000313 NP_HasMethod,
314 NP_Invoke,
315 NP_InvokeDefault,
andersca@apple.com861e84a2010-07-27 19:29:45 +0000316 NP_HasProperty,
317 NP_GetProperty,
andersca@apple.come6509332010-07-28 23:03:25 +0000318 NP_SetProperty,
andersca@apple.com01dbfa02010-08-01 21:02:46 +0000319 NP_RemoveProperty,
andersca@apple.com022916b2010-07-29 22:21:43 +0000320 NP_Enumerate,
andersca@apple.come40da102010-07-29 00:14:08 +0000321 NP_Construct
andersca@apple.com861e84a2010-07-27 19:29:45 +0000322 };
323
324 return &npClass;
325}
326
andersca@apple.com004117f2010-11-01 21:10:56 +0000327NPObject* NPJSObject::NP_Allocate(NPP npp, NPClass*)
andersca@apple.com861e84a2010-07-27 19:29:45 +0000328{
329 ASSERT_UNUSED(npp, !npp);
330
331 return new NPJSObject;
332}
333
334void NPJSObject::NP_Deallocate(NPObject* npObject)
335{
336 NPJSObject* npJSObject = toNPJSObject(npObject);
337 delete npJSObject;
338}
339
andersca@apple.come6509332010-07-28 23:03:25 +0000340bool NPJSObject::NP_HasMethod(NPObject* npObject, NPIdentifier methodName)
341{
342 return toNPJSObject(npObject)->hasMethod(methodName);
343}
344
andersca@apple.come8bdca22010-07-28 23:38:24 +0000345bool NPJSObject::NP_Invoke(NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
andersca@apple.come6509332010-07-28 23:03:25 +0000346{
andersca@apple.come8bdca22010-07-28 23:38:24 +0000347 return toNPJSObject(npObject)->invoke(methodName, arguments, argumentCount, result);
andersca@apple.come6509332010-07-28 23:03:25 +0000348}
349
andersca@apple.come40da102010-07-29 00:14:08 +0000350bool NPJSObject::NP_InvokeDefault(NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
andersca@apple.come6509332010-07-28 23:03:25 +0000351{
andersca@apple.come40da102010-07-29 00:14:08 +0000352 return toNPJSObject(npObject)->invokeDefault(arguments, argumentCount, result);
andersca@apple.come6509332010-07-28 23:03:25 +0000353}
354
andersca@apple.com861e84a2010-07-27 19:29:45 +0000355bool NPJSObject::NP_HasProperty(NPObject* npObject, NPIdentifier propertyName)
356{
357 return toNPJSObject(npObject)->hasProperty(propertyName);
358}
andersca@apple.come6509332010-07-28 23:03:25 +0000359
andersca@apple.com861e84a2010-07-27 19:29:45 +0000360bool NPJSObject::NP_GetProperty(NPObject* npObject, NPIdentifier propertyName, NPVariant* result)
361{
362 return toNPJSObject(npObject)->getProperty(propertyName, result);
363}
364
andersca@apple.com6429f942010-07-29 22:42:17 +0000365bool NPJSObject::NP_SetProperty(NPObject* npObject, NPIdentifier propertyName, const NPVariant* value)
andersca@apple.come6509332010-07-28 23:03:25 +0000366{
andersca@apple.com6429f942010-07-29 22:42:17 +0000367 return toNPJSObject(npObject)->setProperty(propertyName, value);
andersca@apple.come6509332010-07-28 23:03:25 +0000368}
369
andersca@apple.com01dbfa02010-08-01 21:02:46 +0000370bool NPJSObject::NP_RemoveProperty(NPObject* npObject, NPIdentifier propertyName)
371{
372 return toNPJSObject(npObject)->removeProperty(propertyName);
373}
374
andersca@apple.com022916b2010-07-29 22:21:43 +0000375bool NPJSObject::NP_Enumerate(NPObject* npObject, NPIdentifier** identifiers, uint32_t* identifierCount)
376{
377 return toNPJSObject(npObject)->enumerate(identifiers, identifierCount);
378}
379
andersca@apple.come40da102010-07-29 00:14:08 +0000380bool NPJSObject::NP_Construct(NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
381{
382 return toNPJSObject(npObject)->construct(arguments, argumentCount, result);
383}
384
andersca@apple.com861e84a2010-07-27 19:29:45 +0000385} // namespace WebKit
aestes@apple.com022b3782012-05-16 03:55:58 +0000386
387#endif // ENABLE(NETSCAPE_PLUGIN_API)