source: webkit/trunk/JavaScriptCore/API/JSCallbackObject.cpp@ 25085

Last change on this file since 25085 was 25085, checked in by andrew, 18 years ago

JavaScriptCore:

Reviewed by Darin.


http://bugs.webkit.org/show_bug.cgi?id=14967 part 1 - Eliminate most implicit
conversions of wtf::Vector<T> to T* by explicitly calling .data()

  • API/JSCallbackConstructor.cpp: (KJS::JSCallbackConstructor::construct):
  • API/JSCallbackFunction.cpp: (KJS::JSCallbackFunction::callAsFunction):
  • API/JSCallbackObject.cpp: (KJS::JSCallbackObject::construct): (KJS::JSCallbackObject::callAsFunction):
  • bindings/c/c_instance.cpp: (KJS::Bindings::CInstance::invokeMethod): (KJS::Bindings::CInstance::invokeDefaultMethod):
  • kjs/number_object.cpp: (integer_part_noexp): (char_sequence):
  • kjs/ustring.cpp: (KJS::UString::UTF8String):

WebCore:

Reviewed by Darin.


http://bugs.webkit.org/show_bug.cgi?id=14967 part 1 - Eliminate most implicit
conversions of wtf::Vector<T> to T* by explicitly calling .data()

  • html/HTMLSelectElement.cpp: (WebCore::HTMLSelectElement::saveState):
  • platform/KURL.cpp: (WebCore::KURL::KURL): (WebCore::KURL::init): (WebCore::KURL::decode_string): (WebCore::KURL::parse): (WebCore::KURL::encode_string):
  • platform/cf/KURLCFNet.cpp: (WebCore::KURL::KURL):
  • platform/mac/KURLMac.mm: (WebCore::KURL::KURL):
  • rendering/RenderFrameSet.cpp: (WebCore::RenderFrameSet::layOutAxis):

win:

Reviewed by Darin.


http://bugs.webkit.org/show_bug.cgi?id=14967 part 1 - Eliminate most implicit
conversions of wtf::Vector<T> to T* by explicitly calling .data()

  • WebView.cpp: (getCompositionString):
