source: webkit/trunk/JavaScriptCore/kjs/object.cpp@ 30810

Last change on this file since 30810 was 30534, checked in by Darin Adler, 17 years ago

JavaScriptCore:

Reviewed by Anders.

  • API/JSCallbackObject.h: Removed attribute arguments.
  • API/JSCallbackObjectFunctions.h: (KJS::JSCallbackObject<Base>::put): Ditto.
  • API/JSObjectRef.cpp: (JSObjectSetProperty): Use initializeVariable or putDirect when necessary to set attribute values.
  • JavaScriptCore.exp: Updated.
  • bindings/objc/objc_runtime.h: Removed attribute arguments.
  • bindings/objc/objc_runtime.mm: (ObjcFallbackObjectImp::put): Ditto.
  • bindings/runtime_array.cpp: (RuntimeArray::put): Ditto.
  • bindings/runtime_array.h: Ditto.
  • bindings/runtime_object.cpp: (RuntimeObjectImp::put): Ditto.
  • bindings/runtime_object.h: Ditto. Also removed canPut which was only called from one place in WebCore that can use hasProperty instead.
  • kjs/Activation.h: Removed attribute argument from put and added the new initializeVariable function that's used to put variables in variable objects. Also made isActivationObject a const member.
  • kjs/JSGlobalObject.cpp: (KJS::JSGlobalObject::put): Removed attribute argument. (KJS::JSGlobalObject::initializeVariable): Added. Used to give variables their initial values, which can include the read-only property. (KJS::JSGlobalObject::reset): Removed obsolete comments about flags. Removed Internal flag, which is no longer needed.
  • kjs/JSGlobalObject.h: More of the same.
  • kjs/JSVariableObject.h: Added pure virtual initializeVariable function. (KJS::JSVariableObject::symbolTablePut): Removed checkReadOnly flag; we always check read-only. (KJS::JSVariableObject::symbolTableInitializeVariable): Added.
  • kjs/array_instance.cpp: (KJS::ArrayInstance::put): Removed attribute argument.
  • kjs/array_instance.h: Ditto.
  • kjs/function.cpp: (KJS::FunctionImp::put): Ditto. (KJS::Arguments::put): Ditto. (KJS::ActivationImp::put): Ditto. (KJS::ActivationImp::initializeVariable): Added.
  • kjs/function.h: Removed attribute arguments.
  • kjs/function_object.cpp: (KJS::FunctionObjectImp::construct): Removed Internal flag.
  • kjs/lookup.h: (KJS::lookupPut): Removed attributes argument. Also changed to use putDirect instead of calling JSObject::put. (KJS::cacheGlobalObject): Ditto.
  • kjs/nodes.cpp: (KJS::ConstDeclNode::handleSlowCase): Call initializeVariable to initialize the constant. (KJS::ConstDeclNode::evaluateSingle): Ditto. (KJS::TryNode::execute): Use putDirect to set up the new object. (KJS::FunctionBodyNode::processDeclarations): Removed Internal. (KJS::ProgramNode::processDeclarations): Ditto. (KJS::EvalNode::processDeclarations): Call initializeVariable to initialize the variables and functions. (KJS::FuncDeclNode::makeFunction): Removed Internal. (KJS::FuncExprNode::evaluate): Ditto.
  • kjs/object.cpp: Removed canPut, which was only being used in one code path, not the normal high speed one. (KJS::JSObject::put): Removed attribute argument. Moved the logic from canPut here, in the one code ath that was still using it.
  • kjs/object.h: Removed Internal attribute, ad canPut function. Removed the attributes argument to the put function. Made isActivationObject const.
  • kjs/regexp_object.cpp: (KJS::RegExpImp::put): Removed attributes argument. (KJS::RegExpImp::putValueProperty): Ditto. (KJS::RegExpObjectImp::put): Ditto. (KJS::RegExpObjectImp::putValueProperty): Ditto.
  • kjs/regexp_object.h: Ditto.
  • kjs/string_object.cpp: (KJS::StringInstance::put): Removed attributes argument.
  • kjs/string_object.h: Ditto.

