source: webkit/trunk/JavaScriptCore/kjs/object.h@ 13598

Last change on this file since 13598 was 13568, checked in by ggaren, 19 years ago

JavaScriptCore:

Reviewed by Darin.

  • JavaScriptCore side of fix for <rdar://problem/4308243> 8F36 Regression: crash in malloc_consolidate if you use a .PAC file

The crash was a result of threaded deallocation of thread-unsafe
objects. Pure JS objects are thread-safe because all JS execution
is synchronized through JSLock. However, JS objects that wrap WebCore
objects are thread-unsafe because JS and WebCore execution are not
synchronized. That unsafety comes into play when the collector
deallocates a JS object that wraps a WebCore object, thus causing the
WebCore object to be deallocated.

The solution here is to have each JSCell know whether it is safe to
collect on a non-main thread, and to avoid collecting unsafe cells
when on a non-main thread.

We don't have a way to test PAC files yet, so there's no test
attached to this patch.

  • kjs/collector.cpp: (KJS::Collector::collect):
(1) Added the test "currentThreadIsMainThread

imp->m_destructorIsThreadSafe".

  • kjs/protect.h: (KJS::gcProtectNullTolerant): (KJS::gcUnprotectNullTolerant):
  • kjs/value.h: (KJS::JSCell::JSCell): The bools here must be bitfields, otherwise m_destructorIsThreadSafe becomes another whole word, ruining the collector optimizations we've made based on the size of a JSObject.
  • kxmlcore/FastMalloc.cpp: (KXMLCore::currentThreadIsMainThread): (KXMLCore::fastMallocRegisterThread):
  • kxmlcore/FastMalloc.h:

WebCore:

Reviewed by Hyatt.

  • css/html4.css: Added default style info for new text fields.
  • rendering/RenderTextField.cpp: (WebCore::RenderTextField::createDivStyle): Added an extra 1px of padding on the left & right to match Win IE & the latest Mozilla. (WebCore::RenderTextField::updateFromElement): Removed some outdated comments. Cleaned up the way we add text nodes to the div. (WebCore::RenderTextField::setSelectionStart): Tweaked selection code to better match Mozilla behavior. (WebCore::RenderTextField::setSelectionEnd): ditto. (WebCore::RenderTextField::select): Cleaned this up by having it call setSelectionRange. (WebCore::RenderTextField::setSelectionRange): Calls updateLayout now in case this is called in an onload handler, and no other layout has occurred. (WebCore::RenderTextField::calcMinMaxWidth): Use floatWidth to calculate the width of the "0" character.
  • rendering/RenderTheme.cpp: (WebCore::RenderTheme::isControlStyled): If the text field's specified border is different from the default border, then treat the control as styled, so the engine knows to turn off the aqua appearance.
  • rendering/RenderThemeMac.mm: (WebCore::RenderThemeMac::paintTextField): return false so the engine knows not to try to draw the border. (WebCore::RenderThemeMac::adjustTextFieldStyle): text field style info has been moved to html4.css. We also add intrinsic margins here if the font size is large enough.
  • html/HTMLTextFieldInnerElement.cpp: (WebCore::HTMLTextFieldInnerElement::defaultEventHandler): No longer check for appearance. All text fields with m_type == TEXT will use the new implementation.
  • html/HTMLInputElement.cpp: (WebCore::HTMLInputElement::isKeyboardFocusable): ditto. (WebCore::HTMLInputElement::focus): ditto. (WebCore::HTMLInputElement::selectionStart): ditto. (WebCore::HTMLInputElement::selectionEnd): ditto. (WebCore::HTMLInputElement::setSelectionStart): ditto. (WebCore::HTMLInputElement::setSelectionEnd): ditto. (WebCore::HTMLInputElement::select): ditto. (WebCore::HTMLInputElement::setSelectionRange): ditto. (WebCore::HTMLInputElement::createRenderer): ditto. (WebCore::HTMLInputElement::defaultEventHandler): ditto. (WebCore::HTMLInputElement::isMouseFocusable): Added. Old text fields relied on the widget to provide a focus policy. A text field that is focusable should be mouse focusable, and shouldn't need to ask the base class.
  • html/HTMLInputElement.h: Added isMouseFocusable.
  • html/HTMLGenericFormElement.cpp: (WebCore::HTMLGenericFormElement::isMouseFocusable): Removed specific text field code since that is now done in HTMLInputElement::isMouseFocusable.
  • dom/Document.cpp: (WebCore::Document::clearSelectionIfNeeded): Check that the new selection is does not have a shadowAncestorNode that is focused.
  • Property svn:eol-style set to native