File size: 17.7 KB
Line 
1// -*- mode: c++; c-basic-offset: 4 -*-
2/*
3 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <wtf/Platform.h>
28#include "JSCallbackObject.h"
29
30#include "APICast.h"
31#include "JSCallbackFunction.h"
32#include "JSClassRef.h"
33#include "JSObjectRef.h"
34#include "JSStringRef.h"
35#include "PropertyNameArray.h"
36#include "internal.h"
37#include <wtf/Vector.h>
38
39namespace KJS {
40
41const ClassInfo JSCallbackObject::info = { "CallbackObject", 0, 0, 0 };
42
43JSCallbackObject::JSCallbackObject(ExecState* exec, JSClassRef jsClass, JSValue* prototype, void* data)
44 : JSObject(prototype)
45{
46 init(exec, jsClass, data);
47}
48
49void JSCallbackObject::init(ExecState* exec, JSClassRef jsClass, void* data)
50{
51 m_privateData = data;
52 m_class = JSClassRetain(jsClass);
53
54 Vector<JSObjectInitializeCallback, 16> initRoutines;
55 do {
56 if (JSObjectInitializeCallback initialize = jsClass->initialize)
57 initRoutines.append(initialize);
58 } while ((jsClass = jsClass->parentClass));
59
60 // initialize from base to derived
61 for (int i = static_cast<int>(initRoutines.size()) - 1; i >= 0; i--) {
62 JSLock::DropAllLocks dropAllLocks;
63 JSObjectInitializeCallback initialize = initRoutines[i];
64 initialize(toRef(exec), toRef(this));
65 }
66}
67
68JSCallbackObject::~JSCallbackObject()
69{
70 JSObjectRef thisRef = toRef(this);
71
72 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
73 if (JSObjectFinalizeCallback finalize = jsClass->finalize) {
74 finalize(thisRef);
75 }
76
77 JSClassRelease(m_class);
78}
79
80UString JSCallbackObject::className() const
81{
82 if (!m_class->className.isNull())
83 return m_class->className;
84
85 return JSObject::className();
86}
87
88bool JSCallbackObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
89{
90 JSContextRef ctx = toRef(exec);
91 JSObjectRef thisRef = toRef(this);
92 JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
93
94 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
95 // optional optimization to bypass getProperty in cases when we only need to know if the property exists
96 if (JSObjectHasPropertyCallback hasProperty = jsClass->hasProperty) {
97 JSLock::DropAllLocks dropAllLocks;
98 if (hasProperty(ctx, thisRef, propertyNameRef)) {
99 slot.setCustom(this, callbackGetter);
100 return true;
101 }
102 } else if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
103 JSLock::DropAllLocks dropAllLocks;
104 if (JSValueRef value = getProperty(ctx, thisRef, propertyNameRef, toRef(exec->exceptionSlot()))) {
105 // cache the value so we don't have to compute it again
106 // FIXME: This violates the PropertySlot design a little bit.
107 // We should either use this optimization everywhere, or nowhere.
108 slot.setCustom(reinterpret_cast<JSObject*>(toJS(value)), cachedValueGetter);
109 return true;
110 }
111 }
112
113 if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) {
114 if (staticValues->contains(propertyName.ustring().rep())) {
115 slot.setCustom(this, staticValueGetter);
116 return true;
117 }
118 }
119
120 if (OpaqueJSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) {
121 if (staticFunctions->contains(propertyName.ustring().rep())) {
122 slot.setCustom(this, staticFunctionGetter);
123 return true;
124 }
125 }
126 }
127
128 return JSObject::getOwnPropertySlot(exec, propertyName, slot);
129}
130
131bool JSCallbackObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
132{
133 return getOwnPropertySlot(exec, Identifier::from(propertyName), slot);
134}
135
136void JSCallbackObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)
137{
138 JSContextRef ctx = toRef(exec);
139 JSObjectRef thisRef = toRef(this);
140 JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
141 JSValueRef valueRef = toRef(value);
142
143 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
144 if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) {
145 JSLock::DropAllLocks dropAllLocks;
146 if (setProperty(ctx, thisRef, propertyNameRef, valueRef, toRef(exec->exceptionSlot())))
147 return;
148 }
149
150 if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) {
151 if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) {
152 if (entry->attributes & kJSPropertyAttributeReadOnly)
153 return;
154 if (JSObjectSetPropertyCallback setProperty = entry->setProperty) {
155 JSLock::DropAllLocks dropAllLocks;
156 if (setProperty(ctx, thisRef, propertyNameRef, valueRef, toRef(exec->exceptionSlot())))
157 return;
158 } else
159 throwError(exec, ReferenceError, "Attempt to set a property that is not settable.");
160 }
161 }
162
163 if (OpaqueJSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) {
164 if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) {
165 if (entry->attributes & kJSPropertyAttributeReadOnly)
166 return;
167 putDirect(propertyName, value, attr); // put as override property
168 return;
169 }
170 }
171 }
172
173 return JSObject::put(exec, propertyName, value, attr);
174}
175
176void JSCallbackObject::put(ExecState* exec, unsigned propertyName, JSValue* value, int attr)
177{
178 return put(exec, Identifier::from(propertyName), value, attr);
179}
180
181bool JSCallbackObject::deleteProperty(ExecState* exec, const Identifier& propertyName)
182{
183 JSContextRef ctx = toRef(exec);
184 JSObjectRef thisRef = toRef(this);
185 JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
186
187 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
188 if (JSObjectDeletePropertyCallback deleteProperty = jsClass->deleteProperty) {
189 JSLock::DropAllLocks dropAllLocks;
190 if (deleteProperty(ctx, thisRef, propertyNameRef, toRef(exec->exceptionSlot())))
191 return true;
192 }
193
194 if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) {
195 if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) {
196 if (entry->attributes & kJSPropertyAttributeDontDelete)
197 return false;
198 return true;
199 }
200 }
201
202 if (OpaqueJSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) {
203 if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) {
204 if (entry->attributes & kJSPropertyAttributeDontDelete)
205 return false;
206 return true;
207 }
208 }
209 }
210
211 return JSObject::deleteProperty(exec, propertyName);
212}
213
214bool JSCallbackObject::deleteProperty(ExecState* exec, unsigned propertyName)
215{
216 return deleteProperty(exec, Identifier::from(propertyName));
217}
218
219bool JSCallbackObject::implementsConstruct() const
220{
221 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
222 if (jsClass->callAsConstructor)
223 return true;
224
225 return false;
226}
227
228JSObject* JSCallbackObject::construct(ExecState* exec, const List& args)
229{
230 JSContextRef execRef = toRef(exec);
231 JSObjectRef thisRef = toRef(this);
232
233 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
234 if (JSObjectCallAsConstructorCallback callAsConstructor = jsClass->callAsConstructor) {
235 int argumentCount = static_cast<int>(args.size());
236 Vector<JSValueRef, 16> arguments(argumentCount);
237 for (int i = 0; i < argumentCount; i++)
238 arguments[i] = toRef(args[i]);
239 JSLock::DropAllLocks dropAllLocks;
240 return toJS(callAsConstructor(execRef, thisRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
241 }
242 }
243
244 ASSERT(0); // implementsConstruct should prevent us from reaching here
245 return 0;
246}
247
248bool JSCallbackObject::implementsHasInstance() const
249{
250 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
251 if (jsClass->hasInstance)
252 return true;
253
254 return false;
255}
256
257bool JSCallbackObject::hasInstance(ExecState *exec, JSValue *value)
258{
259 JSContextRef execRef = toRef(exec);
260 JSObjectRef thisRef = toRef(this);
261
262 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
263 if (JSObjectHasInstanceCallback hasInstance = jsClass->hasInstance) {
264 JSLock::DropAllLocks dropAllLocks;
265 return hasInstance(execRef, thisRef, toRef(value), toRef(exec->exceptionSlot()));
266 }
267
268 ASSERT(0); // implementsHasInstance should prevent us from reaching here
269 return 0;
270}
271
272
273bool JSCallbackObject::implementsCall() const
274{
275 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
276 if (jsClass->callAsFunction)
277 return true;
278
279 return false;
280}
281
282JSValue* JSCallbackObject::callAsFunction(ExecState* exec, JSObject* thisObj, const List &args)
283{
284 JSContextRef execRef = toRef(exec);
285 JSObjectRef thisRef = toRef(this);
286 JSObjectRef thisObjRef = toRef(thisObj);
287
288 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
289 if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) {
290 int argumentCount = static_cast<int>(args.size());
291 Vector<JSValueRef, 16> arguments(argumentCount);
292 for (int i = 0; i < argumentCount; i++)
293 arguments[i] = toRef(args[i]);
294 JSLock::DropAllLocks dropAllLocks;
295 return toJS(callAsFunction(execRef, thisRef, thisObjRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
296 }
297 }
298
299 ASSERT(0); // implementsCall should prevent us from reaching here
300 return 0;
301}
302
303void JSCallbackObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
304{
305 JSContextRef execRef = toRef(exec);
306 JSObjectRef thisRef = toRef(this);
307
308 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
309 if (JSObjectGetPropertyNamesCallback getPropertyNames = jsClass->getPropertyNames) {
310 JSLock::DropAllLocks dropAllLocks;
311 getPropertyNames(execRef, thisRef, toRef(&propertyNames));
312 }
313
314 if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) {
315 typedef OpaqueJSClass::StaticValuesTable::const_iterator iterator;
316 iterator end = staticValues->end();
317 for (iterator it = staticValues->begin(); it != end; ++it) {
318 UString::Rep* name = it->first.get();
319 StaticValueEntry* entry = it->second;
320 if (entry->getProperty && !(entry->attributes & kJSPropertyAttributeDontEnum))
321 propertyNames.add(Identifier(name));
322 }
323 }
324
325 if (OpaqueJSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) {
326 typedef OpaqueJSClass::StaticFunctionsTable::const_iterator iterator;
327 iterator end = staticFunctions->end();
328 for (iterator it = staticFunctions->begin(); it != end; ++it) {
329 UString::Rep* name = it->first.get();
330 StaticFunctionEntry* entry = it->second;
331 if (!(entry->attributes & kJSPropertyAttributeDontEnum))
332 propertyNames.add(Identifier(name));
333 }
334 }
335 }
336
337 JSObject::getPropertyNames(exec, propertyNames);
338}
339
340double JSCallbackObject::toNumber(ExecState* exec) const
341{
342 JSContextRef ctx = toRef(exec);
343 JSObjectRef thisRef = toRef(this);
344
345 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
346 if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) {
347 JSLock::DropAllLocks dropAllLocks;
348 if (JSValueRef value = convertToType(ctx, thisRef, kJSTypeNumber, toRef(exec->exceptionSlot())))
349 return toJS(value)->getNumber();
350 }
351
352 return JSObject::toNumber(exec);
353}
354
355UString JSCallbackObject::toString(ExecState* exec) const
356{
357 JSContextRef ctx = toRef(exec);
358 JSObjectRef thisRef = toRef(this);
359
360 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
361 if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) {
362 JSLock::DropAllLocks dropAllLocks;
363 if (JSValueRef value = convertToType(ctx, thisRef, kJSTypeString, toRef(exec->exceptionSlot())))
364 return toJS(value)->getString();
365 }
366
367 return JSObject::toString(exec);
368}
369
370void JSCallbackObject::setPrivate(void* data)
371{
372 m_privateData = data;
373}
374
375void* JSCallbackObject::getPrivate()
376{
377 return m_privateData;
378}
379
380bool JSCallbackObject::inherits(JSClassRef c) const
381{
382 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
383 if (jsClass == c)
384 return true;
385
386 return false;
387}
388
389JSValue* JSCallbackObject::cachedValueGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot)
390{
391 JSValue* v = slot.slotBase();
392 ASSERT(v);
393 return v;
394}
395
396JSValue* JSCallbackObject::staticValueGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
397{
398 ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info));
399 JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
400
401 JSObjectRef thisRef = toRef(thisObj);
402 JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
403
404 for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass)
405 if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues)
406 if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep()))
407 if (JSObjectGetPropertyCallback getProperty = entry->getProperty) {
408 JSLock::DropAllLocks dropAllLocks;
409 if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef, toRef(exec->exceptionSlot())))
410 return toJS(value);
411 }
412
413 return throwError(exec, ReferenceError, "Static value property defined with NULL getProperty callback.");
414}
415
416JSValue* JSCallbackObject::staticFunctionGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
417{
418 ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info));
419 JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
420
421 if (JSValue* cachedOrOverrideValue = thisObj->getDirect(propertyName))
422 return cachedOrOverrideValue;
423
424 for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass) {
425 if (OpaqueJSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) {
426 if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) {
427 if (JSObjectCallAsFunctionCallback callAsFunction = entry->callAsFunction) {
428 JSObject* o = new JSCallbackFunction(exec, callAsFunction, propertyName);
429 thisObj->putDirect(propertyName, o, entry->attributes);
430 return o;
431 }
432 }
433 }
434 }
435
436 return throwError(exec, ReferenceError, "Static function property defined with NULL callAsFunction callback.");
437}
438
439JSValue* JSCallbackObject::callbackGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
440{
441 ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info));
442 JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
443
444 JSObjectRef thisRef = toRef(thisObj);
445 JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
446
447 for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass)
448 if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
449 JSLock::DropAllLocks dropAllLocks;
450 if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef, toRef(exec->exceptionSlot())))
451 return toJS(value);
452 }
453
454 return throwError(exec, ReferenceError, "hasProperty callback returned true for a property that doesn't exist.");
455}
456
457} // namespace KJS
Note: See TracBrowser for help on using the repository browser.