WebCore:

Reviewed by Anders.

  • bindings/js/JSCSSStyleDeclarationCustom.cpp: (WebCore::JSCSSStyleDeclaration::customPut): Remove attributes argument.
  • bindings/js/JSCanvasPixelArrayCustom.cpp: (WebCore::JSCanvasPixelArray::indexGetter): Use early exit idiom. (WebCore::JSCanvasPixelArray::indexSetter): Moved length check into the CanvasPixelArray object, for consistency with the getter. Removed attributes argument.
  • bindings/js/JSDOMWindowCustom.cpp: (WebCore::JSDOMWindow::customPut): Removed special case for variable initialization, which is not needed since that does use put any more. Removed attributes argument.
  • bindings/js/JSEventTargetBase.h: (WebCore::JSEventTargetBase::putValueProperty): Removed attributes argument. (WebCore::JSEventTargetBase::put): Ditto. (WebCore::JSEventTargetPrototype::self): Removed Internal flag.
  • bindings/js/JSEventTargetNode.cpp: (WebCore::JSEventTargetNode::put): Removed attributes argument. (WebCore::JSEventTargetNode::putValueProperty): Ditto.
  • bindings/js/JSEventTargetNode.h: Ditto.
  • bindings/js/JSHTMLAppletElementCustom.cpp: (WebCore::JSHTMLAppletElement::customPut): Ditto.
  • bindings/js/JSHTMLEmbedElementCustom.cpp: (WebCore::JSHTMLEmbedElement::customPut): Ditto.
  • bindings/js/JSHTMLInputElementBase.cpp: (WebCore::JSHTMLInputElementBase::put): Ditto. (WebCore::JSHTMLInputElementBase::putValueProperty): Ditto.
  • bindings/js/JSHTMLInputElementBase.h: Ditto.
  • bindings/js/JSHTMLObjectElementCustom.cpp: (WebCore::JSHTMLObjectElement::customPut): Ditto.
  • bindings/js/JSHTMLOptionsCollectionCustom.cpp: (WebCore::JSHTMLOptionsCollection::indexSetter): Ditto.
  • bindings/js/JSHTMLSelectElementCustom.cpp: (WebCore::JSHTMLSelectElement::indexSetter): Ditto.
  • bindings/js/JSHistoryCustom.cpp: (WebCore::JSHistory::customPut): Ditto.
  • bindings/js/JSLocation.cpp: (WebCore::JSLocation::put): Ditto.
  • bindings/js/JSLocation.h: Ditto.
  • bindings/js/JSXMLHttpRequest.cpp: (WebCore::JSXMLHttpRequest::put): Ditto. (WebCore::JSXMLHttpRequest::putValueProperty): Ditto.
  • bindings/js/JSXMLHttpRequest.h: Ditto.
  • bindings/js/kjs_dom.cpp: (WebCore::getRuntimeObject): Changed return type to JSObject*.
  • bindings/js/kjs_dom.h: Ditto.
  • bindings/js/kjs_events.cpp: (WebCore::JSClipboard::put): Removed attributes argument. (WebCore::JSClipboard::putValueProperty): Ditto.
  • bindings/js/kjs_events.h: Ditto.
  • bindings/js/kjs_html.cpp: (WebCore::runtimeObjectGetter): Updated for change to getRuntimeObject to return a JSObject. Used early exit idiom. (WebCore::runtimeObjectPropertyGetter): Ditto. (WebCore::runtimeObjectCustomGetOwnPropertySlot): Ditto. (WebCore::runtimeObjectCustomPut): Use hasProperty to check for properties that we should put with the property syntax instead of canPut. (WebCore::runtimeObjectImplementsCall): Ditto. (WebCore::runtimeObjectCallAsFunction): Ditto.
  • bindings/js/kjs_html.h: Removed attributes argument to runtimeObjectCustomPut.
  • bindings/js/kjs_window.cpp: (KJS::Window::put): Removed attributes argument.
  • bindings/js/kjs_window.h: Ditto.
  • bindings/scripts/CodeGeneratorJS.pm: Removed attributes argument from put, putValueProperty, customPut, and indexSetter.
  • html/CanvasPixelArray.h: (WebCore::CanvasPixelArray::set): Added index checking here, as in the get function. Before, the checking was done in the JavaScript bindings for set.
  • Property svn:eol-style set to native