File size: 23.9 KB
Line 
1// -*- c-basic-offset: 2 -*-
2/*
3 * This file is part of the KDE libraries
4 * Copyright (C) 1999-2001 Harri Porten ([email protected])
5 * Copyright (C) 2001 Peter Kelly ([email protected])
6 * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 *
23 */
24
25#ifndef KJS_OBJECT_H
26#define KJS_OBJECT_H
27
28// Objects
29
30// maximum global call stack size. Protects against accidental or
31// malicious infinite recursions. Define to -1 if you want no limit.
32#if PLATFORM(DARWIN)
33// Given OS X stack sizes we run out of stack at about 350 levels.
34// If we improve our stack usage, we can bump this number.
35#define KJS_MAX_STACK 100
36#else
37#define KJS_MAX_STACK 1000
38#endif
39
40#include "JSType.h"
41#include "interpreter.h"
42#include "kxmlcore/AlwaysInline.h"
43#include "property_map.h"
44#include "property_slot.h"
45#include "scope_chain.h"
46
47namespace KJS {
48
49 class HashTable;
50 class HashEntry;
51 class ListImp;
52 class InternalFunctionImp;
53
54 // ECMA 262-3 8.6.1
55 // Property attributes
56 enum Attribute { None = 0,
57 ReadOnly = 1 << 1, // property can be only read, not written
58 DontEnum = 1 << 2, // property doesn't appear in (for .. in ..)
59 DontDelete = 1 << 3, // property can't be deleted
60 Internal = 1 << 4, // an internal property, set to bypass checks
61 Function = 1 << 5, // property is a function - only used by static hashtables
62 GetterSetter = 1 << 6 }; // property is a getter or setter
63
64 /**
65 * Class Information
66 */
67 struct ClassInfo {
68 /**
69 * A string denoting the class name. Example: "Window".
70 */
71 const char* className;
72 /**
73 * Pointer to the class information of the base class.
74 * 0L if there is none.
75 */
76 const ClassInfo *parentClass;
77 /**
78 * Static hash-table of properties.
79 */
80 const HashTable *propHashTable;
81 /**
82 * Reserved for future extension.
83 */
84 void *dummy;
85 };
86
87 // This is an internal value object which stores getter and setter functions
88 // for a property.
89 class GetterSetterImp : public JSCell {
90 public:
91 JSType type() const { return GetterSetterType; }
92
93 GetterSetterImp() : getter(0), setter(0) { }
94
95 virtual JSValue *toPrimitive(ExecState *exec, JSType preferred = UnspecifiedType) const;
96 virtual bool toBoolean(ExecState *exec) const;
97 virtual double toNumber(ExecState *exec) const;
98 virtual UString toString(ExecState *exec) const;
99 virtual JSObject *toObject(ExecState *exec) const;
100
101 virtual void mark();
102
103 JSObject *getGetter() { return getter; }
104 void setGetter(JSObject *g) { getter = g; }
105 JSObject *getSetter() { return setter; }
106 void setSetter(JSObject *s) { setter = s; }
107
108 private:
109 JSObject *getter;
110 JSObject *setter;
111 };
112
113 class JSObject : public JSCell {
114 public:
115 /**
116 * Creates a new JSObject with the specified prototype
117 *
118 * @param proto The prototype
119 */
120 JSObject(JSObject *proto, bool destructorIsThreadSafe = true);
121
122 /**
123 * Creates a new JSObject with a prototype of jsNull()
124 * (that is, the ECMAScript "null" value, not a null object pointer).
125 */
126 explicit JSObject(bool destructorIsThreadSafe = true);
127
128 virtual void mark();
129 virtual JSType type() const;
130
131 /**
132 * A pointer to a ClassInfo struct for this class. This provides a basic
133 * facility for run-time type information, and can be used to check an
134 * object's class an inheritance (see inherits()). This should
135 * always return a statically declared pointer, or 0 to indicate that
136 * there is no class information.
137 *
138 * This is primarily useful if you have application-defined classes that you
139 * wish to check against for casting purposes.
140 *
141 * For example, to specify the class info for classes FooImp and BarImp,
142 * where FooImp inherits from BarImp, you would add the following in your
143 * class declarations:
144 *
145 * \code
146 * class BarImp : public JSObject {
147 * virtual const ClassInfo *classInfo() const { return &info; }
148 * static const ClassInfo info;
149 * // ...
150 * };
151 *
152 * class FooImp : public JSObject {
153 * virtual const ClassInfo *classInfo() const { return &info; }
154 * static const ClassInfo info;
155 * // ...
156 * };
157 * \endcode
158 *
159 * And in your source file:
160 *
161 * \code
162 * const ClassInfo BarImp::info = {"Bar", 0, 0, 0}; // no parent class
163 * const ClassInfo FooImp::info = {"Foo", &BarImp::info, 0, 0};
164 * \endcode
165 *
166 * @see inherits()
167 */
168 virtual const ClassInfo *classInfo() const;
169
170 /**
171 * Checks whether this object inherits from the class with the specified
172 * classInfo() pointer. This requires that both this class and the other
173 * class return a non-NULL pointer for their classInfo() methods (otherwise
174 * it will return false).
175 *
176 * For example, for two JSObject pointers obj1 and obj2, you can check
177 * if obj1's class inherits from obj2's class using the following:
178 *
179 * if (obj1->inherits(obj2->classInfo())) {
180 * // ...
181 * }
182 *
183 * If you have a handle to a statically declared ClassInfo, such as in the
184 * classInfo() example, you can check for inheritance without needing
185 * an instance of the other class:
186 *
187 * if (obj1->inherits(FooImp::info)) {
188 * // ...
189 * }
190 *
191 * @param cinfo The ClassInfo pointer for the class you want to check
192 * inheritance against.
193 * @return true if this object's class inherits from class with the
194 * ClassInfo pointer specified in cinfo
195 */
196 bool inherits(const ClassInfo *cinfo) const;
197
198 // internal properties (ECMA 262-3 8.6.2)
199
200 /**
201 * Returns the prototype of this object. Note that this is not the same as
202 * the "prototype" property.
203 *
204 * See ECMA 8.6.2
205 *
206 * @return The object's prototype
207 */
208 JSValue *prototype() const;
209 void setPrototype(JSValue *proto);
210
211 /**
212 * Returns the class name of the object
213 *
214 * See ECMA 8.6.2
215 *
216 * @return The object's class name
217 */
218 /**
219 * Implementation of the [[Class]] internal property (implemented by all
220 * Objects)
221 *
222 * The default implementation uses classInfo().
223 * You should either implement classInfo(), or
224 * if you simply need a classname, you can reimplement className()
225 * instead.
226 */
227 virtual UString className() const;
228
229 /**
230 * Retrieves the specified property from the object. If neither the object
231 * or any other object in it's prototype chain have the property, this
232 * function will return Undefined.
233 *
234 * See ECMA 8.6.2.1
235 *
236 * @param exec The current execution state
237 * @param propertyName The name of the property to retrieve
238 *
239 * @return The specified property, or Undefined
240 */
241 JSValue *get(ExecState *exec, const Identifier &propertyName) const;
242 JSValue *get(ExecState *exec, unsigned propertyName) const;
243
244 bool getPropertySlot(ExecState *, const Identifier&, PropertySlot&);
245 bool getPropertySlot(ExecState *, unsigned, PropertySlot&);
246
247 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
248 virtual bool getOwnPropertySlot(ExecState *, unsigned index, PropertySlot&);
249
250 /**
251 * Sets the specified property.
252 *
253 * See ECMA 8.6.2.2
254 *
255 * @param exec The current execution state
256 * @param propertyName The name of the property to set
257 * @param propertyValue The value to set
258 */
259 virtual void put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr = None);
260 virtual void put(ExecState *exec, unsigned propertyName, JSValue *value, int attr = None);
261
262 /**
263 * Used to check whether or not a particular property is allowed to be set
264 * on an object
265 *
266 * See ECMA 8.6.2.3
267 *
268 * @param exec The current execution state
269 * @param propertyName The name of the property
270 * @return true if the property can be set, otherwise false
271 */
272 /**
273 * Implementation of the [[CanPut]] internal property (implemented by all
274 * Objects)
275 */
276 virtual bool canPut(ExecState *exec, const Identifier &propertyName) const;
277
278 /**
279 * Checks if a property is enumerable, that is if it doesn't have the DontEnum
280 * flag set
281 *
282 * See ECMA 15.2.4
283 * @param exec The current execution state
284 * @param propertyName The name of the property
285 * @return true if the property is enumerable, otherwise false
286 */
287 bool propertyIsEnumerable(ExecState *exec, const Identifier &propertyName) const;
288
289 /**
290 * Checks to see whether the object (or any object in it's prototype chain)
291 * has a property with the specified name.
292 *
293 * See ECMA 8.6.2.4
294 *
295 * @param exec The current execution state
296 * @param propertyName The name of the property to check for
297 * @return true if the object has the property, otherwise false
298 */
299 bool hasProperty(ExecState *exec, const Identifier &propertyName) const;
300 bool hasProperty(ExecState *exec, unsigned propertyName) const;
301
302 /**
303 * Removes the specified property from the object.
304 *
305 * See ECMA 8.6.2.5
306 *
307 * @param exec The current execution state
308 * @param propertyName The name of the property to delete
309 * @return true if the property was successfully deleted or did not
310 * exist on the object. false if deleting the specified property is not
311 * allowed.
312 */
313 virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
314 virtual bool deleteProperty(ExecState *exec, unsigned propertyName);
315
316 /**
317 * Converts the object into a primitive value. The value return may differ
318 * depending on the supplied hint
319 *
320 * See ECMA 8.6.2.6
321 *
322 * @param exec The current execution state
323 * @param hint The desired primitive type to convert to
324 * @return A primitive value converted from the objetc. Note that the
325 * type of primitive value returned may not be the same as the requested
326 * hint.
327 */
328 /**
329 * Implementation of the [[DefaultValue]] internal property (implemented by
330 * all Objects)
331 */
332 virtual JSValue *defaultValue(ExecState *exec, JSType hint) const;
333
334 /**
335 * Whether or not the object implements the construct() method. If this
336 * returns false you should not call the construct() method on this
337 * object (typically, an assertion will fail to indicate this).
338 *
339 * @return true if this object implements the construct() method, otherwise
340 * false
341 */
342 virtual bool implementsConstruct() const;
343
344 /**
345 * Creates a new object based on this object. Typically this means the
346 * following:
347 * 1. A new object is created
348 * 2. The prototype of the new object is set to the value of this object's
349 * "prototype" property
350 * 3. The call() method of this object is called, with the new object
351 * passed as the this value
352 * 4. The new object is returned
353 *
354 * In some cases, Host objects may differ from these semantics, although
355 * this is discouraged.
356 *
357 * If an error occurs during construction, the execution state's exception
358 * will be set. This can be tested for with ExecState::hadException().
359 * Under some circumstances, the exception object may also be returned.
360 *
361 * Note: This function should not be called if implementsConstruct() returns
362 * false, in which case it will result in an assertion failure.
363 *
364 * @param exec The current execution state
365 * @param args The arguments to be passed to call() once the new object has
366 * been created
367 * @return The newly created &amp; initialized object
368 */
369 /**
370 * Implementation of the [[Construct]] internal property
371 */
372 virtual JSObject* construct(ExecState* exec, const List& args);
373 virtual JSObject* construct(ExecState* exec, const List& args, const Identifier& functionName, const UString& sourceURL, int lineNumber);
374
375 /**
376 * Whether or not the object implements the call() method. If this returns
377 * false you should not call the call() method on this object (typically,
378 * an assertion will fail to indicate this).
379 *
380 * @return true if this object implements the call() method, otherwise
381 * false
382 */
383 virtual bool implementsCall() const;
384
385 /**
386 * Calls this object as if it is a function.
387 *
388 * Note: This function should not be called if implementsCall() returns
389 * false, in which case it will result in an assertion failure.
390 *
391 * See ECMA 8.6.2.3
392 *
393 * @param exec The current execution state
394 * @param thisObj The obj to be used as "this" within function execution.
395 * Note that in most cases this will be different from the C++ "this"
396 * object. For example, if the ECMAScript code "window.location->toString()"
397 * is executed, call() will be invoked on the C++ object which implements
398 * the toString method, with the thisObj being window.location
399 * @param args List of arguments to be passed to the function
400 * @return The return value from the function
401 */
402 JSValue *call(ExecState *exec, JSObject *thisObj, const List &args);
403 virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
404
405 /**
406 * Whether or not the object implements the hasInstance() method. If this
407 * returns false you should not call the hasInstance() method on this
408 * object (typically, an assertion will fail to indicate this).
409 *
410 * @return true if this object implements the hasInstance() method,
411 * otherwise false
412 */
413 virtual bool implementsHasInstance() const;
414
415 /**
416 * Checks whether value delegates behavior to this object. Used by the
417 * instanceof operator.
418 *
419 * @param exec The current execution state
420 * @param value The value to check
421 * @return true if value delegates behavior to this object, otherwise
422 * false
423 */
424 virtual bool hasInstance(ExecState *exec, JSValue *value);
425
426 /**
427 * Returns the scope of this object. This is used when execution declared
428 * functions - the execution context for the function is initialized with
429 * extra object in it's scope. An example of this is functions declared
430 * inside other functions:
431 *
432 * \code
433 * function f() {
434 *
435 * function b() {
436 * return prototype;
437 * }
438 *
439 * var x = 4;
440 * // do some stuff
441 * }
442 * f.prototype = new String();
443 * \endcode
444 *
445 * When the function f.b is executed, its scope will include properties of
446 * f. So in the example above the return value of f.b() would be the new
447 * String object that was assigned to f.prototype.
448 *
449 * @param exec The current execution state
450 * @return The function's scope
451 */
452 const ScopeChain &scope() const { return _scope; }
453 void setScope(const ScopeChain &s) { _scope = s; }
454
455 /**
456 * Returns a List of References to all the properties of the object. Used
457 * in "for x in y" statements. The list is created new, so it can be freely
458 * modified without affecting the object's properties. It should be deleted
459 * by the caller.
460 *
461 * Subclasses can override this method in ObjectImpl to provide the
462 * appearance of
463 * having extra properties other than those set specifically with put().
464 *
465 * @param exec The current execution state
466 * @param recursive Whether or not properties in the object's prototype
467 * chain should be
468 * included in the list.
469 * @return A List of References to properties of the object.
470 **/
471 virtual ReferenceList propList(ExecState *exec, bool recursive = true);
472
473 /**
474 * Returns the internal value of the object. This is used for objects such
475 * as String and Boolean which are wrappers for native types. The interal
476 * value is the actual value represented by the wrapper objects.
477 *
478 * @see ECMA 8.6.2
479 * @return The internal value of the object
480 */
481 JSValue *internalValue() const;
482
483 /**
484 * Sets the internal value of the object
485 *
486 * @see internalValue()
487 *
488 * @param v The new internal value
489 */
490 void setInternalValue(JSValue *v);
491
492 JSValue *toPrimitive(ExecState *exec, JSType preferredType = UnspecifiedType) const;
493 bool toBoolean(ExecState *exec) const;
494 double toNumber(ExecState *exec) const;
495 UString toString(ExecState *exec) const;
496 JSObject *toObject(ExecState *exec) const;
497
498 bool getPropertyAttributes(const Identifier& propertyName, int& attributes) const;
499
500 // Returns whether the object should be treated as undefined when doing equality comparisons
501 virtual bool masqueradeAsUndefined() const { return false; }
502
503 // This get function only looks at the property map.
504 // This is used e.g. by lookupOrCreateFunction (to cache a function, we don't want
505 // to look up in the prototype, it might already exist there)
506 JSValue *getDirect(const Identifier& propertyName) const
507 { return _prop.get(propertyName); }
508 JSValue **getDirectLocation(const Identifier& propertyName)
509 { return _prop.getLocation(propertyName); }
510 void putDirect(const Identifier &propertyName, JSValue *value, int attr = 0);
511 void putDirect(const Identifier &propertyName, int value, int attr = 0);
512
513 // convenience to add a function property under the function's own built-in name
514 void putDirectFunction(InternalFunctionImp*, int attr = 0);
515
516 void fillGetterPropertySlot(PropertySlot& slot, JSValue **location);
517
518 void defineGetter(ExecState *exec, const Identifier& propertyName, JSObject *getterFunc);
519 void defineSetter(ExecState *exec, const Identifier& propertyName, JSObject *setterFunc);
520
521 /**
522 * Remove all properties from this object.
523 * This doesn't take DontDelete into account, and isn't in the ECMA spec.
524 * It's simply a quick way to remove everything stored in the property map.
525 */
526 void clearProperties() { _prop.clear(); }
527
528 void saveProperties(SavedProperties &p) const { _prop.save(p); }
529 void restoreProperties(const SavedProperties &p) { _prop.restore(p); }
530
531 virtual bool isActivation() { return false; }
532 protected:
533 PropertyMap _prop;
534 private:
535 const HashEntry* findPropertyHashEntry( const Identifier& propertyName ) const;
536 JSValue *_proto;
537 JSValue *_internalValue;
538 ScopeChain _scope;
539 };
540
541 /**
542 * Types of Native Errors available. For custom errors, GeneralError
543 * should be used.
544 */
545 enum ErrorType { GeneralError = 0,
546 EvalError = 1,
547 RangeError = 2,
548 ReferenceError = 3,
549 SyntaxError = 4,
550 TypeError = 5,
551 URIError = 6};
552
553 /**
554 * @short Factory methods for error objects.
555 */
556 class Error {
557 public:
558 /**
559 * Factory method for error objects.
560 *
561 * @param exec The current execution state
562 * @param errtype Type of error.
563 * @param message Optional error message.
564 * @param lineNumber Optional line number.
565 * @param sourceId Optional source id.
566 * @param sourceURL Optional source URL.
567 */
568 static JSObject *create(ExecState *, ErrorType, const UString &message, int lineNumber, int sourceId, const UString *sourceURL);
569 static JSObject *create(ExecState *, ErrorType, const char *message);
570
571 /**
572 * Array of error names corresponding to ErrorType
573 */
574 static const char * const * const errorNames;
575 };
576
577JSObject *throwError(ExecState *, ErrorType, const UString &message, int lineNumber, int sourceId, const UString *sourceURL);
578JSObject *throwError(ExecState *, ErrorType, const UString &message);
579JSObject *throwError(ExecState *, ErrorType, const char *message);
580JSObject *throwError(ExecState *, ErrorType);
581
582inline JSObject::JSObject(JSObject *proto, bool destructorIsThreadSafe)
583 : JSCell(destructorIsThreadSafe)
584 , _proto(proto)
585 , _internalValue(0)
586{
587 assert(proto);
588}
589
590inline JSObject::JSObject(bool destructorIsThreadSafe)
591 : JSCell(destructorIsThreadSafe)
592 , _proto(jsNull())
593 , _internalValue(0)
594{
595}
596
597inline JSValue *JSObject::internalValue() const
598{
599 return _internalValue;
600}
601
602inline void JSObject::setInternalValue(JSValue *v)
603{
604 _internalValue = v;
605}
606
607inline JSValue *JSObject::prototype() const
608{
609 return _proto;
610}
611
612inline void JSObject::setPrototype(JSValue *proto)
613{
614 assert(proto);
615 _proto = proto;
616}
617
618inline bool JSObject::inherits(const ClassInfo *info) const
619{
620 for (const ClassInfo *ci = classInfo(); ci; ci = ci->parentClass)
621 if (ci == info)
622 return true;
623 return false;
624}
625
626// this method is here to be after the inline declaration of JSObject::inherits
627inline bool JSCell::isObject(const ClassInfo *info) const
628{
629 return isObject() && static_cast<const JSObject *>(this)->inherits(info);
630}
631
632// this method is here to be after the inline declaration of JSCell::isObject
633inline bool JSValue::isObject(const ClassInfo *c) const
634{
635 return !JSImmediate::isImmediate(this) && downcast()->isObject(c);
636}
637
638// It may seem crazy to inline a function this large but it makes a big difference
639// since this is function very hot in variable lookup
640inline bool JSObject::getPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
641{
642 JSObject *object = this;
643 while (true) {
644 if (object->getOwnPropertySlot(exec, propertyName, slot))
645 return true;
646
647 JSValue *proto = object->_proto;
648 if (!proto->isObject())
649 return false;
650
651 object = static_cast<JSObject *>(proto);
652 }
653}
654
655// It may seem crazy to inline a function this large, especially a virtual function,
656// but it makes a big difference to property lookup that derived classes can inline their
657// base class call to this.
658ALWAYS_INLINE bool JSObject::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
659{
660 if (JSValue **location = getDirectLocation(propertyName)) {
661 if (_prop.hasGetterSetterProperties() && location[0]->type() == GetterSetterType)
662 fillGetterPropertySlot(slot, location);
663 else
664 slot.setValueSlot(this, location);
665 return true;
666 }
667
668 // non-standard Netscape extension
669 if (propertyName == exec->dynamicInterpreter()->specialPrototypeIdentifier()) {
670 slot.setValueSlot(this, &_proto);
671 return true;
672 }
673
674 return false;
675}
676
677// FIXME: Put this function in a separate file named something like scope_chain_mark.h -- can't put it in scope_chain.h since it depends on JSObject.
678
679inline void ScopeChain::mark()
680{
681 for (ScopeChainNode *n = _node; n; n = n->next) {
682 JSObject *o = n->object;
683 if (!o->marked())
684 o->mark();
685 }
686}
687
688inline void ScopeChain::release()
689{
690 // This function is only called by deref(),
691 // Deref ensures these conditions are true.
692 assert(_node && _node->refCount == 0);
693 ScopeChainNode *n = _node;
694 do {
695 ScopeChainNode *next = n->next;
696 delete n;
697 n = next;
698 } while (n && --n->refCount == 0);
699}
700
701inline JSValue* JSObject::toPrimitive(ExecState* exec, JSType preferredType) const
702{
703 return defaultValue(exec, preferredType);
704}
705
706} // namespace
707
708#endif // KJS_OBJECT_H
Note: See TracBrowser for help on using the repository browser.