Changeset 35007 in webkit for trunk/JavaScriptCore/kjs/Error.cpp


Ignore:
Timestamp:
Jul 4, 2008, 10:35:09 PM (17 years ago)
Author:
[email protected]
Message:

JavaScriptCore:

2008-07-04 Sam Weinig <[email protected]>

Rubber-stamped by Dan Bernstein.

Split Error and GetterSetter out of JSObject.h.

  • API/JSCallbackObjectFunctions.h:
  • GNUmakefile.am:
  • JavaScriptCore.pri:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • JavaScriptCoreSources.bkl:
  • kjs/AllInOneFile.cpp:
  • kjs/ClassInfo.h: Copied from JavaScriptCore/kjs/JSObject.h.
  • kjs/Error.cpp: Copied from JavaScriptCore/kjs/JSObject.cpp.
  • kjs/Error.h: Copied from JavaScriptCore/kjs/JSObject.h.
  • kjs/GetterSetter.cpp:
  • kjs/GetterSetter.h: Copied from JavaScriptCore/kjs/JSObject.h.
  • kjs/JSObject.cpp:
  • kjs/JSObject.h:
  • kjs/nodes.h:

JavaScriptGlue:

2008-07-04 Sam Weinig <[email protected]>

Rubber-stamped by Dan Bernstein.

  • JSObject.h: Rename the header guard as it now conflicts with the JSObject in JavaScriptCore.

WebCore:

2008-07-04 Sam Weinig <[email protected]>

Rubber-stamped by Dan Bernstein.

Split Error and GetterSetter out of JSObject.h.

  • ForwardingHeaders/kjs/Error.h: Added.
  • bindings/js/JSCanvasRenderingContext2DCustom.cpp:
  • bindings/js/JSClipboardCustom.cpp:
  • bindings/js/JSDOMWindowBase.cpp:
  • bindings/js/JSEventTargetBase.cpp:
  • bindings/js/JSHTMLDocumentCustom.cpp:
  • bindings/js/JSXMLHttpRequestCustom.cpp:
  • bindings/scripts/CodeGeneratorJS.pm:
  • bridge/NP_jsobject.cpp:
  • bridge/jni/jni_instance.cpp:
  • bridge/jni/jni_runtime.cpp:
  • bridge/objc/objc_instance.mm:
  • bridge/objc/objc_runtime.mm:
  • bridge/objc/objc_utility.h:
  • bridge/runtime_array.cpp:
  • bridge/runtime_method.cpp:
  • bridge/runtime_object.cpp:
