Ignore:
Timestamp:
Jan 17, 2008, 11:27:33 AM (17 years ago)
Author:
[email protected]
Message:

Reviewed by Darin.

Fix for http://bugs.webkit.org/show_bug.cgi?id=16901
Convert remaining JS function objects to use the new PrototypeFunction class

  • Moves Boolean, Function, RegExp, Number, Object and Global functions to their own static function implementations so that they can be used with the PrototypeFunction class. SunSpider says this is 1.003x as fast.
  • kjs/JSGlobalObject.cpp: (KJS::JSGlobalObject::reset):
  • kjs/array_object.h:
  • kjs/bool_object.cpp: (KJS::BooleanInstance::BooleanInstance): (KJS::BooleanPrototype::BooleanPrototype): (KJS::booleanProtoFuncToString): (KJS::booleanProtoFuncValueOf): (KJS::BooleanObjectImp::BooleanObjectImp): (KJS::BooleanObjectImp::implementsConstruct): (KJS::BooleanObjectImp::construct): (KJS::BooleanObjectImp::callAsFunction):
  • kjs/bool_object.h: (KJS::BooleanInstance::classInfo):
  • kjs/error_object.cpp: (KJS::ErrorPrototype::ErrorPrototype): (KJS::errorProtoFuncToString):
  • kjs/error_object.h:
  • kjs/function.cpp: (KJS::globalFuncEval): (KJS::globalFuncParseInt): (KJS::globalFuncParseFloat): (KJS::globalFuncIsNaN): (KJS::globalFuncIsFinite): (KJS::globalFuncDecodeURI): (KJS::globalFuncDecodeURIComponent): (KJS::globalFuncEncodeURI): (KJS::globalFuncEncodeURIComponent): (KJS::globalFuncEscape): (KJS::globalFuncUnEscape): (KJS::globalFuncKJSPrint): (KJS::PrototypeFunction::PrototypeFunction):
  • kjs/function.h:
  • kjs/function_object.cpp: (KJS::FunctionPrototype::FunctionPrototype): (KJS::functionProtoFuncToString): (KJS::functionProtoFuncApply): (KJS::functionProtoFuncCall):
  • kjs/function_object.h:
  • kjs/number_object.cpp: (KJS::NumberPrototype::NumberPrototype): (KJS::numberProtoFuncToString): (KJS::numberProtoFuncToLocaleString): (KJS::numberProtoFuncValueOf): (KJS::numberProtoFuncToFixed): (KJS::numberProtoFuncToExponential): (KJS::numberProtoFuncToPrecision):
  • kjs/number_object.h: (KJS::NumberInstance::classInfo): (KJS::NumberObjectImp::classInfo): (KJS::NumberObjectImp::):
  • kjs/object_object.cpp: (KJS::ObjectPrototype::ObjectPrototype): (KJS::objectProtoFuncValueOf): (KJS::objectProtoFuncHasOwnProperty): (KJS::objectProtoFuncIsPrototypeOf): (KJS::objectProtoFuncDefineGetter): (KJS::objectProtoFuncDefineSetter): (KJS::objectProtoFuncLookupGetter): (KJS::objectProtoFuncLookupSetter): (KJS::objectProtoFuncPropertyIsEnumerable): (KJS::objectProtoFuncToLocaleString): (KJS::objectProtoFuncToString):
  • kjs/object_object.h:
  • kjs/regexp_object.cpp: (KJS::RegExpPrototype::RegExpPrototype): (KJS::regExpProtoFuncTest): (KJS::regExpProtoFuncExec): (KJS::regExpProtoFuncCompile): (KJS::regExpProtoFuncToString):
  • kjs/regexp_object.h:
File:
1 edited

