]>
Commit | Line | Data |
---|---|---|
b37bf2e1 A |
1 | // -*- c-basic-offset: 2 -*- |
2 | /* | |
3 | * This file is part of the KDE libraries | |
4 | * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) | |
5 | * Copyright (C) 2001 Peter Kelly (pmk@post.com) | |
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 | #include "CommonIdentifiers.h" | |
29 | #include "ExecState.h" | |
30 | #include "JSType.h" | |
31 | #include "list.h" | |
32 | #include "property_map.h" | |
33 | #include "property_slot.h" | |
34 | #include "scope_chain.h" | |
35 | ||
36 | namespace KJS { | |
37 | ||
38 | class InternalFunctionImp; | |
39 | class PropertyNameArray; | |
40 | ||
41 | struct HashEntry; | |
42 | struct HashTable; | |
43 | ||
44 | // ECMA 262-3 8.6.1 | |
45 | // Property attributes | |
46 | enum Attribute { None = 0, | |
47 | ReadOnly = 1 << 1, // property can be only read, not written | |
48 | DontEnum = 1 << 2, // property doesn't appear in (for .. in ..) | |
49 | DontDelete = 1 << 3, // property can't be deleted | |
50 | Internal = 1 << 4, // an internal property, set to bypass checks | |
51 | Function = 1 << 5, // property is a function - only used by static hashtables | |
52 | GetterSetter = 1 << 6 }; // property is a getter or setter | |
53 | ||
54 | /** | |
55 | * Class Information | |
56 | */ | |
57 | struct ClassInfo { | |
58 | /** | |
59 | * A string denoting the class name. Example: "Window". | |
60 | */ | |
61 | const char* className; | |
62 | /** | |
63 | * Pointer to the class information of the base class. | |
64 | * 0L if there is none. | |
65 | */ | |
66 | const ClassInfo* parentClass; | |
67 | /** | |
68 | * Static hash-table of properties. | |
69 | */ | |
70 | const HashTable* propHashTable; | |
71 | }; | |
72 | ||
73 | // This is an internal value object which stores getter and setter functions | |
74 | // for a property. | |
75 | class GetterSetterImp : public JSCell { | |
76 | public: | |
77 | JSType type() const { return GetterSetterType; } | |
78 | ||
79 | GetterSetterImp() : getter(0), setter(0) { } | |
80 | ||
81 | virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const; | |
82 | virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value); | |
83 | virtual bool toBoolean(ExecState *exec) const; | |
84 | virtual double toNumber(ExecState *exec) const; | |
85 | virtual UString toString(ExecState *exec) const; | |
86 | virtual JSObject *toObject(ExecState *exec) const; | |
87 | ||
88 | virtual void mark(); | |
89 | ||
90 | JSObject *getGetter() { return getter; } | |
91 | void setGetter(JSObject *g) { getter = g; } | |
92 | JSObject *getSetter() { return setter; } | |
93 | void setSetter(JSObject *s) { setter = s; } | |
94 | ||
95 | private: | |
96 | JSObject *getter; | |
97 | JSObject *setter; | |
98 | }; | |
99 | ||
100 | class JSObject : public JSCell { | |
101 | public: | |
102 | /** | |
103 | * Creates a new JSObject with the specified prototype | |
104 | * | |
105 | * @param proto The prototype | |
106 | */ | |
107 | JSObject(JSValue* proto); | |
108 | ||
109 | /** | |
110 | * Creates a new JSObject with a prototype of jsNull() | |
111 | * (that is, the ECMAScript "null" value, not a null object pointer). | |
112 | */ | |
113 | JSObject(); | |
114 | ||
115 | virtual void mark(); | |
116 | virtual JSType type() const; | |
117 | ||
118 | /** | |
119 | * A pointer to a ClassInfo struct for this class. This provides a basic | |
120 | * facility for run-time type information, and can be used to check an | |
121 | * object's class an inheritance (see inherits()). This should | |
122 | * always return a statically declared pointer, or 0 to indicate that | |
123 | * there is no class information. | |
124 | * | |
125 | * This is primarily useful if you have application-defined classes that you | |
126 | * wish to check against for casting purposes. | |
127 | * | |
128 | * For example, to specify the class info for classes FooImp and BarImp, | |
129 | * where FooImp inherits from BarImp, you would add the following in your | |
130 | * class declarations: | |
131 | * | |
132 | * \code | |
133 | * class BarImp : public JSObject { | |
134 | * virtual const ClassInfo *classInfo() const { return &info; } | |
135 | * static const ClassInfo info; | |
136 | * // ... | |
137 | * }; | |
138 | * | |
139 | * class FooImp : public JSObject { | |
140 | * virtual const ClassInfo *classInfo() const { return &info; } | |
141 | * static const ClassInfo info; | |
142 | * // ... | |
143 | * }; | |
144 | * \endcode | |
145 | * | |
146 | * And in your source file: | |
147 | * | |
148 | * \code | |
149 | * const ClassInfo BarImp::info = { "Bar", 0, 0 }; // no parent class | |
150 | * const ClassInfo FooImp::info = { "Foo", &BarImp::info, 0 }; | |
151 | * \endcode | |
152 | * | |
153 | * @see inherits() | |
154 | */ | |
155 | virtual const ClassInfo *classInfo() const; | |
156 | ||
157 | /** | |
158 | * Checks whether this object inherits from the class with the specified | |
159 | * classInfo() pointer. This requires that both this class and the other | |
160 | * class return a non-NULL pointer for their classInfo() methods (otherwise | |
161 | * it will return false). | |
162 | * | |
163 | * For example, for two JSObject pointers obj1 and obj2, you can check | |
164 | * if obj1's class inherits from obj2's class using the following: | |
165 | * | |
166 | * if (obj1->inherits(obj2->classInfo())) { | |
167 | * // ... | |
168 | * } | |
169 | * | |
170 | * If you have a handle to a statically declared ClassInfo, such as in the | |
171 | * classInfo() example, you can check for inheritance without needing | |
172 | * an instance of the other class: | |
173 | * | |
174 | * if (obj1->inherits(FooImp::info)) { | |
175 | * // ... | |
176 | * } | |
177 | * | |
178 | * @param cinfo The ClassInfo pointer for the class you want to check | |
179 | * inheritance against. | |
180 | * @return true if this object's class inherits from class with the | |
181 | * ClassInfo pointer specified in cinfo | |
182 | */ | |
183 | bool inherits(const ClassInfo *cinfo) const; | |
184 | ||
185 | // internal properties (ECMA 262-3 8.6.2) | |
186 | ||
187 | /** | |
188 | * Returns the prototype of this object. Note that this is not the same as | |
189 | * the "prototype" property. | |
190 | * | |
191 | * See ECMA 8.6.2 | |
192 | * | |
193 | * @return The object's prototype | |
194 | */ | |
195 | JSValue *prototype() const; | |
196 | void setPrototype(JSValue *proto); | |
197 | ||
198 | /** | |
199 | * Returns the class name of the object | |
200 | * | |
201 | * See ECMA 8.6.2 | |
202 | * | |
203 | * @return The object's class name | |
204 | */ | |
205 | /** | |
206 | * Implementation of the [[Class]] internal property (implemented by all | |
207 | * Objects) | |
208 | * | |
209 | * The default implementation uses classInfo(). | |
210 | * You should either implement classInfo(), or | |
211 | * if you simply need a classname, you can reimplement className() | |
212 | * instead. | |
213 | */ | |
214 | virtual UString className() const; | |
215 | ||
216 | /** | |
217 | * Retrieves the specified property from the object. If neither the object | |
218 | * or any other object in it's prototype chain have the property, this | |
219 | * function will return Undefined. | |
220 | * | |
221 | * See ECMA 8.6.2.1 | |
222 | * | |
223 | * @param exec The current execution state | |
224 | * @param propertyName The name of the property to retrieve | |
225 | * | |
226 | * @return The specified property, or Undefined | |
227 | */ | |
228 | JSValue *get(ExecState *exec, const Identifier &propertyName) const; | |
229 | JSValue *get(ExecState *exec, unsigned propertyName) const; | |
230 | ||
231 | bool getPropertySlot(ExecState *, const Identifier&, PropertySlot&); | |
232 | bool getPropertySlot(ExecState *, unsigned, PropertySlot&); | |
233 | ||
234 | virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); | |
235 | virtual bool getOwnPropertySlot(ExecState *, unsigned index, PropertySlot&); | |
236 | ||
237 | /** | |
238 | * Sets the specified property. | |
239 | * | |
240 | * See ECMA 8.6.2.2 | |
241 | * | |
242 | * @param exec The current execution state | |
243 | * @param propertyName The name of the property to set | |
244 | * @param propertyValue The value to set | |
245 | */ | |
246 | virtual void put(ExecState* exec, const Identifier &propertyName, JSValue* value, int attr = None); | |
247 | virtual void put(ExecState* exec, unsigned propertyName, JSValue* value, int attr = None); | |
248 | ||
249 | /** | |
250 | * Used to check whether or not a particular property is allowed to be set | |
251 | * on an object | |
252 | * | |
253 | * See ECMA 8.6.2.3 | |
254 | * | |
255 | * @param exec The current execution state | |
256 | * @param propertyName The name of the property | |
257 | * @return true if the property can be set, otherwise false | |
258 | */ | |
259 | /** | |
260 | * Implementation of the [[CanPut]] internal property (implemented by all | |
261 | * Objects) | |
262 | */ | |
263 | virtual bool canPut(ExecState *exec, const Identifier &propertyName) const; | |
264 | ||
265 | /** | |
266 | * Checks if a property is enumerable, that is if it doesn't have the DontEnum | |
267 | * flag set | |
268 | * | |
269 | * See ECMA 15.2.4 | |
270 | * @param exec The current execution state | |
271 | * @param propertyName The name of the property | |
272 | * @return true if the property is enumerable, otherwise false | |
273 | */ | |
274 | bool propertyIsEnumerable(ExecState *exec, const Identifier &propertyName) const; | |
275 | ||
276 | /** | |
277 | * Checks to see whether the object (or any object in it's prototype chain) | |
278 | * has a property with the specified name. | |
279 | * | |
280 | * See ECMA 8.6.2.4 | |
281 | * | |
282 | * @param exec The current execution state | |
283 | * @param propertyName The name of the property to check for | |
284 | * @return true if the object has the property, otherwise false | |
285 | */ | |
286 | bool hasProperty(ExecState*, const Identifier&) const; | |
287 | bool hasProperty(ExecState*, unsigned) const; | |
288 | bool hasOwnProperty(ExecState*, const Identifier&) const; | |
289 | ||
290 | /** | |
291 | * Removes the specified property from the object. | |
292 | * | |
293 | * See ECMA 8.6.2.5 | |
294 | * | |
295 | * @param exec The current execution state | |
296 | * @param propertyName The name of the property to delete | |
297 | * @return true if the property was successfully deleted or did not | |
298 | * exist on the object. false if deleting the specified property is not | |
299 | * allowed. | |
300 | */ | |
301 | virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName); | |
302 | virtual bool deleteProperty(ExecState *exec, unsigned propertyName); | |
303 | ||
304 | /** | |
305 | * Converts the object into a primitive value. The value return may differ | |
306 | * depending on the supplied hint | |
307 | * | |
308 | * See ECMA 8.6.2.6 | |
309 | * | |
310 | * @param exec The current execution state | |
311 | * @param hint The desired primitive type to convert to | |
312 | * @return A primitive value converted from the objetc. Note that the | |
313 | * type of primitive value returned may not be the same as the requested | |
314 | * hint. | |
315 | */ | |
316 | /** | |
317 | * Implementation of the [[DefaultValue]] internal property (implemented by | |
318 | * all Objects) | |
319 | */ | |
320 | virtual JSValue *defaultValue(ExecState *exec, JSType hint) const; | |
321 | ||
322 | /** | |
323 | * Whether or not the object implements the construct() method. If this | |
324 | * returns false you should not call the construct() method on this | |
325 | * object (typically, an assertion will fail to indicate this). | |
326 | * | |
327 | * @return true if this object implements the construct() method, otherwise | |
328 | * false | |
329 | */ | |
330 | virtual bool implementsConstruct() const; | |
331 | ||
332 | /** | |
333 | * Creates a new object based on this object. Typically this means the | |
334 | * following: | |
335 | * 1. A new object is created | |
336 | * 2. The prototype of the new object is set to the value of this object's | |
337 | * "prototype" property | |
338 | * 3. The call() method of this object is called, with the new object | |
339 | * passed as the this value | |
340 | * 4. The new object is returned | |
341 | * | |
342 | * In some cases, Host objects may differ from these semantics, although | |
343 | * this is discouraged. | |
344 | * | |
345 | * If an error occurs during construction, the execution state's exception | |
346 | * will be set. This can be tested for with ExecState::hadException(). | |
347 | * Under some circumstances, the exception object may also be returned. | |
348 | * | |
349 | * Note: This function should not be called if implementsConstruct() returns | |
350 | * false, in which case it will result in an assertion failure. | |
351 | * | |
352 | * @param exec The current execution state | |
353 | * @param args The arguments to be passed to call() once the new object has | |
354 | * been created | |
355 | * @return The newly created & initialized object | |
356 | */ | |
357 | /** | |
358 | * Implementation of the [[Construct]] internal property | |
359 | */ | |
360 | virtual JSObject* construct(ExecState* exec, const List& args); | |
361 | virtual JSObject* construct(ExecState* exec, const List& args, const Identifier& functionName, const UString& sourceURL, int lineNumber); | |
362 | ||
363 | /** | |
364 | * Whether or not the object implements the call() method. If this returns | |
365 | * false you should not call the call() method on this object (typically, | |
366 | * an assertion will fail to indicate this). | |
367 | * | |
368 | * @return true if this object implements the call() method, otherwise | |
369 | * false | |
370 | */ | |
371 | virtual bool implementsCall() const; | |
372 | ||
373 | /** | |
374 | * Calls this object as if it is a function. | |
375 | * | |
376 | * Note: This function should not be called if implementsCall() returns | |
377 | * false, in which case it will result in an assertion failure. | |
378 | * | |
379 | * See ECMA 8.6.2.3 | |
380 | * | |
381 | * @param exec The current execution state | |
382 | * @param thisObj The obj to be used as "this" within function execution. | |
383 | * Note that in most cases this will be different from the C++ "this" | |
384 | * object. For example, if the ECMAScript code "window.location->toString()" | |
385 | * is executed, call() will be invoked on the C++ object which implements | |
386 | * the toString method, with the thisObj being window.location | |
387 | * @param args List of arguments to be passed to the function | |
388 | * @return The return value from the function | |
389 | */ | |
390 | JSValue *call(ExecState *exec, JSObject *thisObj, const List &args); | |
391 | virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); | |
392 | ||
393 | /** | |
394 | * Whether or not the object implements the hasInstance() method. If this | |
395 | * returns false you should not call the hasInstance() method on this | |
396 | * object (typically, an assertion will fail to indicate this). | |
397 | * | |
398 | * @return true if this object implements the hasInstance() method, | |
399 | * otherwise false | |
400 | */ | |
401 | virtual bool implementsHasInstance() const; | |
402 | ||
403 | /** | |
404 | * Checks whether value delegates behavior to this object. Used by the | |
405 | * instanceof operator. | |
406 | * | |
407 | * @param exec The current execution state | |
408 | * @param value The value to check | |
409 | * @return true if value delegates behavior to this object, otherwise | |
410 | * false | |
411 | */ | |
412 | virtual bool hasInstance(ExecState *exec, JSValue *value); | |
413 | ||
414 | virtual void getPropertyNames(ExecState*, PropertyNameArray&); | |
415 | ||
416 | virtual JSValue* toPrimitive(ExecState*, JSType preferredType = UnspecifiedType) const; | |
417 | virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value); | |
418 | virtual bool toBoolean(ExecState *exec) const; | |
419 | virtual double toNumber(ExecState *exec) const; | |
420 | virtual UString toString(ExecState *exec) const; | |
421 | virtual JSObject *toObject(ExecState *exec) const; | |
422 | ||
423 | bool getPropertyAttributes(const Identifier& propertyName, unsigned& attributes) const; | |
424 | ||
425 | // WebCore uses this to make document.all and style.filter undetectable | |
426 | virtual bool masqueradeAsUndefined() const { return false; } | |
427 | ||
428 | // This get function only looks at the property map. | |
429 | // This is used e.g. by lookupOrCreateFunction (to cache a function, we don't want | |
430 | // to look up in the prototype, it might already exist there) | |
431 | JSValue *getDirect(const Identifier& propertyName) const | |
432 | { return _prop.get(propertyName); } | |
433 | JSValue **getDirectLocation(const Identifier& propertyName) | |
434 | { return _prop.getLocation(propertyName); } | |
435 | void putDirect(const Identifier &propertyName, JSValue *value, int attr = 0); | |
436 | void putDirect(const Identifier &propertyName, int value, int attr = 0); | |
437 | void removeDirect(const Identifier &propertyName); | |
438 | ||
439 | // convenience to add a function property under the function's own built-in name | |
440 | void putDirectFunction(InternalFunctionImp*, int attr = 0); | |
441 | ||
442 | void fillGetterPropertySlot(PropertySlot& slot, JSValue **location); | |
443 | ||
444 | void defineGetter(ExecState *exec, const Identifier& propertyName, JSObject *getterFunc); | |
445 | void defineSetter(ExecState *exec, const Identifier& propertyName, JSObject *setterFunc); | |
446 | ||
447 | void saveProperties(SavedProperties &p) const { _prop.save(p); } | |
448 | void restoreProperties(const SavedProperties &p) { _prop.restore(p); } | |
449 | ||
450 | virtual bool isActivationObject() { return false; } | |
451 | virtual bool isGlobalObject() const { return false; } | |
452 | ||
453 | protected: | |
454 | PropertyMap _prop; | |
455 | ||
456 | private: | |
457 | const HashEntry* findPropertyHashEntry( const Identifier& propertyName ) const; | |
458 | JSValue *_proto; | |
459 | }; | |
460 | ||
461 | /** | |
462 | * Types of Native Errors available. For custom errors, GeneralError | |
463 | * should be used. | |
464 | */ | |
465 | enum ErrorType { GeneralError = 0, | |
466 | EvalError = 1, | |
467 | RangeError = 2, | |
468 | ReferenceError = 3, | |
469 | SyntaxError = 4, | |
470 | TypeError = 5, | |
471 | URIError = 6, | |
472 | TimeoutError = 7 | |
473 | }; | |
474 | ||
475 | /** | |
476 | * @short Factory methods for error objects. | |
477 | */ | |
478 | class Error { | |
479 | public: | |
480 | /** | |
481 | * Factory method for error objects. | |
482 | * | |
483 | * @param exec The current execution state | |
484 | * @param errtype Type of error. | |
485 | * @param message Optional error message. | |
486 | * @param lineNumber Optional line number. | |
487 | * @param sourceId Optional source id. | |
488 | * @param sourceURL Optional source URL. | |
489 | */ | |
490 | static JSObject *create(ExecState *, ErrorType, const UString &message, int lineNumber, int sourceId, const UString &sourceURL); | |
491 | static JSObject *create(ExecState *, ErrorType, const char *message); | |
492 | ||
493 | /** | |
494 | * Array of error names corresponding to ErrorType | |
495 | */ | |
496 | static const char * const * const errorNames; | |
497 | }; | |
498 | ||
499 | JSObject *throwError(ExecState *, ErrorType, const UString &message, int lineNumber, int sourceId, const UString &sourceURL); | |
500 | JSObject *throwError(ExecState *, ErrorType, const UString &message); | |
501 | JSObject *throwError(ExecState *, ErrorType, const char *message); | |
502 | JSObject *throwError(ExecState *, ErrorType); | |
503 | ||
504 | inline JSObject::JSObject(JSValue* proto) | |
505 | : _proto(proto) | |
506 | { | |
507 | ASSERT(proto); | |
508 | } | |
509 | ||
510 | inline JSObject::JSObject() | |
511 | : _proto(jsNull()) | |
512 | { | |
513 | } | |
514 | ||
515 | inline JSValue *JSObject::prototype() const | |
516 | { | |
517 | return _proto; | |
518 | } | |
519 | ||
520 | inline void JSObject::setPrototype(JSValue *proto) | |
521 | { | |
522 | ASSERT(proto); | |
523 | _proto = proto; | |
524 | } | |
525 | ||
526 | inline bool JSObject::inherits(const ClassInfo *info) const | |
527 | { | |
528 | for (const ClassInfo *ci = classInfo(); ci; ci = ci->parentClass) | |
529 | if (ci == info) | |
530 | return true; | |
531 | return false; | |
532 | } | |
533 | ||
534 | // this method is here to be after the inline declaration of JSObject::inherits | |
535 | inline bool JSCell::isObject(const ClassInfo *info) const | |
536 | { | |
537 | return isObject() && static_cast<const JSObject *>(this)->inherits(info); | |
538 | } | |
539 | ||
540 | // this method is here to be after the inline declaration of JSCell::isObject | |
541 | inline bool JSValue::isObject(const ClassInfo *c) const | |
542 | { | |
543 | return !JSImmediate::isImmediate(this) && asCell()->isObject(c); | |
544 | } | |
545 | ||
546 | // It may seem crazy to inline a function this large but it makes a big difference | |
547 | // since this is function very hot in variable lookup | |
548 | inline bool JSObject::getPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) | |
549 | { | |
550 | JSObject *object = this; | |
551 | while (true) { | |
552 | if (object->getOwnPropertySlot(exec, propertyName, slot)) | |
553 | return true; | |
554 | ||
555 | JSValue *proto = object->_proto; | |
556 | if (!proto->isObject()) | |
557 | return false; | |
558 | ||
559 | object = static_cast<JSObject *>(proto); | |
560 | } | |
561 | } | |
562 | ||
563 | // It may seem crazy to inline a function this large, especially a virtual function, | |
564 | // but it makes a big difference to property lookup that derived classes can inline their | |
565 | // base class call to this. | |
566 | ALWAYS_INLINE bool JSObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) | |
567 | { | |
568 | if (JSValue **location = getDirectLocation(propertyName)) { | |
569 | if (_prop.hasGetterSetterProperties() && location[0]->type() == GetterSetterType) | |
570 | fillGetterPropertySlot(slot, location); | |
571 | else | |
572 | slot.setValueSlot(this, location); | |
573 | return true; | |
574 | } | |
575 | ||
576 | // non-standard Netscape extension | |
577 | if (propertyName == exec->propertyNames().underscoreProto) { | |
578 | slot.setValueSlot(this, &_proto); | |
579 | return true; | |
580 | } | |
581 | ||
582 | return false; | |
583 | } | |
584 | ||
585 | inline void ScopeChain::release() | |
586 | { | |
587 | // This function is only called by deref(), | |
588 | // Deref ensures these conditions are true. | |
589 | ASSERT(_node && _node->refCount == 0); | |
590 | ScopeChainNode *n = _node; | |
591 | do { | |
592 | ScopeChainNode *next = n->next; | |
593 | delete n; | |
594 | n = next; | |
595 | } while (n && --n->refCount == 0); | |
596 | } | |
597 | ||
598 | inline JSValue* JSObject::toPrimitive(ExecState* exec, JSType preferredType) const | |
599 | { | |
600 | return defaultValue(exec, preferredType); | |
601 | } | |
602 | ||
603 | } // namespace | |
604 | ||
605 | #endif // KJS_OBJECT_H |