File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/Error.cpp

    r35003 r35007  
    1 // -*- c-basic-offset: 2 -*-
    21/*
    32 *  Copyright (C) 1999-2001 Harri Porten ([email protected])
     
    2423
    2524#include "config.h"
    26 #include "JSObject.h"
     25#include "Error.h"
    2726
    28 #include "DatePrototype.h"
     27#include "ConstructData.h"
    2928#include "ErrorConstructor.h"
    3029#include "JSGlobalObject.h"
     30#include "JSObject.h"
    3131#include "NativeErrorConstructor.h"
    32 #include "ObjectPrototype.h"
    33 #include "PropertyNameArray.h"
    34 #include "lookup.h"
    35 #include "nodes.h"
    36 #include "operations.h"
    37 #include <math.h>
    38 #include <profiler/Profiler.h>
    39 #include <wtf/Assertions.h>
    40 
    41 #define JAVASCRIPT_MARK_TRACING 0
    4232
    4333namespace KJS {
    44 
    45 // ------------------------------ JSObject ------------------------------------
    46 
    47 void JSObject::mark()
    48 {
    49   JSCell::mark();
    50 
    51 #if JAVASCRIPT_MARK_TRACING
    52   static int markStackDepth = 0;
    53   markStackDepth++;
    54   for (int i = 0; i < markStackDepth; i++)
    55     putchar('-');
    56  
    57   printf("%s (%p)\n", className().UTF8String().c_str(), this);
    58 #endif
    59  
    60   JSValue *proto = _proto;
    61   if (!proto->marked())
    62     proto->mark();
    63 
    64   _prop.mark();
    65  
    66 #if JAVASCRIPT_MARK_TRACING
    67   markStackDepth--;
    68 #endif
    69 }
    70 
    71 JSType JSObject::type() const
    72 {
    73   return ObjectType;
    74 }
    75 
    76 UString JSObject::className() const
    77 {
    78   const ClassInfo *ci = classInfo();
    79   if ( ci )
    80     return ci->className;
    81   return "Object";
    82 }
    83 
    84 bool JSObject::getOwnPropertySlot(ExecState *exec, unsigned propertyName, PropertySlot& slot)
    85 {
    86   return getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
    87 }
    88 
    89 static void throwSetterError(ExecState *exec)
    90 {
    91   throwError(exec, TypeError, "setting a property that has only a getter");
    92 }
    93 
    94 // ECMA 8.6.2.2
    95 void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
    96 {
    97   ASSERT(value);
    98   ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
    99 
    100   if (propertyName == exec->propertyNames().underscoreProto) {
    101     JSObject* proto = value->getObject();
    102 
    103     // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla.
    104     if (!proto && value != jsNull())
    105       return;
    106 
    107     while (proto) {
    108       if (proto == this) {
    109         throwError(exec, GeneralError, "cyclic __proto__ value");
    110         return;
    111       }
    112       proto = proto->prototype() ? proto->prototype()->getObject() : 0;
    113     }
    114 
    115     setPrototype(value);
    116     return;
    117   }
    118 
    119   // Check if there are any setters or getters in the prototype chain
    120   JSValue* prototype;
    121   for (JSObject* obj = this; !obj->_prop.hasGetterSetterProperties(); obj = static_cast<JSObject*>(prototype)) {
    122     prototype = obj->_proto;
    123     if (prototype == jsNull()) {
    124       _prop.put(propertyName, value, 0, true);
    125       return;
    126     }
    127   }
    128 
    129   unsigned attributes;
    130   if (_prop.get(propertyName, attributes) && attributes & ReadOnly)
    131     return;
    132 
    133   for (JSObject* obj = this; ; obj = static_cast<JSObject*>(prototype)) {
    134     if (JSValue* gs = obj->_prop.get(propertyName, attributes)) {
    135       if (attributes & IsGetterSetter) {
    136         JSObject* setterFunc = static_cast<GetterSetter*>(gs)->setter();       
    137         if (!setterFunc) {
    138           throwSetterError(exec);
    139           return;
    140         }
    141 
    142         CallData callData;
    143         CallType callType = setterFunc->getCallData(callData);
    144         ArgList args;
    145         args.append(value);
    146         call(exec, setterFunc, callType, callData, this, args);
    147         return;
    148       }
    149 
    150       // If there's an existing property on the object or one of its
    151       // prototypes it should be replaced, so break here.
    152       break;
    153     }
    154 
    155     prototype = obj->_proto;
    156     if (prototype == jsNull())
    157       break;
    158   }
    159 
    160   _prop.put(propertyName, value, 0, true);
    161 }
    162 
    163 void JSObject::put(ExecState* exec, unsigned propertyName, JSValue* value)
    164 {
    165     put(exec, Identifier::from(exec, propertyName), value);
    166 }
    167 
    168 void JSObject::putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes)
    169 {
    170     putDirect(propertyName, value, attributes);
    171 }
    172 
    173 void JSObject::putWithAttributes(ExecState* exec, unsigned propertyName, JSValue* value, unsigned attributes)
    174 {
    175     putWithAttributes(exec, Identifier::from(exec, propertyName), value, attributes);
    176 }
    177 
    178 bool JSObject::hasProperty(ExecState *exec, const Identifier &propertyName) const
    179 {
    180   PropertySlot slot;
    181   return const_cast<JSObject *>(this)->getPropertySlot(exec, propertyName, slot);
    182 }
    183 
    184 bool JSObject::hasProperty(ExecState *exec, unsigned propertyName) const
    185 {
    186   PropertySlot slot;
    187   return const_cast<JSObject *>(this)->getPropertySlot(exec, propertyName, slot);
    188 }
    189 
    190 // ECMA 8.6.2.5
    191 bool JSObject::deleteProperty(ExecState* exec, const Identifier &propertyName)
    192 {
    193   unsigned attributes;
    194   JSValue *v = _prop.get(propertyName, attributes);
    195   if (v) {
    196     if ((attributes & DontDelete))
    197       return false;
    198     _prop.remove(propertyName);
    199     if (attributes & IsGetterSetter)
    200         _prop.setHasGetterSetterProperties(_prop.containsGettersOrSetters());
    201     return true;
    202   }
    203 
    204   // Look in the static hashtable of properties
    205   const HashEntry* entry = findPropertyHashEntry(exec, propertyName);
    206   if (entry && entry->attributes & DontDelete)
    207     return false; // this builtin property can't be deleted
    208   // FIXME: Should the code here actually do some deletion?
    209   return true;
    210 }
    211 
    212 bool JSObject::hasOwnProperty(ExecState* exec, const Identifier& propertyName) const
    213 {
    214     PropertySlot slot;
    215     return const_cast<JSObject*>(this)->getOwnPropertySlot(exec, propertyName, slot);
    216 }
    217 
    218 bool JSObject::deleteProperty(ExecState *exec, unsigned propertyName)
    219 {
    220   return deleteProperty(exec, Identifier::from(exec, propertyName));
    221 }
    222 
    223 static ALWAYS_INLINE JSValue* callDefaultValueFunction(ExecState* exec, const JSObject* object, const Identifier& propertyName)
    224 {
    225     JSValue* function = object->get(exec, propertyName);
    226     CallData callData;
    227     CallType callType = function->getCallData(callData);
    228     if (callType == CallTypeNone)
    229         return exec->exception();
    230 
    231     // Prevent "toString" and "valueOf" from observing execution if an exception
    232     // is pending.
    233     if (exec->hadException())
    234         return exec->exception();
    235 
    236     JSValue* result = call(exec, function, callType, callData, const_cast<JSObject*>(object), exec->emptyList());
    237     ASSERT(result->type() != GetterSetterType);
    238     if (exec->hadException())
    239         return exec->exception();
    240     if (result->isObject())
    241         return 0;
    242     return result;
    243 }
    244 
    245 bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValue*& result)
    246 {
    247     result = defaultValue(exec, NumberType);
    248     number = result->toNumber(exec);
    249     return !result->isString();
    250 }
    251 
    252 // ECMA 8.6.2.6
    253 JSValue* JSObject::defaultValue(ExecState* exec, JSType hint) const
    254 {
    255     // Must call toString first for Date objects.
    256     if ((hint == StringType) || (hint != NumberType && _proto == exec->lexicalGlobalObject()->datePrototype())) {
    257         if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().toString))
    258             return value;
    259         if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf))
    260             return value;
    261     } else {
    262         if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf))
    263             return value;
    264         if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().toString))
    265             return value;
    266     }
    267 
    268     ASSERT(!exec->hadException());
    269 
    270     return throwError(exec, TypeError, "No default value");
    271 }
    272 
    273 const HashEntry* JSObject::findPropertyHashEntry(ExecState* exec, const Identifier& propertyName) const
    274 {
    275     for (const ClassInfo* info = classInfo(); info; info = info->parentClass) {
    276         if (const HashTable* propHashTable = info->propHashTable(exec)) {
    277             if (const HashEntry* e = propHashTable->entry(exec, propertyName))
    278                 return e;
    279         }
    280     }
    281     return 0;
    282 }
    283 
    284 void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunc)
    285 {
    286     JSValue *o = getDirect(propertyName);
    287     GetterSetter *gs;
    288    
    289     if (o && o->type() == GetterSetterType) {
    290         gs = static_cast<GetterSetter *>(o);
    291     } else {
    292         gs = new (exec) GetterSetter;
    293         putDirect(propertyName, gs, IsGetterSetter);
    294     }
    295    
    296     _prop.setHasGetterSetterProperties(true);
    297     gs->setGetter(getterFunc);
    298 }
    299 
    300 void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunc)
    301 {
    302     JSValue *o = getDirect(propertyName);
    303     GetterSetter *gs;
    304    
    305     if (o && o->type() == GetterSetterType) {
    306         gs = static_cast<GetterSetter *>(o);
    307     } else {
    308         gs = new (exec) GetterSetter;
    309         putDirect(propertyName, gs, IsGetterSetter);
    310     }
    311    
    312     _prop.setHasGetterSetterProperties(true);
    313     gs->setSetter(setterFunc);
    314 }
    315 
    316 JSValue* JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
    317 {
    318     JSObject* obj = this;
    319     while (true) {
    320         JSValue* v = obj->getDirect(propertyName);
    321         if (v) {
    322             if (v->type() != GetterSetterType)
    323                 return jsUndefined();
    324             JSObject* funcObj = static_cast<GetterSetter*>(v)->getter();
    325             if (!funcObj)
    326                 return jsUndefined();
    327             return funcObj;
    328         }
    329 
    330         if (!obj->prototype() || !obj->prototype()->isObject())
    331             return jsUndefined();
    332         obj = static_cast<JSObject*>(obj->prototype());
    333     }
    334 }
    335 
    336 JSValue* JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
    337 {
    338     JSObject* obj = this;
    339     while (true) {
    340         JSValue* v = obj->getDirect(propertyName);
    341         if (v) {
    342             if (v->type() != GetterSetterType)
    343                 return jsUndefined();
    344             JSObject* funcObj = static_cast<GetterSetter*>(v)->setter();
    345             if (!funcObj)
    346                 return jsUndefined();
    347             return funcObj;
    348         }
    349 
    350         if (!obj->prototype() || !obj->prototype()->isObject())
    351             return jsUndefined();
    352         obj = static_cast<JSObject*>(obj->prototype());
    353     }
    354 }
    355 
    356 bool JSObject::implementsHasInstance() const
    357 {
    358   return false;
    359 }
    360 
    361 bool JSObject::hasInstance(ExecState* exec, JSValue* value)
    362 {
    363     JSValue* proto = get(exec, exec->propertyNames().prototype);
    364     if (!proto->isObject()) {
    365         throwError(exec, TypeError, "instanceof called on an object with an invalid prototype property.");
    366         return false;
    367     }
    368    
    369     if (!value->isObject())
    370         return false;
    371    
    372     JSObject* o = static_cast<JSObject*>(value);
    373     while ((o = o->prototype()->getObject())) {
    374         if (o == proto)
    375             return true;
    376     }
    377     return false;
    378 }
    379 
    380 bool JSObject::propertyIsEnumerable(ExecState* exec, const Identifier& propertyName) const
    381 {
    382   unsigned attributes;
    383  
    384   if (!getPropertyAttributes(exec, propertyName, attributes))
    385     return false;
    386   else
    387     return !(attributes & DontEnum);
    388 }
    389 
    390 bool JSObject::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
    391 {
    392   if (_prop.get(propertyName, attributes))
    393     return true;
    394    
    395   // Look in the static hashtable of properties
    396   const HashEntry* e = findPropertyHashEntry(exec, propertyName);
    397   if (e) {
    398     attributes = e->attributes;
    399     return true;
    400   }
    401    
    402   return false;
    403 }
    404 
    405 void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
    406 {
    407     _prop.getEnumerablePropertyNames(propertyNames);
    408 
    409     // Add properties from the static hashtables of properties
    410     for (const ClassInfo* info = classInfo(); info; info = info->parentClass) {
    411         const HashTable* table = info->propHashTable(exec);
    412         if (!table)
    413             continue;
    414         table->initializeIfNeeded(exec);
    415         ASSERT(table->table);
    416         int hashSizeMask = table->hashSizeMask;
    417         const HashEntry* e = table->table;
    418         for (int i = 0; i <= hashSizeMask; ++i, ++e) {
    419             if (e->key && !(e->attributes & DontEnum))
    420                 propertyNames.add(e->key);
    421         }
    422     }
    423 
    424     if (_proto->isObject())
    425         static_cast<JSObject*>(_proto)->getPropertyNames(exec, propertyNames);
    426 }
    427 
    428 bool JSObject::toBoolean(ExecState*) const
    429 {
    430   return true;
    431 }
    432 
    433 double JSObject::toNumber(ExecState *exec) const
    434 {
    435   JSValue *prim = toPrimitive(exec,NumberType);
    436   if (exec->hadException()) // should be picked up soon in nodes.cpp
    437     return 0.0;
    438   return prim->toNumber(exec);
    439 }
    440 
    441 UString JSObject::toString(ExecState* exec) const
    442 {
    443     JSValue* primitive = toPrimitive(exec, StringType);
    444     if (exec->hadException())
    445         return "";
    446     return primitive->toString(exec);
    447 }
    448 
    449 JSObject *JSObject::toObject(ExecState*) const
    450 {
    451   return const_cast<JSObject*>(this);
    452 }
    453 
    454 JSObject* JSObject::toThisObject(ExecState*) const
    455 {
    456     return const_cast<JSObject*>(this);
    457 }
    458 
    459 JSGlobalObject* JSObject::toGlobalObject(ExecState*) const
    460 {
    461     return 0;
    462 }
    463 
    464 void JSObject::removeDirect(const Identifier &propertyName)
    465 {
    466     _prop.remove(propertyName);
    467 }
    468 
    469 void JSObject::putDirectFunction(InternalFunction* func, int attr)
    470 {
    471     putDirect(func->functionName(), func, attr);
    472 }
    473 
    474 void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue** location)
    475 {
    476     if (JSObject* getterFunc = static_cast<GetterSetter*>(*location)->getter())
    477         slot.setGetterSlot(getterFunc);
    478     else
    479         slot.setUndefined();
    480 }
    481 
    482 // ------------------------------ Error ----------------------------------------
    48334
    48435JSObject* Error::create(ExecState* exec, ErrorType errtype, const UString& message,
     
    571122}
    572123
    573 JSObject* constructEmptyObject(ExecState* exec)
    574 {
    575     return new (exec) JSObject(exec->lexicalGlobalObject()->objectPrototype());
    576 }
    577 
    578124} // namespace KJS
Note: See TracChangeset for help on using the changeset viewer.