Legend:

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

    r28884 r29588  
    1 // -*- c-basic-offset: 2 -*-
    21/*
    3  *  This file is part of the KDE libraries
    42 *  Copyright (C) 1999-2000 Harri Porten ([email protected])
     3 *  Copyright (C) 2008 Apple Inc. All rights reserved.
    54 *
    65 *  This library is free software; you can redistribute it and/or
     
    2827#include <stdio.h>
    2928
    30 using namespace KJS;
     29namespace KJS {
    3130
    3231// ------------------------------ ObjectPrototype --------------------------------
    3332
    34 ObjectPrototype::ObjectPrototype(ExecState* exec, FunctionPrototype* funcProto)
    35   : JSObject() // [[Prototype]] is null
     33static JSValue* objectProtoFuncValueOf(ExecState*, JSObject*, const List&);
     34static JSValue* objectProtoFuncHasOwnProperty(ExecState*, JSObject*, const List&);
     35static JSValue* objectProtoFuncIsPrototypeOf(ExecState*, JSObject*, const List&);
     36static JSValue* objectProtoFuncDefineGetter(ExecState*, JSObject*, const List&);
     37static JSValue* objectProtoFuncDefineSetter(ExecState*, JSObject*, const List&);
     38static JSValue* objectProtoFuncLookupGetter(ExecState*, JSObject*, const List&);
     39static JSValue* objectProtoFuncLookupSetter(ExecState*, JSObject*, const List&);
     40static JSValue* objectProtoFuncPropertyIsEnumerable(ExecState*, JSObject*, const List&);
     41static JSValue* objectProtoFuncToLocaleString(ExecState*, JSObject*, const List&);
     42static JSValue* objectProtoFuncToString(ExecState*, JSObject*, const List&);
     43
     44ObjectPrototype::ObjectPrototype(ExecState* exec, FunctionPrototype* functionPrototype)
     45    : JSObject() // [[Prototype]] is null
    3646{
    3747    static const Identifier* hasOwnPropertyPropertyName = new Identifier("hasOwnProperty");
     
    4353    static const Identifier* lookupSetterPropertyName = new Identifier("__lookupSetter__");
    4454
    45     putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::ToString, 0, exec->propertyNames().toString), DontEnum);
    46     putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::ToLocaleString, 0, exec->propertyNames().toLocaleString), DontEnum);
    47     putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::ValueOf, 0, exec->propertyNames().valueOf), DontEnum);
    48     putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::HasOwnProperty, 1, *hasOwnPropertyPropertyName), DontEnum);
    49     putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::PropertyIsEnumerable, 1, *propertyIsEnumerablePropertyName), DontEnum);
    50     putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::IsPrototypeOf, 1, *isPrototypeOfPropertyName), DontEnum);
     55    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
     56    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum);
     57    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum);
     58    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, *hasOwnPropertyPropertyName, objectProtoFuncHasOwnProperty), DontEnum);
     59    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, *propertyIsEnumerablePropertyName, objectProtoFuncPropertyIsEnumerable), DontEnum);
     60    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, *isPrototypeOfPropertyName, objectProtoFuncIsPrototypeOf), DontEnum);
    5161
    5262    // Mozilla extensions
    53     putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::DefineGetter, 2, *defineGetterPropertyName), DontEnum);
    54     putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::DefineSetter, 2, *defineSetterPropertyName), DontEnum);
    55     putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::LookupGetter, 1, *lookupGetterPropertyName), DontEnum);
    56     putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::LookupSetter, 1, *lookupSetterPropertyName), DontEnum);
    57 }
    58 
    59 
    60 // ------------------------------ ObjectProtoFunc --------------------------------
    61 
    62 ObjectProtoFunc::ObjectProtoFunc(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name)
    63   : InternalFunctionImp(funcProto, name)
    64   , id(i)
    65 {
    66   putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum);
    67 }
    68 
     63    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 2, *defineGetterPropertyName, objectProtoFuncDefineGetter), DontEnum);
     64    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 2, *defineSetterPropertyName, objectProtoFuncDefineSetter), DontEnum);
     65    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, *lookupGetterPropertyName, objectProtoFuncLookupGetter), DontEnum);
     66    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, *lookupSetterPropertyName, objectProtoFuncLookupSetter), DontEnum);
     67}
     68
     69
     70// ------------------------------ Functions --------------------------------
    6971
    7072// ECMA 15.2.4.2, 15.2.4.4, 15.2.4.5, 15.2.4.7
    7173
    72 JSValue *ObjectProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
    73 {
    74     switch (id) {
    75         case ValueOf:
    76             return thisObj;
    77         case HasOwnProperty:
    78             return jsBoolean(thisObj->hasOwnProperty(exec, Identifier(args[0]->toString(exec))));
    79         case IsPrototypeOf: {
    80             if (!args[0]->isObject())
    81                 return jsBoolean(false);
    82          
    83             JSValue *v = static_cast<JSObject *>(args[0])->prototype();
    84 
    85             while (true) {
    86                 if (!v->isObject())
    87                     return jsBoolean(false);
    88                
    89                 if (thisObj == static_cast<JSObject *>(v))
    90 
    91                     return jsBoolean(true);
    92                
    93                 v = static_cast<JSObject *>(v)->prototype();
    94             }
     74JSValue* objectProtoFuncValueOf(ExecState*, JSObject* thisObj, const List&)
     75{
     76    return thisObj;
     77}
     78
     79JSValue* objectProtoFuncHasOwnProperty(ExecState* exec, JSObject* thisObj, const List& args)
     80{
     81    return jsBoolean(thisObj->hasOwnProperty(exec, Identifier(args[0]->toString(exec))));
     82}
     83
     84JSValue* objectProtoFuncIsPrototypeOf(ExecState*, JSObject* thisObj, const List& args)
     85{
     86    if (!args[0]->isObject())
     87        return jsBoolean(false);
     88
     89    JSValue* v = static_cast<JSObject*>(args[0])->prototype();
     90
     91    while (true) {
     92        if (!v->isObject())
     93            return jsBoolean(false);
     94        if (thisObj == static_cast<JSObject*>(v))
     95
     96            return jsBoolean(true);
     97        v = static_cast<JSObject*>(v)->prototype();
     98    }
     99}
     100
     101JSValue* objectProtoFuncDefineGetter(ExecState* exec, JSObject* thisObj, const List& args)
     102{
     103    if (!args[1]->isObject() || !static_cast<JSObject*>(args[1])->implementsCall())
     104        return throwError(exec, SyntaxError, "invalid getter usage");
     105
     106    thisObj->defineGetter(exec, Identifier(args[0]->toString(exec)), static_cast<JSObject *>(args[1]));
     107    return jsUndefined();
     108}
     109
     110JSValue* objectProtoFuncDefineSetter(ExecState* exec, JSObject* thisObj, const List& args)
     111{
     112    if (!args[1]->isObject() || !static_cast<JSObject*>(args[1])->implementsCall())
     113        return throwError(exec, SyntaxError, "invalid setter usage");
     114
     115    thisObj->defineSetter(exec, Identifier(args[0]->toString(exec)), static_cast<JSObject *>(args[1]));
     116    return jsUndefined();
     117}
     118
     119JSValue* objectProtoFuncLookupGetter(ExecState* exec, JSObject* thisObj, const List& args)
     120{
     121    Identifier propertyName = Identifier(args[0]->toString(exec));
     122    JSObject* obj = thisObj;
     123    while (true) {
     124        JSValue* v = obj->getDirect(propertyName);
     125        if (v) {
     126            if (v->type() != GetterSetterType)
     127                return jsUndefined();
     128            JSObject* funcObj = static_cast<GetterSetterImp*>(v)->getGetter();
     129            if (!funcObj)
     130                return jsUndefined();
     131            return funcObj;
    95132        }
    96         case DefineGetter:
    97         case DefineSetter: {
    98             if (!args[1]->isObject() ||
    99                 !static_cast<JSObject *>(args[1])->implementsCall()) {
    100                 if (id == DefineGetter)
    101                     return throwError(exec, SyntaxError, "invalid getter usage");
    102                 else
    103                     return throwError(exec, SyntaxError, "invalid setter usage");
    104             }
    105 
    106             if (id == DefineGetter)
    107                 thisObj->defineGetter(exec, Identifier(args[0]->toString(exec)), static_cast<JSObject *>(args[1]));
    108             else
    109                 thisObj->defineSetter(exec, Identifier(args[0]->toString(exec)), static_cast<JSObject *>(args[1]));
     133
     134        if (!obj->prototype() || !obj->prototype()->isObject())
    110135            return jsUndefined();
     136        obj = static_cast<JSObject*>(obj->prototype());
     137    }
     138}
     139
     140JSValue* objectProtoFuncLookupSetter(ExecState* exec, JSObject* thisObj, const List& args)
     141{
     142    Identifier propertyName = Identifier(args[0]->toString(exec));
     143    JSObject* obj = thisObj;
     144    while (true) {
     145        JSValue* v = obj->getDirect(propertyName);
     146        if (v) {
     147            if (v->type() != GetterSetterType)
     148                return jsUndefined();
     149            JSObject* funcObj = static_cast<GetterSetterImp*>(v)->getSetter();
     150            if (!funcObj)
     151                return jsUndefined();
     152            return funcObj;
    111153        }
    112         case LookupGetter:
    113         case LookupSetter: {
    114             Identifier propertyName = Identifier(args[0]->toString(exec));
    115            
    116             JSObject *obj = thisObj;
    117             while (true) {
    118                 JSValue *v = obj->getDirect(propertyName);
    119                
    120                 if (v) {
    121                     if (v->type() != GetterSetterType)
    122                         return jsUndefined();
    123 
    124                     JSObject *funcObj;
    125                        
    126                     if (id == LookupGetter)
    127                         funcObj = static_cast<GetterSetterImp *>(v)->getGetter();
    128                     else
    129                         funcObj = static_cast<GetterSetterImp *>(v)->getSetter();
    130                
    131                     if (!funcObj)
    132                         return jsUndefined();
    133                     else
    134                         return funcObj;
    135                 }
    136                
    137                 if (!obj->prototype() || !obj->prototype()->isObject())
    138                     return jsUndefined();
    139                
    140                 obj = static_cast<JSObject *>(obj->prototype());
    141             }
    142         }
    143         case PropertyIsEnumerable:
    144             return jsBoolean(thisObj->propertyIsEnumerable(exec, Identifier(args[0]->toString(exec))));
    145         case ToLocaleString:
    146             return jsString(thisObj->toString(exec));
    147         case ToString:
    148         default:
    149             return jsString("[object " + thisObj->className() + "]");
     154
     155        if (!obj->prototype() || !obj->prototype()->isObject())
     156            return jsUndefined();
     157        obj = static_cast<JSObject*>(obj->prototype());
    150158    }
     159}
     160
     161JSValue* objectProtoFuncPropertyIsEnumerable(ExecState* exec, JSObject* thisObj, const List& args)
     162{
     163    return jsBoolean(thisObj->propertyIsEnumerable(exec, Identifier(args[0]->toString(exec))));
     164}
     165
     166JSValue* objectProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const List&)
     167{
     168    return jsString(thisObj->toString(exec));
     169}
     170
     171JSValue* objectProtoFuncToString(ExecState*, JSObject* thisObj, const List&)
     172{
     173    return jsString("[object " + thisObj->className() + "]");
    151174}
    152175
     
    193216}
    194217
     218} // namespace KJS
Note: See TracChangeset for help on using the changeset viewer.