File size: 17.5 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 * Copyright (C) 2007 Eric Seidel ([email protected])
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 *
24 */
25
26#include "config.h"
27#include "object.h"
28
29#include "date_object.h"
30#include "error_object.h"
31#include "lookup.h"
32#include "nodes.h"
33#include "operations.h"
34#include "PropertyNameArray.h"
35#include <math.h>
36#include <wtf/Assertions.h>
37
38// maximum global call stack size. Protects against accidental or
39// malicious infinite recursions. Define to -1 if you want no limit.
40// In real-world testing it appears ok to bump the stack depth count to 500.
41// This of course is dependent on stack frame size.
42#define KJS_MAX_STACK 500
43
44#define JAVASCRIPT_CALL_TRACING 0
45#define JAVASCRIPT_MARK_TRACING 0
46
47#if JAVASCRIPT_CALL_TRACING
48static bool _traceJavaScript = false;
49
50extern "C" {
51 void setTraceJavaScript(bool f)
52 {
53 _traceJavaScript = f;
54 }
55
56 static bool traceJavaScript()
57 {
58 return _traceJavaScript;
59 }
60}
61#endif
62
63namespace KJS {
64
65// ------------------------------ Object ---------------------------------------
66
67JSValue *JSObject::call(ExecState *exec, JSObject *thisObj, const List &args)
68{
69 ASSERT(implementsCall());
70
71#if KJS_MAX_STACK > 0
72 static int depth = 0; // sum of all extant function calls
73
74#if JAVASCRIPT_CALL_TRACING
75 static bool tracing = false;
76 if (traceJavaScript() && !tracing) {
77 tracing = true;
78 for (int i = 0; i < depth; i++)
79 putchar (' ');
80 printf ("*** calling: %s\n", toString(exec).ascii());
81 for (int j = 0; j < args.size(); j++) {
82 for (int i = 0; i < depth; i++)
83 putchar (' ');
84 printf ("*** arg[%d] = %s\n", j, args[j]->toString(exec).ascii());
85 }
86 tracing = false;
87 }
88#endif
89
90 if (++depth > KJS_MAX_STACK) {
91 --depth;
92 return throwError(exec, RangeError, "Maximum call stack size exceeded.");
93 }
94#endif
95
96 JSValue *ret = callAsFunction(exec,thisObj,args);
97
98#if KJS_MAX_STACK > 0
99 --depth;
100#endif
101
102#if JAVASCRIPT_CALL_TRACING
103 if (traceJavaScript() && !tracing) {
104 tracing = true;
105 for (int i = 0; i < depth; i++)
106 putchar (' ');
107 printf ("*** returning: %s\n", ret->toString(exec).ascii());
108 tracing = false;
109 }
110#endif
111
112 return ret;
113}
114
115// ------------------------------ JSObject ------------------------------------
116
117void JSObject::mark()
118{
119 JSCell::mark();
120
121#if JAVASCRIPT_MARK_TRACING
122 static int markStackDepth = 0;
123 markStackDepth++;
124 for (int i = 0; i < markStackDepth; i++)
125 putchar('-');
126
127 printf("%s (%p)\n", className().UTF8String().c_str(), this);
128#endif
129
130 JSValue *proto = _proto;
131 if (!proto->marked())
132 proto->mark();
133
134 _prop.mark();
135
136#if JAVASCRIPT_MARK_TRACING
137 markStackDepth--;
138#endif
139}
140
141JSType JSObject::type() const
142{
143 return ObjectType;
144}
145
146const ClassInfo *JSObject::classInfo() const
147{
148 return 0;
149}
150
151UString JSObject::className() const
152{
153 const ClassInfo *ci = classInfo();
154 if ( ci )
155 return ci->className;
156 return "Object";
157}
158
159JSValue *JSObject::get(ExecState *exec, const Identifier &propertyName) const
160{
161 PropertySlot slot;
162
163 if (const_cast<JSObject *>(this)->getPropertySlot(exec, propertyName, slot))
164 return slot.getValue(exec, const_cast<JSObject *>(this), propertyName);
165
166 return jsUndefined();
167}
168
169JSValue *JSObject::get(ExecState *exec, unsigned propertyName) const
170{
171 PropertySlot slot;
172 if (const_cast<JSObject *>(this)->getPropertySlot(exec, propertyName, slot))
173 return slot.getValue(exec, const_cast<JSObject *>(this), propertyName);
174
175 return jsUndefined();
176}
177
178bool JSObject::getPropertySlot(ExecState *exec, unsigned propertyName, PropertySlot& slot)
179{
180 JSObject *imp = this;
181
182 while (true) {
183 if (imp->getOwnPropertySlot(exec, propertyName, slot))
184 return true;
185
186 JSValue *proto = imp->_proto;
187 if (!proto->isObject())
188 break;
189
190 imp = static_cast<JSObject *>(proto);
191 }
192
193 return false;
194}
195
196bool JSObject::getOwnPropertySlot(ExecState *exec, unsigned propertyName, PropertySlot& slot)
197{
198 return getOwnPropertySlot(exec, Identifier::from(propertyName), slot);
199}
200
201static void throwSetterError(ExecState *exec)
202{
203 throwError(exec, TypeError, "setting a property that has only a getter");
204}
205
206// ECMA 8.6.2.2
207void JSObject::put(ExecState* exec, const Identifier &propertyName, JSValue *value)
208{
209 ASSERT(value);
210
211 if (propertyName == exec->propertyNames().underscoreProto) {
212 JSObject* proto = value->getObject();
213 while (proto) {
214 if (proto == this)
215 throwError(exec, GeneralError, "cyclic __proto__ value");
216 proto = proto->prototype() ? proto->prototype()->getObject() : 0;
217 }
218
219 setPrototype(value);
220 return;
221 }
222
223 // Check if there are any setters or getters in the prototype chain
224 JSObject *obj = this;
225 bool hasGettersOrSetters = false;
226 while (true) {
227 if (obj->_prop.hasGetterSetterProperties()) {
228 hasGettersOrSetters = true;
229 break;
230 }
231
232 if (!obj->_proto->isObject())
233 break;
234
235 obj = static_cast<JSObject *>(obj->_proto);
236 }
237
238 if (hasGettersOrSetters) {
239 unsigned attributes;
240 if (_prop.get(propertyName, attributes) && attributes & ReadOnly)
241 return;
242
243 obj = this;
244 while (true) {
245 if (JSValue *gs = obj->_prop.get(propertyName, attributes)) {
246 if (attributes & GetterSetter) {
247 JSObject *setterFunc = static_cast<GetterSetterImp *>(gs)->getSetter();
248
249 if (!setterFunc) {
250 throwSetterError(exec);
251 return;
252 }
253
254 List args;
255 args.append(value);
256
257 setterFunc->call(exec, this, args);
258 return;
259 } else {
260 // If there's an existing property on the object or one of its
261 // prototype it should be replaced, so we just break here.
262 break;
263 }
264 }
265
266 if (!obj->_proto->isObject())
267 break;
268
269 obj = static_cast<JSObject *>(obj->_proto);
270 }
271 }
272
273 _prop.put(propertyName, value, 0, true);
274}
275
276void JSObject::put(ExecState* exec, unsigned propertyName, JSValue* value)
277{
278 put(exec, Identifier::from(propertyName), value);
279}
280
281// ECMA 8.6.2.4
282bool JSObject::hasProperty(ExecState *exec, const Identifier &propertyName) const
283{
284 PropertySlot slot;
285 return const_cast<JSObject *>(this)->getPropertySlot(exec, propertyName, slot);
286}
287
288bool JSObject::hasProperty(ExecState *exec, unsigned propertyName) const
289{
290 PropertySlot slot;
291 return const_cast<JSObject *>(this)->getPropertySlot(exec, propertyName, slot);
292}
293
294// ECMA 8.6.2.5
295bool JSObject::deleteProperty(ExecState* /*exec*/, const Identifier &propertyName)
296{
297 unsigned attributes;
298 JSValue *v = _prop.get(propertyName, attributes);
299 if (v) {
300 if ((attributes & DontDelete))
301 return false;
302 _prop.remove(propertyName);
303 if (attributes & GetterSetter)
304 _prop.setHasGetterSetterProperties(_prop.containsGettersOrSetters());
305 return true;
306 }
307
308 // Look in the static hashtable of properties
309 const HashEntry* entry = findPropertyHashEntry(propertyName);
310 if (entry && entry->attr & DontDelete)
311 return false; // this builtin property can't be deleted
312 return true;
313}
314
315bool JSObject::hasOwnProperty(ExecState* exec, const Identifier& propertyName) const
316{
317 PropertySlot slot;
318 return const_cast<JSObject*>(this)->getOwnPropertySlot(exec, propertyName, slot);
319}
320
321bool JSObject::deleteProperty(ExecState *exec, unsigned propertyName)
322{
323 return deleteProperty(exec, Identifier::from(propertyName));
324}
325
326static ALWAYS_INLINE JSValue *tryGetAndCallProperty(ExecState *exec, const JSObject *object, const Identifier &propertyName) {
327 JSValue *v = object->get(exec, propertyName);
328 if (v->isObject()) {
329 JSObject *o = static_cast<JSObject*>(v);
330 if (o->implementsCall()) { // spec says "not primitive type" but ...
331 JSObject *thisObj = const_cast<JSObject*>(object);
332 JSValue* def = o->call(exec, thisObj, exec->emptyList());
333 JSType defType = def->type();
334 ASSERT(defType != GetterSetterType);
335 if (defType != ObjectType)
336 return def;
337 }
338 }
339 return NULL;
340}
341
342bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValue*& result)
343{
344 result = defaultValue(exec, NumberType);
345 number = result->toNumber(exec);
346 return !result->isString();
347}
348
349// ECMA 8.6.2.6
350JSValue* JSObject::defaultValue(ExecState* exec, JSType hint) const
351{
352 /* Prefer String for Date objects */
353 if ((hint == StringType) || (hint != NumberType && _proto == exec->lexicalGlobalObject()->datePrototype())) {
354 if (JSValue* v = tryGetAndCallProperty(exec, this, exec->propertyNames().toString))
355 return v;
356 if (JSValue* v = tryGetAndCallProperty(exec, this, exec->propertyNames().valueOf))
357 return v;
358 } else {
359 if (JSValue* v = tryGetAndCallProperty(exec, this, exec->propertyNames().valueOf))
360 return v;
361 if (JSValue* v = tryGetAndCallProperty(exec, this, exec->propertyNames().toString))
362 return v;
363 }
364
365 if (exec->hadException())
366 return exec->exception();
367
368 return throwError(exec, TypeError, "No default value");
369}
370
371const HashEntry* JSObject::findPropertyHashEntry(const Identifier& propertyName) const
372{
373 for (const ClassInfo *info = classInfo(); info; info = info->parentClass) {
374 if (const HashTable *propHashTable = info->propHashTable) {
375 if (const HashEntry *e = Lookup::findEntry(propHashTable, propertyName))
376 return e;
377 }
378 }
379 return 0;
380}
381
382void JSObject::defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc)
383{
384 JSValue *o = getDirect(propertyName);
385 GetterSetterImp *gs;
386
387 if (o && o->type() == GetterSetterType) {
388 gs = static_cast<GetterSetterImp *>(o);
389 } else {
390 gs = new GetterSetterImp;
391 putDirect(propertyName, gs, GetterSetter);
392 }
393
394 _prop.setHasGetterSetterProperties(true);
395 gs->setGetter(getterFunc);
396}
397
398void JSObject::defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc)
399{
400 JSValue *o = getDirect(propertyName);
401 GetterSetterImp *gs;
402
403 if (o && o->type() == GetterSetterType) {
404 gs = static_cast<GetterSetterImp *>(o);
405 } else {
406 gs = new GetterSetterImp;
407 putDirect(propertyName, gs, GetterSetter);
408 }
409
410 _prop.setHasGetterSetterProperties(true);
411 gs->setSetter(setterFunc);
412}
413
414bool JSObject::implementsConstruct() const
415{
416 return false;
417}
418
419JSObject* JSObject::construct(ExecState*, const List& /*args*/)
420{
421 ASSERT(false);
422 return NULL;
423}
424
425JSObject* JSObject::construct(ExecState* exec, const List& args, const Identifier& /*functionName*/, const UString& /*sourceURL*/, int /*lineNumber*/)
426{
427 return construct(exec, args);
428}
429
430bool JSObject::implementsCall() const
431{
432 return false;
433}
434
435JSValue *JSObject::callAsFunction(ExecState* /*exec*/, JSObject* /*thisObj*/, const List &/*args*/)
436{
437 ASSERT(false);
438 return NULL;
439}
440
441bool JSObject::implementsHasInstance() const
442{
443 return false;
444}
445
446bool JSObject::hasInstance(ExecState* exec, JSValue* value)
447{
448 JSValue* proto = get(exec, exec->propertyNames().prototype);
449 if (!proto->isObject()) {
450 throwError(exec, TypeError, "intanceof called on an object with an invalid prototype property.");
451 return false;
452 }
453
454 if (!value->isObject())
455 return false;
456
457 JSObject* o = static_cast<JSObject*>(value);
458 while ((o = o->prototype()->getObject())) {
459 if (o == proto)
460 return true;
461 }
462 return false;
463}
464
465bool JSObject::propertyIsEnumerable(ExecState*, const Identifier& propertyName) const
466{
467 unsigned attributes;
468
469 if (!getPropertyAttributes(propertyName, attributes))
470 return false;
471 else
472 return !(attributes & DontEnum);
473}
474
475bool JSObject::getPropertyAttributes(const Identifier& propertyName, unsigned& attributes) const
476{
477 if (_prop.get(propertyName, attributes))
478 return true;
479
480 // Look in the static hashtable of properties
481 const HashEntry* e = findPropertyHashEntry(propertyName);
482 if (e) {
483 attributes = e->attr;
484 return true;
485 }
486
487 return false;
488}
489
490void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
491{
492 _prop.getEnumerablePropertyNames(propertyNames);
493
494 // Add properties from the static hashtable of properties
495 const ClassInfo *info = classInfo();
496 while (info) {
497 if (info->propHashTable) {
498 int size = info->propHashTable->size;
499 const HashEntry *e = info->propHashTable->entries;
500 for (int i = 0; i < size; ++i, ++e) {
501 if (e->s && !(e->attr & DontEnum))
502 propertyNames.add(e->s);
503 }
504 }
505 info = info->parentClass;
506 }
507 if (_proto->isObject())
508 static_cast<JSObject*>(_proto)->getPropertyNames(exec, propertyNames);
509}
510
511bool JSObject::toBoolean(ExecState*) const
512{
513 return true;
514}
515
516double JSObject::toNumber(ExecState *exec) const
517{
518 JSValue *prim = toPrimitive(exec,NumberType);
519 if (exec->hadException()) // should be picked up soon in nodes.cpp
520 return 0.0;
521 return prim->toNumber(exec);
522}
523
524UString JSObject::toString(ExecState *exec) const
525{
526 JSValue *prim = toPrimitive(exec,StringType);
527 if (exec->hadException()) // should be picked up soon in nodes.cpp
528 return "";
529 return prim->toString(exec);
530}
531
532JSObject *JSObject::toObject(ExecState*) const
533{
534 return const_cast<JSObject*>(this);
535}
536
537void JSObject::putDirect(const Identifier &propertyName, JSValue *value, int attr)
538{
539 _prop.put(propertyName, value, attr);
540}
541
542void JSObject::putDirect(const Identifier &propertyName, int value, int attr)
543{
544 _prop.put(propertyName, jsNumber(value), attr);
545}
546
547void JSObject::removeDirect(const Identifier &propertyName)
548{
549 _prop.remove(propertyName);
550}
551
552void JSObject::putDirectFunction(InternalFunctionImp* func, int attr)
553{
554 putDirect(func->functionName(), func, attr);
555}
556
557void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue **location)
558{
559 GetterSetterImp *gs = static_cast<GetterSetterImp *>(*location);
560 JSObject *getterFunc = gs->getGetter();
561 if (getterFunc)
562 slot.setGetterSlot(this, getterFunc);
563 else
564 slot.setUndefined(this);
565}
566
567// ------------------------------ Error ----------------------------------------
568
569const char * const errorNamesArr[] = {
570 I18N_NOOP("Error"), // GeneralError
571 I18N_NOOP("Evaluation error"), // EvalError
572 I18N_NOOP("Range error"), // RangeError
573 I18N_NOOP("Reference error"), // ReferenceError
574 I18N_NOOP("Syntax error"), // SyntaxError
575 I18N_NOOP("Type error"), // TypeError
576 I18N_NOOP("URI error"), // URIError
577};
578
579const char * const * const Error::errorNames = errorNamesArr;
580
581JSObject *Error::create(ExecState *exec, ErrorType errtype, const UString &message,
582 int lineno, int sourceId, const UString &sourceURL)
583{
584 JSObject *cons;
585 switch (errtype) {
586 case EvalError:
587 cons = exec->lexicalGlobalObject()->evalErrorConstructor();
588 break;
589 case RangeError:
590 cons = exec->lexicalGlobalObject()->rangeErrorConstructor();
591 break;
592 case ReferenceError:
593 cons = exec->lexicalGlobalObject()->referenceErrorConstructor();
594 break;
595 case SyntaxError:
596 cons = exec->lexicalGlobalObject()->syntaxErrorConstructor();
597 break;
598 case TypeError:
599 cons = exec->lexicalGlobalObject()->typeErrorConstructor();
600 break;
601 case URIError:
602 cons = exec->lexicalGlobalObject()->URIErrorConstructor();
603 break;
604 default:
605 cons = exec->lexicalGlobalObject()->errorConstructor();
606 break;
607 }
608
609 List args;
610 if (message.isEmpty())
611 args.append(jsString(errorNames[errtype]));
612 else
613 args.append(jsString(message));
614 JSObject *err = static_cast<JSObject *>(cons->construct(exec,args));
615
616 if (lineno != -1)
617 err->put(exec, "line", jsNumber(lineno));
618 if (sourceId != -1)
619 err->put(exec, "sourceId", jsNumber(sourceId));
620
621 if(!sourceURL.isNull())
622 err->put(exec, "sourceURL", jsString(sourceURL));
623
624 return err;
625}
626
627JSObject *Error::create(ExecState *exec, ErrorType type, const char *message)
628{
629 return create(exec, type, message, -1, -1, NULL);
630}
631
632JSObject *throwError(ExecState *exec, ErrorType type)
633{
634 JSObject *error = Error::create(exec, type, UString(), -1, -1, NULL);
635 exec->setException(error);
636 return error;
637}
638
639JSObject *throwError(ExecState *exec, ErrorType type, const UString &message)
640{
641 JSObject *error = Error::create(exec, type, message, -1, -1, NULL);
642 exec->setException(error);
643 return error;
644}
645
646JSObject *throwError(ExecState *exec, ErrorType type, const char *message)
647{
648 JSObject *error = Error::create(exec, type, message, -1, -1, NULL);
649 exec->setException(error);
650 return error;
651}
652
653JSObject *throwError(ExecState *exec, ErrorType type, const UString &message, int line, int sourceId, const UString &sourceURL)
654{
655 JSObject *error = Error::create(exec, type, message, line, sourceId, sourceURL);
656 exec->setException(error);
657 return error;
658}
659
660} // namespace KJS
Note: See TracBrowser for help on using the repository browser.