WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
patch
moreFunctions.diff (text/plain), 76.76 KB, created by
Sam Weinig
on 2008-01-16 22:33:26 PST
(
hide
)
Description:
patch
Filename:
MIME Type:
Creator:
Sam Weinig
Created:
2008-01-16 22:33:26 PST
Size:
76.76 KB
patch
obsolete
>Index: ChangeLog >=================================================================== >--- ChangeLog (revision 29552) >+++ ChangeLog (working copy) >@@ -1,3 +1,86 @@ >+2008-01-16 Sam Weinig <sam@webkit.org> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ 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: >+ > 2008-01-16 Cameron Zwarich <cwzwarich@uwaterloo.ca> > > Reviewed by Maciej & Darin. >Index: kjs/JSGlobalObject.cpp >=================================================================== >--- kjs/JSGlobalObject.cpp (revision 29541) >+++ kjs/JSGlobalObject.cpp (working copy) >@@ -231,7 +231,7 @@ void JSGlobalObject::reset(JSValue* prot > d()->booleanPrototype = new BooleanPrototype(exec, d()->objectPrototype, d()->functionPrototype); > d()->numberPrototype = new NumberPrototype(exec, d()->objectPrototype, d()->functionPrototype); > d()->datePrototype = new DatePrototype(exec, d()->objectPrototype); >- d()->regExpPrototype = new RegExpPrototype(exec, d()->objectPrototype, d()->functionPrototype);; >+ d()->regExpPrototype = new RegExpPrototype(exec, d()->objectPrototype, d()->functionPrototype); > d()->errorPrototype = new ErrorPrototype(exec, d()->objectPrototype, d()->functionPrototype); > > d()->evalErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "EvalError", "EvalError"); >@@ -311,19 +311,19 @@ void JSGlobalObject::reset(JSValue* prot > > // Set global functions. > >- putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::Eval, 1, "eval"), DontEnum); >- putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::ParseInt, 2, "parseInt"), DontEnum); >- putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::ParseFloat, 1, "parseFloat"), DontEnum); >- putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::IsNaN, 1, "isNaN"), DontEnum); >- putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::IsFinite, 1, "isFinite"), DontEnum); >- putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::Escape, 1, "escape"), DontEnum); >- putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::UnEscape, 1, "unescape"), DontEnum); >- putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::DecodeURI, 1, "decodeURI"), DontEnum); >- putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::DecodeURIComponent, 1, "decodeURIComponent"), DontEnum); >- putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::EncodeURI, 1, "encodeURI"), DontEnum); >- putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::EncodeURIComponent, 1, "encodeURIComponent"), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "eval", globalFuncEval), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 2, "parseInt", globalFuncParseInt), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "parseFloat", globalFuncParseFloat), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "isNaN", globalFuncIsNaN), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "isFinite", globalFuncIsFinite), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "escape", globalFuncEscape), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "unescape", globalFuncUnEscape), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "decodeURI", globalFuncDecodeURI), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "decodeURIComponent", globalFuncDecodeURIComponent), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "encodeURI", globalFuncEncodeURI), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "encodeURIComponent", globalFuncEncodeURIComponent), DontEnum); > #ifndef NDEBUG >- putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::KJSPrint, 1, "kjsprint"), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "kjsprint", globalFuncKJSPrint), DontEnum); > #endif > > // Set prototype, and also insert the object prototype at the end of the chain. >Index: kjs/array_object.h >=================================================================== >--- kjs/array_object.h (revision 29541) >+++ kjs/array_object.h (working copy) >@@ -1,8 +1,6 @@ >-// -*- c-basic-offset: 2 -*- > /* >- * This file is part of the KDE libraries > * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) >- * Copyright (C) 2007 Apple Inc. All rights reserved. >+ * Copyright (C) 2007 Apple Inc. All rights reserved. > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Lesser General Public >Index: kjs/bool_object.cpp >=================================================================== >--- kjs/bool_object.cpp (revision 29541) >+++ kjs/bool_object.cpp (working copy) >@@ -1,8 +1,6 @@ >-// -*- c-basic-offset: 2 -*- > /* >- * This file is part of the KDE libraries > * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) >- * Copyright (C) 2003 Apple Computer, Inc. >+ * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Lesser General Public >@@ -28,14 +26,14 @@ > #include "operations.h" > #include <wtf/Assertions.h> > >-using namespace KJS; >+namespace KJS { > > // ------------------------------ BooleanInstance --------------------------- > > const ClassInfo BooleanInstance::info = {"Boolean", 0, 0}; > >-BooleanInstance::BooleanInstance(JSObject *proto) >- : JSWrapperObject(proto) >+BooleanInstance::BooleanInstance(JSObject* proto) >+ : JSWrapperObject(proto) > { > } > >@@ -43,82 +41,81 @@ BooleanInstance::BooleanInstance(JSObjec > > // ECMA 15.6.4 > >-BooleanPrototype::BooleanPrototype(ExecState* exec, ObjectPrototype* objectProto, FunctionPrototype* funcProto) >- : BooleanInstance(objectProto) >+BooleanPrototype::BooleanPrototype(ExecState* exec, ObjectPrototype* objectPrototype, FunctionPrototype* functionPrototype) >+ : BooleanInstance(objectPrototype) > { >- putDirectFunction(new BooleanProtoFunc(exec, funcProto, BooleanProtoFunc::ToString, 0, exec->propertyNames().toString), DontEnum); >- putDirectFunction(new BooleanProtoFunc(exec, funcProto, BooleanProtoFunc::ValueOf, 0, exec->propertyNames().valueOf), DontEnum); >- setInternalValue(jsBoolean(false)); >+ setInternalValue(jsBoolean(false)); >+ >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, booleanProtoFuncToString), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, booleanProtoFuncValueOf), DontEnum); > } > > >-// ------------------------------ BooleanProtoFunc -------------------------- >+// ------------------------------ Functions -------------------------- >+ >+// ECMA 15.6.4.2 + 15.6.4.3 > >-BooleanProtoFunc::BooleanProtoFunc(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name) >- : InternalFunctionImp(funcProto, name) >- , id(i) >+JSValue* booleanProtoFuncToString(ExecState* exec, JSObject* thisObj, const List&) > { >- putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum); >-} >+ if (!thisObj->inherits(&BooleanInstance::info)) >+ return throwError(exec, TypeError); > >+ JSValue* v = static_cast<BooleanInstance*>(thisObj)->internalValue(); >+ ASSERT(v); > >-// ECMA 15.6.4.2 + 15.6.4.3 >-JSValue *BooleanProtoFunc::callAsFunction(ExecState* exec, JSObject *thisObj, const List &/*args*/) >+ return jsString(v->toString(exec)); >+} >+JSValue* booleanProtoFuncValueOf(ExecState* exec, JSObject* thisObj, const List&) > { >- // no generic function. "this" has to be a Boolean object >- if (!thisObj->inherits(&BooleanInstance::info)) >- return throwError(exec, TypeError); >- >- // execute "toString()" or "valueOf()", respectively >+ if (!thisObj->inherits(&BooleanInstance::info)) >+ return throwError(exec, TypeError); > >- JSValue *v = static_cast<BooleanInstance*>(thisObj)->internalValue(); >- ASSERT(v); >+ JSValue* v = static_cast<BooleanInstance*>(thisObj)->internalValue(); >+ ASSERT(v); > >- if (id == ToString) >- return jsString(v->toString(exec)); >- return jsBoolean(v->toBoolean(exec)); /* TODO: optimize for bool case */ >+ // TODO: optimize for bool case >+ return jsBoolean(v->toBoolean(exec)); > } > > // ------------------------------ BooleanObjectImp ----------------------------- > > >-BooleanObjectImp::BooleanObjectImp(ExecState* exec, FunctionPrototype* funcProto, BooleanPrototype* booleanProto) >- : InternalFunctionImp(funcProto) >+BooleanObjectImp::BooleanObjectImp(ExecState* exec, FunctionPrototype* functionPrototype, BooleanPrototype* booleanPrototype) >+ : InternalFunctionImp(functionPrototype) > { >- putDirect(exec->propertyNames().prototype, booleanProto, DontEnum|DontDelete|ReadOnly); >+ putDirect(exec->propertyNames().prototype, booleanPrototype, DontEnum | DontDelete | ReadOnly); > >- // no. of arguments for constructor >- putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum); >+ // no. of arguments for constructor >+ putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum); > } > > > bool BooleanObjectImp::implementsConstruct() const > { >- return true; >+ return true; > } > > // ECMA 15.6.2 >-JSObject *BooleanObjectImp::construct(ExecState *exec, const List &args) >+JSObject* BooleanObjectImp::construct(ExecState* exec, const List& args) > { >- BooleanInstance *obj(new BooleanInstance(exec->lexicalGlobalObject()->booleanPrototype())); >- >- bool b; >- if (args.size() > 0) >- b = args[0]->toBoolean(exec); >- else >- b = false; >+ BooleanInstance* obj(new BooleanInstance(exec->lexicalGlobalObject()->booleanPrototype())); > >- obj->setInternalValue(jsBoolean(b)); >+ bool b; >+ if (args.size() > 0) >+ b = args[0]->toBoolean(exec); >+ else >+ b = false; > >- return obj; >+ obj->setInternalValue(jsBoolean(b)); >+ return obj; > } > > // ECMA 15.6.1 >-JSValue *BooleanObjectImp::callAsFunction(ExecState *exec, JSObject *, const List &args) >+JSValue* BooleanObjectImp::callAsFunction(ExecState* exec, JSObject*, const List& args) > { >- if (args.isEmpty()) >- return jsBoolean(false); >- else >+ if (args.isEmpty()) >+ return jsBoolean(false); > return jsBoolean(args[0]->toBoolean(exec)); /* TODO: optimize for bool case */ > } > >+} // namespace KJS >Index: kjs/bool_object.h >=================================================================== >--- kjs/bool_object.h (revision 29541) >+++ kjs/bool_object.h (working copy) >@@ -1,7 +1,6 @@ >-// -*- c-basic-offset: 2 -*- > /* >- * This file is part of the KDE libraries > * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) >+ * Copyright (C) 2008 Apple Inc. All rights reserved. > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Lesser General Public >@@ -27,61 +26,45 @@ > > namespace KJS { > >- class BooleanInstance : public JSWrapperObject { >- public: >- BooleanInstance(JSObject *proto); >- >- virtual const ClassInfo *classInfo() const { return &info; } >- static const ClassInfo info; >- }; >- >- /** >- * @internal >- * >- * The initial value of Boolean.prototype (and thus all objects created >- * with the Boolean constructor >- */ >- class BooleanPrototype : public BooleanInstance { >- public: >- BooleanPrototype(ExecState *exec, >- ObjectPrototype *objectProto, >- FunctionPrototype *funcProto); >- }; >- >- /** >- * @internal >- * >- * Class to implement all methods that are properties of the >- * Boolean.prototype object >- */ >- class BooleanProtoFunc : public InternalFunctionImp { >- public: >- BooleanProtoFunc(ExecState*, FunctionPrototype*, int i, int len, const Identifier&); >- >- virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); >- >- enum { ToString, ValueOf }; >- private: >- int id; >- }; >- >- /** >- * @internal >- * >- * The initial value of the the global variable's "Boolean" property >- */ >- class BooleanObjectImp : public InternalFunctionImp { >- friend class BooleanProtoFunc; >- public: >- BooleanObjectImp(ExecState *exec, FunctionPrototype *funcProto, >- BooleanPrototype *booleanProto); >- >- virtual bool implementsConstruct() const; >- virtual JSObject *construct(ExecState *exec, const List &args); >+ class BooleanInstance : public JSWrapperObject { >+ public: >+ BooleanInstance(JSObject* proto); >+ >+ virtual const ClassInfo* classInfo() const { return &info; } >+ static const ClassInfo info; >+ }; >+ >+ /** >+ * @internal >+ * >+ * The initial value of Boolean.prototype (and thus all objects created >+ * with the Boolean constructor >+ */ >+ class BooleanPrototype : public BooleanInstance { >+ public: >+ BooleanPrototype(ExecState*, ObjectPrototype*, FunctionPrototype*); >+ }; >+ >+ // Functions >+ JSValue* booleanProtoFuncToString(ExecState*, JSObject*, const List&); >+ JSValue* booleanProtoFuncValueOf(ExecState*, JSObject*, const List&); >+ >+ >+ /** >+ * @internal >+ * >+ * The initial value of the the global variable's "Boolean" property >+ */ >+ class BooleanObjectImp : public InternalFunctionImp { >+ public: >+ BooleanObjectImp(ExecState*, FunctionPrototype*, BooleanPrototype*); >+ >+ virtual bool implementsConstruct() const; >+ virtual JSObject* construct(ExecState*, const List&); > >- virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); >- }; >+ virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&); >+ }; > >-} // namespace >+} // namespace KJS > >-#endif >+#endif // BOOL_OBJECT_H_ >Index: kjs/error_object.cpp >=================================================================== >--- kjs/error_object.cpp (revision 29541) >+++ kjs/error_object.cpp (working copy) >@@ -41,25 +41,18 @@ ErrorInstance::ErrorInstance(JSObject* p > // ------------------------------ ErrorPrototype ---------------------------- > > // ECMA 15.9.4 >-ErrorPrototype::ErrorPrototype(ExecState* exec, ObjectPrototype* objectProto, FunctionPrototype* funcProto) >- : JSObject(objectProto) >+ErrorPrototype::ErrorPrototype(ExecState* exec, ObjectPrototype* objectPrototype, FunctionPrototype* functionPrototype) >+ : JSObject(objectPrototype) > { > // The constructor will be added later in ErrorObjectImp's constructor > > put(exec, exec->propertyNames().name, jsString("Error"), DontEnum); > put(exec, exec->propertyNames().message, jsString("Unknown error"), DontEnum); >- putDirectFunction(new ErrorProtoFuncToString(exec, funcProto), DontEnum); >-} >- >-// ------------------------------ ErrorProtoFunc ---------------------------- > >-ErrorProtoFuncToString::ErrorProtoFuncToString(ExecState* exec, FunctionPrototype* funcProto) >- : InternalFunctionImp(funcProto, exec->propertyNames().toString) >-{ >- putDirect(exec->propertyNames().length, jsNumber(0), DontDelete|ReadOnly|DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum); > } > >-JSValue* ErrorProtoFuncToString::callAsFunction(ExecState* exec, JSObject* thisObj, const List&) >+JSValue* errorProtoFuncToString(ExecState* exec, JSObject* thisObj, const List&) > { > UString s = "Error"; > >Index: kjs/error_object.h >=================================================================== >--- kjs/error_object.h (revision 29541) >+++ kjs/error_object.h (working copy) >@@ -38,12 +38,7 @@ namespace KJS { > ErrorPrototype(ExecState*, ObjectPrototype*, FunctionPrototype*); > }; > >- class ErrorProtoFuncToString : public InternalFunctionImp { >- public: >- ErrorProtoFuncToString(ExecState*, FunctionPrototype*); >- >- virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&); >- }; >+ JSValue* errorProtoFuncToString(ExecState*, JSObject*, const List&); > > class ErrorObjectImp : public InternalFunctionImp { > public: >Index: kjs/function.cpp >=================================================================== >--- kjs/function.cpp (revision 29541) >+++ kjs/function.cpp (working copy) >@@ -471,15 +471,7 @@ ActivationImp::ActivationData::Activatio > { > } > >-// ------------------------------ GlobalFunc ----------------------------------- >- >- >-GlobalFuncImp::GlobalFuncImp(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name) >- : InternalFunctionImp(funcProto, name) >- , id(i) >-{ >- putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum); >-} >+// ------------------------------ Global Functions ----------------------------------- > > static JSValue* encode(ExecState* exec, const List& args, const char* do_not_escape) > { >@@ -700,161 +692,173 @@ static double parseFloat(const UString& > return s.toDouble( true /*tolerant*/, false /* NaN for empty string */ ); > } > >-JSValue* GlobalFuncImp::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args) >+JSValue* globalFuncEval(ExecState* exec, JSObject* thisObj, const List& args) > { >- JSValue* res = jsUndefined(); >- >- static const char do_not_escape[] = >- "ABCDEFGHIJKLMNOPQRSTUVWXYZ" >- "abcdefghijklmnopqrstuvwxyz" >- "0123456789" >- "*+-./@_"; >- >- static const char do_not_escape_when_encoding_URI_component[] = >- "ABCDEFGHIJKLMNOPQRSTUVWXYZ" >- "abcdefghijklmnopqrstuvwxyz" >- "0123456789" >- "!'()*-._~"; >- static const char do_not_escape_when_encoding_URI[] = >- "ABCDEFGHIJKLMNOPQRSTUVWXYZ" >- "abcdefghijklmnopqrstuvwxyz" >- "0123456789" >- "!#$&'()*+,-./:;=?@_~"; >- static const char do_not_unescape_when_decoding_URI[] = >- "#$&+,/:;=?@"; >- >- switch (id) { >- case Eval: { // eval() >- JSValue* x = args[0]; >- if (!x->isString()) >+ JSValue* x = args[0]; >+ if (!x->isString()) > return x; >- else { >- UString s = x->toString(exec); >- >- int sourceId; >- int errLine; >- UString errMsg; >- RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(UString(), 0, s.data(), s.size(), &sourceId, &errLine, &errMsg); >- >- Debugger* dbg = exec->dynamicGlobalObject()->debugger(); >- if (dbg) { >- bool cont = dbg->sourceParsed(exec, sourceId, UString(), s, 0, errLine, errMsg); >- if (!cont) >+ >+ UString s = x->toString(exec); >+ >+ int sourceId; >+ int errLine; >+ UString errMsg; >+ RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(UString(), 0, s.data(), s.size(), &sourceId, &errLine, &errMsg); >+ >+ Debugger* dbg = exec->dynamicGlobalObject()->debugger(); >+ if (dbg) { >+ bool cont = dbg->sourceParsed(exec, sourceId, UString(), s, 0, errLine, errMsg); >+ if (!cont) > return jsUndefined(); >- } >+ } > >- // no program node means a syntax occurred >- if (!evalNode) >- return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL); >- >- bool switchGlobal = thisObj && thisObj != exec->dynamicGlobalObject() && thisObj->isGlobalObject(); >- >- // enter a new execution context >- if (!switchGlobal) >- exec->dynamicGlobalObject()->tearOffActivation(exec); >- >- JSGlobalObject* globalObject = switchGlobal ? static_cast<JSGlobalObject*>(thisObj) : exec->dynamicGlobalObject(); >- ExecState newExec(globalObject, evalNode.get(), exec); >- >- if (switchGlobal) { >- newExec.pushScope(thisObj); >- newExec.setVariableObject(static_cast<JSGlobalObject*>(thisObj)); >- } >- JSValue* value = evalNode->execute(&newExec); >- if (switchGlobal) >- newExec.popScope(); >- >- if (newExec.completionType() == Throw) { >- exec->setException(value); >- return value; >- } >- return value ? value : jsUndefined(); >- } >+ // no program node means a syntax occurred >+ if (!evalNode) >+ return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL); >+ >+ bool switchGlobal = thisObj && thisObj != exec->dynamicGlobalObject() && thisObj->isGlobalObject(); >+ >+ // enter a new execution context >+ if (!switchGlobal) >+ exec->dynamicGlobalObject()->tearOffActivation(exec); >+ >+ JSGlobalObject* globalObject = switchGlobal ? static_cast<JSGlobalObject*>(thisObj) : exec->dynamicGlobalObject(); >+ ExecState newExec(globalObject, evalNode.get(), exec); >+ >+ if (switchGlobal) { >+ newExec.pushScope(thisObj); >+ newExec.setVariableObject(static_cast<JSGlobalObject*>(thisObj)); >+ } >+ >+ JSValue* value = evalNode->execute(&newExec); >+ if (switchGlobal) >+ newExec.popScope(); >+ >+ if (newExec.completionType() == Throw) { >+ exec->setException(value); >+ return value; > } >- case ParseInt: >- res = jsNumber(parseInt(args[0]->toString(exec), args[1]->toInt32(exec))); >- break; >- case ParseFloat: >- res = jsNumber(parseFloat(args[0]->toString(exec))); >- break; >- case IsNaN: >- res = jsBoolean(isnan(args[0]->toNumber(exec))); >- break; >- case IsFinite: { >+ >+ return value ? value : jsUndefined(); >+} >+ >+JSValue* globalFuncParseInt(ExecState* exec, JSObject*, const List& args) >+{ >+ return jsNumber(parseInt(args[0]->toString(exec), args[1]->toInt32(exec))); >+} >+ >+JSValue* globalFuncParseFloat(ExecState* exec, JSObject*, const List& args) >+{ >+ return jsNumber(parseFloat(args[0]->toString(exec))); >+} >+ >+JSValue* globalFuncIsNaN(ExecState* exec, JSObject*, const List& args) >+{ >+ return jsBoolean(isnan(args[0]->toNumber(exec))); >+} >+ >+JSValue* globalFuncIsFinite(ExecState* exec, JSObject*, const List& args) >+{ > double n = args[0]->toNumber(exec); >- res = jsBoolean(!isnan(n) && !isinf(n)); >- break; >- } >- case DecodeURI: >- res = decode(exec, args, do_not_unescape_when_decoding_URI, true); >- break; >- case DecodeURIComponent: >- res = decode(exec, args, "", true); >- break; >- case EncodeURI: >- res = encode(exec, args, do_not_escape_when_encoding_URI); >- break; >- case EncodeURIComponent: >- res = encode(exec, args, do_not_escape_when_encoding_URI_component); >- break; >- case Escape: >- { >- UString r = "", s, str = args[0]->toString(exec); >- const UChar* c = str.data(); >- for (int k = 0; k < str.size(); k++, c++) { >+ return jsBoolean(!isnan(n) && !isinf(n)); >+} >+ >+JSValue* globalFuncDecodeURI(ExecState* exec, JSObject*, const List& args) >+{ >+ static const char do_not_unescape_when_decoding_URI[] = >+ "#$&+,/:;=?@"; >+ >+ return decode(exec, args, do_not_unescape_when_decoding_URI, true); >+} >+ >+JSValue* globalFuncDecodeURIComponent(ExecState* exec, JSObject*, const List& args) >+{ >+ return decode(exec, args, "", true); >+} >+ >+JSValue* globalFuncEncodeURI(ExecState* exec, JSObject*, const List& args) >+{ >+ static const char do_not_escape_when_encoding_URI[] = >+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" >+ "abcdefghijklmnopqrstuvwxyz" >+ "0123456789" >+ "!#$&'()*+,-./:;=?@_~"; >+ >+ return encode(exec, args, do_not_escape_when_encoding_URI); >+} >+ >+JSValue* globalFuncEncodeURIComponent(ExecState* exec, JSObject*, const List& args) >+{ >+ static const char do_not_escape_when_encoding_URI_component[] = >+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" >+ "abcdefghijklmnopqrstuvwxyz" >+ "0123456789" >+ "!'()*-._~"; >+ >+ return encode(exec, args, do_not_escape_when_encoding_URI_component); >+} >+ >+JSValue* globalFuncEscape(ExecState* exec, JSObject*, const List& args) >+{ >+ static const char do_not_escape[] = >+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" >+ "abcdefghijklmnopqrstuvwxyz" >+ "0123456789" >+ "*+-./@_"; >+ >+ UString r = "", s, str = args[0]->toString(exec); >+ const UChar* c = str.data(); >+ for (int k = 0; k < str.size(); k++, c++) { > int u = c->uc; > if (u > 255) { >- char tmp[7]; >- sprintf(tmp, "%%u%04X", u); >- s = UString(tmp); >- } else if (u != 0 && strchr(do_not_escape, (char)u)) { >- s = UString(c, 1); >- } else { >- char tmp[4]; >- sprintf(tmp, "%%%02X", u); >- s = UString(tmp); >+ char tmp[7]; >+ sprintf(tmp, "%%u%04X", u); >+ s = UString(tmp); >+ } else if (u != 0 && strchr(do_not_escape, (char)u)) >+ s = UString(c, 1); >+ else { >+ char tmp[4]; >+ sprintf(tmp, "%%%02X", u); >+ s = UString(tmp); > } > r += s; >- } >- res = jsString(r); >- break; > } >- case UnEscape: >- { >- UString s = "", str = args[0]->toString(exec); >- int k = 0, len = str.size(); >- while (k < len) { >+ >+ return jsString(r); >+} >+ >+JSValue* globalFuncUnEscape(ExecState* exec, JSObject*, const List& args) >+{ >+ UString s = "", str = args[0]->toString(exec); >+ int k = 0, len = str.size(); >+ while (k < len) { > const UChar* c = str.data() + k; > UChar u; >- if (*c == UChar('%') && k <= len - 6 && *(c+1) == UChar('u')) { >- if (Lexer::isHexDigit((c+2)->uc) && Lexer::isHexDigit((c+3)->uc) && >- Lexer::isHexDigit((c+4)->uc) && Lexer::isHexDigit((c+5)->uc)) { >- u = Lexer::convertUnicode((c+2)->uc, (c+3)->uc, >- (c+4)->uc, (c+5)->uc); >- c = &u; >- k += 5; >- } >- } else if (*c == UChar('%') && k <= len - 3 && >- Lexer::isHexDigit((c+1)->uc) && Lexer::isHexDigit((c+2)->uc)) { >- u = UChar(Lexer::convertHex((c+1)->uc, (c+2)->uc)); >- c = &u; >- k += 2; >+ if (*c == UChar('%') && k <= len - 6 && *(c + 1) == UChar('u')) { >+ if (Lexer::isHexDigit((c + 2)->uc) && Lexer::isHexDigit((c + 3)->uc) && Lexer::isHexDigit((c + 4)->uc) && Lexer::isHexDigit((c + 5)->uc)) { >+ u = Lexer::convertUnicode((c + 2)->uc, (c + 3)->uc, (c + 4)->uc, (c + 5)->uc); >+ c = &u; >+ k += 5; >+ } >+ } else if (*c == UChar('%') && k <= len - 3 && Lexer::isHexDigit((c + 1)->uc) && Lexer::isHexDigit((c + 2)->uc)) { >+ u = UChar(Lexer::convertHex((c+1)->uc, (c+2)->uc)); >+ c = &u; >+ k += 2; > } > k++; > s += UString(c, 1); >- } >- res = jsString(s); >- break; > } >+ >+ return jsString(s); >+} >+ > #ifndef NDEBUG >- case KJSPrint: >+JSValue* globalFuncKJSPrint(ExecState* exec, JSObject*, const List& args) >+{ > puts(args[0]->toString(exec).ascii()); >- break; >-#endif >- } >- >- return res; >+ return jsUndefined(); > } >+#endif > > // ------------------------------ PrototypeFunction ------------------------------- > >@@ -866,6 +870,14 @@ PrototypeFunction::PrototypeFunction(Exe > put(exec, exec->propertyNames().length, jsNumber(len), DontDelete | ReadOnly | DontEnum); > } > >+PrototypeFunction::PrototypeFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, JSMemberFunction function) >+ : InternalFunctionImp(functionPrototype, name) >+ , m_function(function) >+{ >+ ASSERT_ARG(function, function); >+ put(exec, exec->propertyNames().length, jsNumber(len), DontDelete | ReadOnly | DontEnum); >+} >+ > JSValue* PrototypeFunction::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args) > { > return m_function(exec, thisObj, args); >Index: kjs/function.h >=================================================================== >--- kjs/function.h (revision 29541) >+++ kjs/function.h (working copy) >@@ -56,20 +56,6 @@ namespace KJS { > Identifier m_name; > }; > >- /** >- * @internal >- * >- * The initial value of Function.prototype (and thus all objects created >- * with the Function constructor) >- */ >- class FunctionPrototype : public InternalFunctionImp { >- public: >- FunctionPrototype(ExecState *exec); >- virtual ~FunctionPrototype(); >- >- virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); >- }; >- > class FunctionImp : public InternalFunctionImp { > friend class ActivationImp; > public: >@@ -143,6 +129,7 @@ namespace KJS { > typedef KJS::JSValue* (*JSMemberFunction)(ExecState*, JSObject*, const List&); > > PrototypeFunction(ExecState*, int len, const Identifier&, JSMemberFunction); >+ PrototypeFunction(ExecState*, FunctionPrototype*, int len, const Identifier&, JSMemberFunction); > > virtual JSValue* callAsFunction(ExecState* exec, JSObject* thisObj, const List&); > >@@ -150,22 +137,26 @@ namespace KJS { > const JSMemberFunction m_function; > }; > >- class GlobalFuncImp : public InternalFunctionImp { >- public: >- GlobalFuncImp(ExecState*, FunctionPrototype*, int i, int len, const Identifier&); >- virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List& args); >- enum { Eval, ParseInt, ParseFloat, IsNaN, IsFinite, Escape, UnEscape, >- DecodeURI, DecodeURIComponent, EncodeURI, EncodeURIComponent >+ >+ // Global Functions >+ >+ JSValue* globalFuncEval(ExecState*, JSObject*, const List&); >+ JSValue* globalFuncParseInt(ExecState*, JSObject*, const List&); >+ JSValue* globalFuncParseFloat(ExecState*, JSObject*, const List&); >+ JSValue* globalFuncIsNaN(ExecState*, JSObject*, const List&); >+ JSValue* globalFuncIsFinite(ExecState*, JSObject*, const List&); >+ JSValue* globalFuncDecodeURI(ExecState*, JSObject*, const List&); >+ JSValue* globalFuncDecodeURIComponent(ExecState*, JSObject*, const List&); >+ JSValue* globalFuncEncodeURI(ExecState*, JSObject*, const List&); >+ JSValue* globalFuncEncodeURIComponent(ExecState*, JSObject*, const List&); >+ JSValue* globalFuncEscape(ExecState*, JSObject*, const List&); >+ JSValue* globalFuncUnEscape(ExecState*, JSObject*, const List&); > #ifndef NDEBUG >- , KJSPrint >+ JSValue* globalFuncKJSPrint(ExecState*, JSObject*, const List&); > #endif >-}; >- private: >- int id; >- }; > >- static const double mantissaOverflowLowerBound = 9007199254740992.0; >- double parseIntOverflow(const char* s, int length, int radix); >+ static const double mantissaOverflowLowerBound = 9007199254740992.0; >+ double parseIntOverflow(const char* s, int length, int radix); > > } // namespace > >Index: kjs/function_object.cpp >=================================================================== >--- kjs/function_object.cpp (revision 29541) >+++ kjs/function_object.cpp (working copy) >@@ -36,23 +36,20 @@ > #include <string.h> > #include <wtf/Assertions.h> > >-using namespace KJS; >+namespace KJS { > > // ------------------------------ FunctionPrototype ------------------------- > >-FunctionPrototype::FunctionPrototype(ExecState *exec) >+FunctionPrototype::FunctionPrototype(ExecState* exec) > { > static const Identifier* applyPropertyName = new Identifier("apply"); > static const Identifier* callPropertyName = new Identifier("call"); > > putDirect(exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum); >- putDirectFunction(new FunctionProtoFunc(exec, this, FunctionProtoFunc::ToString, 0, exec->propertyNames().toString), DontEnum); >- putDirectFunction(new FunctionProtoFunc(exec, this, FunctionProtoFunc::Apply, 2, *applyPropertyName), DontEnum); >- putDirectFunction(new FunctionProtoFunc(exec, this, FunctionProtoFunc::Call, 1, *callPropertyName), DontEnum); >-} > >-FunctionPrototype::~FunctionPrototype() >-{ >+ putDirectFunction(new PrototypeFunction(exec, this, 0, exec->propertyNames().toString, functionProtoFuncToString), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, this, 2, *applyPropertyName, functionProtoFuncApply), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, this, 1, *callPropertyName, functionProtoFuncCall), DontEnum); > } > > // ECMA 15.3.4 >@@ -63,89 +60,73 @@ JSValue *FunctionPrototype::callAsFuncti > > // ------------------------------ FunctionProtoFunc ------------------------- > >-FunctionProtoFunc::FunctionProtoFunc(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name) >- : InternalFunctionImp(funcProto, name) >- , id(i) >-{ >- putDirect(exec->propertyNames().length, len, DontDelete | ReadOnly | DontEnum); >-} >- >-JSValue* FunctionProtoFunc::callAsFunction(ExecState* exec, JSObject* thisObj, const List &args) >+JSValue* functionProtoFuncToString(ExecState* exec, JSObject* thisObj, const List&) > { >- JSValue* result = NULL; >- >- switch (id) { >- case ToString: > if (!thisObj || !thisObj->inherits(&InternalFunctionImp::info)) { > #ifndef NDEBUG >- fprintf(stderr,"attempted toString() call on null or non-function object\n"); >+ fprintf(stderr,"attempted toString() call on null or non-function object\n"); > #endif >- return throwError(exec, TypeError); >+ return throwError(exec, TypeError); > } >+ > if (thisObj->inherits(&FunctionImp::info)) { >- FunctionImp *fi = static_cast<FunctionImp*>(thisObj); >- return jsString("function " + fi->functionName().ustring() + "(" + >- fi->body->paramString() + ") " + fi->body->toString()); >- } else if (thisObj->inherits(&InternalFunctionImp::info) && >- !static_cast<InternalFunctionImp*>(thisObj)->functionName().isNull()) { >- result = jsString("\nfunction " + static_cast<InternalFunctionImp*>(thisObj)->functionName().ustring() + "() {\n" >- " [native code]\n}\n"); >- } else { >- result = jsString("[function]"); >+ FunctionImp* fi = static_cast<FunctionImp*>(thisObj); >+ return jsString("function " + fi->functionName().ustring() + "(" + fi->body->paramString() + ") " + fi->body->toString()); > } >- break; >- case Apply: { >- JSValue *thisArg = args[0]; >- JSValue *argArray = args[1]; >- JSObject *func = thisObj; > >- if (!func->implementsCall()) >- return throwError(exec, TypeError); >+ if (thisObj->inherits(&InternalFunctionImp::info) && !static_cast<InternalFunctionImp*>(thisObj)->functionName().isNull()) >+ return jsString("\nfunction " + static_cast<InternalFunctionImp*>(thisObj)->functionName().ustring() + "() {\n [native code]\n}\n"); > >- JSObject *applyThis; >+ return jsString("[function]"); >+} >+ >+JSValue* functionProtoFuncApply(ExecState* exec, JSObject* thisObj, const List& args) >+{ >+ if (!thisObj->implementsCall()) >+ return throwError(exec, TypeError); >+ >+ JSValue* thisArg = args[0]; >+ JSValue* argArray = args[1]; >+ >+ JSObject* applyThis; > if (thisArg->isUndefinedOrNull()) >- applyThis = exec->dynamicGlobalObject(); >+ applyThis = exec->dynamicGlobalObject(); > else >- applyThis = thisArg->toObject(exec); >+ applyThis = thisArg->toObject(exec); > > List applyArgs; > if (!argArray->isUndefinedOrNull()) { >- if (argArray->isObject() && >- (static_cast<JSObject *>(argArray)->inherits(&ArrayInstance::info) || >- static_cast<JSObject *>(argArray)->inherits(&Arguments::info))) { >- >- JSObject *argArrayObj = static_cast<JSObject *>(argArray); >- unsigned int length = argArrayObj->get(exec, exec->propertyNames().length)->toUInt32(exec); >- for (unsigned int i = 0; i < length; i++) >- applyArgs.append(argArrayObj->get(exec,i)); >- } >- else >- return throwError(exec, TypeError); >- } >- result = func->call(exec,applyThis,applyArgs); >+ if (argArray->isObject() && >+ (static_cast<JSObject*>(argArray)->inherits(&ArrayInstance::info) || >+ static_cast<JSObject*>(argArray)->inherits(&Arguments::info))) { >+ >+ JSObject* argArrayObj = static_cast<JSObject*>(argArray); >+ unsigned int length = argArrayObj->get(exec, exec->propertyNames().length)->toUInt32(exec); >+ for (unsigned int i = 0; i < length; i++) >+ applyArgs.append(argArrayObj->get(exec, i)); >+ } else >+ return throwError(exec, TypeError); > } >- break; >- case Call: { >- JSValue *thisArg = args[0]; >- JSObject *func = thisObj; > >- if (!func->implementsCall()) >- return throwError(exec, TypeError); >+ return thisObj->call(exec, applyThis, applyArgs); >+} >+ >+JSValue* functionProtoFuncCall(ExecState* exec, JSObject* thisObj, const List& args) >+{ >+ if (!thisObj->implementsCall()) >+ return throwError(exec, TypeError); >+ >+ JSValue* thisArg = args[0]; > >- JSObject *callThis; >+ JSObject* callThis; > if (thisArg->isUndefinedOrNull()) >- callThis = exec->dynamicGlobalObject(); >+ callThis = exec->dynamicGlobalObject(); > else >- callThis = thisArg->toObject(exec); >+ callThis = thisArg->toObject(exec); > > List argsTail; > args.getSlice(1, argsTail); >- result = func->call(exec, callThis, argsTail); >- } >- break; >- } >- >- return result; >+ return thisObj->call(exec, callThis, argsTail); > } > > // ------------------------------ FunctionObjectImp ---------------------------- >@@ -159,10 +140,6 @@ FunctionObjectImp::FunctionObjectImp(Exe > putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum); > } > >-FunctionObjectImp::~FunctionObjectImp() >-{ >-} >- > bool FunctionObjectImp::implementsConstruct() const > { > return true; >@@ -264,3 +241,5 @@ JSValue* FunctionObjectImp::callAsFuncti > { > return construct(exec, args); > } >+ >+} // namespace KJS >Index: kjs/function_object.h >=================================================================== >--- kjs/function_object.h (revision 29541) >+++ kjs/function_object.h (working copy) >@@ -28,39 +28,38 @@ > > namespace KJS { > >- /** >- * @internal >- * >- * Class to implement all methods that are properties of the >- * Function.prototype object >- */ >- class FunctionProtoFunc : public InternalFunctionImp { >- public: >- FunctionProtoFunc(ExecState*, FunctionPrototype*, int i, int len, const Identifier&); >- >- virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); >- >- enum { ToString, Apply, Call }; >- private: >- int id; >- }; >- >- /** >- * @internal >- * >- * The initial value of the the global variable's "Function" property >- */ >- class FunctionObjectImp : public InternalFunctionImp { >- public: >- FunctionObjectImp(ExecState*, FunctionPrototype*); >- virtual ~FunctionObjectImp(); >- >- virtual bool implementsConstruct() const; >- virtual JSObject* construct(ExecState*, const List& args); >- virtual JSObject* construct(ExecState*, const List& args, const Identifier& functionName, const UString& sourceURL, int lineNumber); >- virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List& args); >- }; >+ /** >+ * @internal >+ * >+ * The initial value of Function.prototype (and thus all objects created >+ * with the Function constructor) >+ */ >+ class FunctionPrototype : public InternalFunctionImp { >+ public: >+ FunctionPrototype(ExecState*); >+ >+ virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&); >+ }; >+ >+ JSValue* functionProtoFuncToString(ExecState*, JSObject*, const List&); >+ JSValue* functionProtoFuncApply(ExecState*, JSObject*, const List&); >+ JSValue* functionProtoFuncCall(ExecState*, JSObject*, const List&); >+ >+ /** >+ * @internal >+ * >+ * The initial value of the the global variable's "Function" property >+ */ >+ class FunctionObjectImp : public InternalFunctionImp { >+ public: >+ FunctionObjectImp(ExecState*, FunctionPrototype*); >+ >+ virtual bool implementsConstruct() const; >+ virtual JSObject* construct(ExecState*, const List&); >+ virtual JSObject* construct(ExecState*, const List&, const Identifier& functionName, const UString& sourceURL, int lineNumber); >+ virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&); >+ }; > >-} // namespace >+} // namespace KJS > > #endif // _FUNCTION_OBJECT_H_ >Index: kjs/number_object.cpp >=================================================================== >--- kjs/number_object.cpp (revision 29541) >+++ kjs/number_object.cpp (working copy) >@@ -41,34 +41,29 @@ NumberInstance::NumberInstance(JSObject* > : JSWrapperObject(proto) > { > } >+ > // ------------------------------ NumberPrototype --------------------------- > > // ECMA 15.7.4 > >-NumberPrototype::NumberPrototype(ExecState* exec, ObjectPrototype* objProto, FunctionPrototype* funcProto) >- : NumberInstance(objProto) >+NumberPrototype::NumberPrototype(ExecState* exec, ObjectPrototype* objectPrototype, FunctionPrototype* functionPrototype) >+ : NumberInstance(objectPrototype) > { > setInternalValue(jsNumber(0)); > > // The constructor will be added later, after NumberObjectImp has been constructed > >- putDirectFunction(new NumberProtoFunc(exec, funcProto, NumberProtoFunc::ToString, 1, exec->propertyNames().toString), DontEnum); >- putDirectFunction(new NumberProtoFunc(exec, funcProto, NumberProtoFunc::ToLocaleString, 0, exec->propertyNames().toLocaleString), DontEnum); >- putDirectFunction(new NumberProtoFunc(exec, funcProto, NumberProtoFunc::ValueOf, 0, exec->propertyNames().valueOf), DontEnum); >- putDirectFunction(new NumberProtoFunc(exec, funcProto, NumberProtoFunc::ToFixed, 1, exec->propertyNames().toFixed), DontEnum); >- putDirectFunction(new NumberProtoFunc(exec, funcProto, NumberProtoFunc::ToExponential, 1, exec->propertyNames().toExponential), DontEnum); >- putDirectFunction(new NumberProtoFunc(exec, funcProto, NumberProtoFunc::ToPrecision, 1, exec->propertyNames().toPrecision), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toString, numberProtoFuncToString), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toLocaleString, numberProtoFuncToLocaleString), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, numberProtoFuncValueOf), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toFixed, numberProtoFuncToFixed), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toExponential, numberProtoFuncToExponential), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toPrecision, numberProtoFuncToPrecision), DontEnum); > } > >+// ------------------------------ Functions --------------------------- > >-// ------------------------------ NumberProtoFunc --------------------------- >- >-NumberProtoFunc::NumberProtoFunc(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name) >- : InternalFunctionImp(funcProto, name) >- , id(i) >-{ >- putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum); >-} >+// ECMA 15.7.4.2 - 15.7.4.7 > > static UString integer_part_noexp(double d) > { >@@ -140,8 +135,14 @@ static double intPow10(int e) > return static_cast<double>(result); > } > >-static JSValue* numberToString(ExecState* exec, JSValue* v, const List& args) >+ >+JSValue* numberProtoFuncToString(ExecState* exec, JSObject* thisObj, const List& args) > { >+ if (!thisObj->inherits(&NumberInstance::info)) >+ return throwError(exec, TypeError); >+ >+ JSValue* v = static_cast<NumberInstance*>(thisObj)->internalValue(); >+ > double radixAsDouble = args[0]->toInteger(exec); // nan -> 0 > if (radixAsDouble == 10 || args[0]->isUndefined()) > return jsString(v->toString(exec)); >@@ -200,8 +201,30 @@ static JSValue* numberToString(ExecState > return jsString(startOfResultString); > } > >-static JSValue* numberToFixed(ExecState* exec, JSValue* v, const List& args) >+JSValue* numberProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const List&) > { >+ if (!thisObj->inherits(&NumberInstance::info)) >+ return throwError(exec, TypeError); >+ >+ // TODO >+ return jsString(static_cast<NumberInstance*>(thisObj)->internalValue()->toString(exec)); >+} >+ >+JSValue* numberProtoFuncValueOf(ExecState* exec, JSObject* thisObj, const List&) >+{ >+ if (!thisObj->inherits(&NumberInstance::info)) >+ return throwError(exec, TypeError); >+ >+ return static_cast<NumberInstance*>(thisObj)->internalValue()->toJSNumber(exec); >+} >+ >+JSValue* numberProtoFuncToFixed(ExecState* exec, JSObject* thisObj, const List& args) >+{ >+ if (!thisObj->inherits(&NumberInstance::info)) >+ return throwError(exec, TypeError); >+ >+ JSValue* v = static_cast<NumberInstance*>(thisObj)->internalValue(); >+ > JSValue* fractionDigits = args[0]; > double df = fractionDigits->toInteger(exec); > if (!(df >= 0 && df <= 20)) >@@ -281,8 +304,13 @@ void exponentialPartToString(char* buf, > buf[i++] = static_cast<char>('0' + exponential % 10); > } > >-static JSValue* numberToExponential(ExecState* exec, JSValue* v, const List& args) >+JSValue* numberProtoFuncToExponential(ExecState* exec, JSObject* thisObj, const List& args) > { >+ if (!thisObj->inherits(&NumberInstance::info)) >+ return throwError(exec, TypeError); >+ >+ JSValue* v = static_cast<NumberInstance*>(thisObj)->internalValue(); >+ > double x = v->toNumber(exec); > > if (isnan(x) || isinf(x)) >@@ -346,9 +374,14 @@ static JSValue* numberToExponential(Exec > > return jsString(buf); > } >- >-static JSValue* numberToPrecision(ExecState* exec, JSValue* v, const List& args) >+ >+JSValue* numberProtoFuncToPrecision(ExecState* exec, JSObject* thisObj, const List& args) > { >+ if (!thisObj->inherits(&NumberInstance::info)) >+ return throwError(exec, TypeError); >+ >+ JSValue* v = static_cast<NumberInstance*>(thisObj)->internalValue(); >+ > double doublePrecision = args[0]->toIntegerPreserveNaN(exec); > double x = v->toNumber(exec); > if (args[0]->isUndefined() || isnan(x) || isinf(x)) >@@ -409,31 +442,6 @@ static JSValue* numberToPrecision(ExecSt > return jsString(s + "0." + char_sequence('0', -(e + 1)) + m); > } > >-// ECMA 15.7.4.2 - 15.7.4.7 >-JSValue* NumberProtoFunc::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args) >-{ >- // no generic function. "this" has to be a Number object >- if (!thisObj->inherits(&NumberInstance::info)) >- return throwError(exec, TypeError); >- >- JSValue* v = static_cast<NumberInstance*>(thisObj)->internalValue(); >- switch (id) { >- case ToString: >- return numberToString(exec, v, args); >- case ToLocaleString: /* TODO */ >- return jsString(v->toString(exec)); >- case ValueOf: >- return v->toJSNumber(exec); >- case ToFixed: >- return numberToFixed(exec, v, args); >- case ToExponential: >- return numberToExponential(exec, v, args); >- case ToPrecision: >- return numberToPrecision(exec, v, args); >- } >- return 0; >-} >- > // ------------------------------ NumberObjectImp ------------------------------ > > const ClassInfo NumberObjectImp::info = { "Function", &InternalFunctionImp::info, &numberTable }; >Index: kjs/number_object.h >=================================================================== >--- kjs/number_object.h (revision 29541) >+++ kjs/number_object.h (working copy) >@@ -27,70 +27,58 @@ > > namespace KJS { > >- class NumberInstance : public JSWrapperObject { >- public: >- NumberInstance(JSObject *proto); >- >- virtual const ClassInfo *classInfo() const { return &info; } >- static const ClassInfo info; >- }; >- >- /** >- * @internal >- * >- * The initial value of Number.prototype (and thus all objects created >- * with the Number constructor >- */ >- class NumberPrototype : public NumberInstance { >- public: >- NumberPrototype(ExecState *exec, >- ObjectPrototype *objProto, >- FunctionPrototype *funcProto); >- }; >- >- /** >- * @internal >- * >- * Class to implement all methods that are properties of the >- * Number.prototype object >- */ >- class NumberProtoFunc : public InternalFunctionImp { >- public: >- NumberProtoFunc(ExecState*, FunctionPrototype*, int i, int len, const Identifier&); >- >- virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); >- >- enum { ToString, ToLocaleString, ValueOf, ToFixed, ToExponential, ToPrecision }; >- private: >- int id; >- }; >- >- /** >- * @internal >- * >- * The initial value of the the global variable's "Number" property >- */ >- class NumberObjectImp : public InternalFunctionImp { >- public: >- NumberObjectImp(ExecState *exec, >- FunctionPrototype *funcProto, >- NumberPrototype *numberProto); >- >- virtual bool implementsConstruct() const; >- virtual JSObject *construct(ExecState *exec, const List &args); >- >- virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); >- >- bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); >- JSValue *getValueProperty(ExecState *exec, int token) const; >- >- virtual const ClassInfo *classInfo() const { return &info; } >- static const ClassInfo info; >- enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue }; >+ class NumberInstance : public JSWrapperObject { >+ public: >+ NumberInstance(JSObject* prototype); >+ >+ virtual const ClassInfo* classInfo() const { return &info; } >+ static const ClassInfo info; >+ }; >+ >+ /** >+ * @internal >+ * >+ * The initial value of Number.prototype (and thus all objects created >+ * with the Number constructor >+ */ >+ class NumberPrototype : public NumberInstance { >+ public: >+ NumberPrototype(ExecState*, ObjectPrototype*, FunctionPrototype*); >+ }; >+ >+ // Functions >+ JSValue* numberProtoFuncToString(ExecState*, JSObject*, const List&); >+ JSValue* numberProtoFuncToLocaleString(ExecState*, JSObject*, const List&); >+ JSValue* numberProtoFuncValueOf(ExecState*, JSObject*, const List&); >+ JSValue* numberProtoFuncToFixed(ExecState*, JSObject*, const List&); >+ JSValue* numberProtoFuncToExponential(ExecState*, JSObject*, const List&); >+ JSValue* numberProtoFuncToPrecision(ExecState*, JSObject*, const List&); >+ >+ /** >+ * @internal >+ * >+ * The initial value of the the global variable's "Number" property >+ */ >+ class NumberObjectImp : public InternalFunctionImp { >+ public: >+ NumberObjectImp(ExecState*, FunctionPrototype*, NumberPrototype*); >+ >+ virtual bool implementsConstruct() const; >+ virtual JSObject* construct(ExecState*, const List&); >+ >+ virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&); >+ >+ bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); >+ JSValue* getValueProperty(ExecState*, int token) const; >+ >+ virtual const ClassInfo* classInfo() const { return &info; } >+ static const ClassInfo info; > >- JSObject *construct(const List &); >- }; >+ enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue }; > >-} // namespace >+ JSObject* construct(const List&); >+ }; > >-#endif >+} // namespace KJS >+ >+#endif // NUMBER_OBJECT_H_ >Index: kjs/object_object.cpp >=================================================================== >--- kjs/object_object.cpp (revision 29541) >+++ kjs/object_object.cpp (working copy) >@@ -1,7 +1,6 @@ >-// -*- c-basic-offset: 2 -*- > /* >- * This file is part of the KDE libraries > * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) >+ * Copyright (C) 2008 Apple Inc. All rights reserved. > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Lesser General Public >@@ -27,12 +26,12 @@ > #include "function_object.h" > #include <stdio.h> > >-using namespace KJS; >+namespace KJS { > > // ------------------------------ ObjectPrototype -------------------------------- > >-ObjectPrototype::ObjectPrototype(ExecState* exec, FunctionPrototype* funcProto) >- : JSObject() // [[Prototype]] is null >+ObjectPrototype::ObjectPrototype(ExecState* exec, FunctionPrototype* functionPrototype) >+ : JSObject() // [[Prototype]] is null > { > static const Identifier* hasOwnPropertyPropertyName = new Identifier("hasOwnProperty"); > static const Identifier* propertyIsEnumerablePropertyName = new Identifier("propertyIsEnumerable"); >@@ -42,113 +41,126 @@ ObjectPrototype::ObjectPrototype(ExecSta > static const Identifier* lookupGetterPropertyName = new Identifier("__lookupGetter__"); > static const Identifier* lookupSetterPropertyName = new Identifier("__lookupSetter__"); > >- putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::ToString, 0, exec->propertyNames().toString), DontEnum); >- putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::ToLocaleString, 0, exec->propertyNames().toLocaleString), DontEnum); >- putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::ValueOf, 0, exec->propertyNames().valueOf), DontEnum); >- putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::HasOwnProperty, 1, *hasOwnPropertyPropertyName), DontEnum); >- putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::PropertyIsEnumerable, 1, *propertyIsEnumerablePropertyName), DontEnum); >- putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::IsPrototypeOf, 1, *isPrototypeOfPropertyName), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, *hasOwnPropertyPropertyName, objectProtoFuncHasOwnProperty), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, *propertyIsEnumerablePropertyName, objectProtoFuncPropertyIsEnumerable), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, *isPrototypeOfPropertyName, objectProtoFuncIsPrototypeOf), DontEnum); > > // Mozilla extensions >- putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::DefineGetter, 2, *defineGetterPropertyName), DontEnum); >- putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::DefineSetter, 2, *defineSetterPropertyName), DontEnum); >- putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::LookupGetter, 1, *lookupGetterPropertyName), DontEnum); >- putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::LookupSetter, 1, *lookupSetterPropertyName), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 2, *defineGetterPropertyName, objectProtoFuncDefineGetter), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 2, *defineSetterPropertyName, objectProtoFuncDefineSetter), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, *lookupGetterPropertyName, objectProtoFuncLookupGetter), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, *lookupSetterPropertyName, objectProtoFuncLookupSetter), DontEnum); > } > > >-// ------------------------------ ObjectProtoFunc -------------------------------- >+// ------------------------------ Functions -------------------------------- > >-ObjectProtoFunc::ObjectProtoFunc(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name) >- : InternalFunctionImp(funcProto, name) >- , id(i) >+// ECMA 15.2.4.2, 15.2.4.4, 15.2.4.5, 15.2.4.7 >+ >+JSValue* objectProtoFuncValueOf(ExecState*, JSObject* thisObj, const List&) > { >- putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum); >+ return thisObj; > } > >+JSValue* objectProtoFuncHasOwnProperty(ExecState* exec, JSObject* thisObj, const List& args) >+{ >+ return jsBoolean(thisObj->hasOwnProperty(exec, Identifier(args[0]->toString(exec)))); >+} > >-// ECMA 15.2.4.2, 15.2.4.4, 15.2.4.5, 15.2.4.7 >+JSValue* objectProtoFuncIsPrototypeOf(ExecState*, JSObject* thisObj, const List& args) >+{ >+ if (!args[0]->isObject()) >+ return jsBoolean(false); >+ >+ JSValue* v = static_cast<JSObject*>(args[0])->prototype(); >+ >+ while (true) { >+ if (!v->isObject()) >+ return jsBoolean(false); >+ if (thisObj == static_cast<JSObject*>(v)) >+ return jsBoolean(true); >+ v = static_cast<JSObject*>(v)->prototype(); >+ } >+} >+ >+JSValue* objectProtoFuncDefineGetter(ExecState* exec, JSObject* thisObj, const List& args) >+{ >+ if (!args[1]->isObject() || !static_cast<JSObject*>(args[1])->implementsCall()) >+ return throwError(exec, SyntaxError, "invalid getter usage"); >+ >+ thisObj->defineGetter(exec, Identifier(args[0]->toString(exec)), static_cast<JSObject *>(args[1])); >+ return jsUndefined(); >+} >+ >+JSValue* objectProtoFuncDefineSetter(ExecState* exec, JSObject* thisObj, const List& args) >+{ >+ if (!args[1]->isObject() || !static_cast<JSObject*>(args[1])->implementsCall()) >+ return throwError(exec, SyntaxError, "invalid setter usage"); >+ >+ thisObj->defineSetter(exec, Identifier(args[0]->toString(exec)), static_cast<JSObject *>(args[1])); >+ return jsUndefined(); >+} > >-JSValue *ObjectProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) >+JSValue* objectProtoFuncLookupGetter(ExecState* exec, JSObject* thisObj, const List& args) > { >- switch (id) { >- case ValueOf: >- return thisObj; >- case HasOwnProperty: >- return jsBoolean(thisObj->hasOwnProperty(exec, Identifier(args[0]->toString(exec)))); >- case IsPrototypeOf: { >- if (!args[0]->isObject()) >- return jsBoolean(false); >- >- JSValue *v = static_cast<JSObject *>(args[0])->prototype(); >- >- while (true) { >- if (!v->isObject()) >- return jsBoolean(false); >- >- if (thisObj == static_cast<JSObject *>(v)) >- return jsBoolean(true); >- >- v = static_cast<JSObject *>(v)->prototype(); >- } >+ Identifier propertyName = Identifier(args[0]->toString(exec)); >+ JSObject* obj = thisObj; >+ while (true) { >+ JSValue* v = obj->getDirect(propertyName); >+ if (v) { >+ if (v->type() != GetterSetterType) >+ return jsUndefined(); >+ JSObject* funcObj = static_cast<GetterSetterImp*>(v)->getGetter(); >+ if (!funcObj) >+ return jsUndefined(); >+ return funcObj; > } >- case DefineGetter: >- case DefineSetter: { >- if (!args[1]->isObject() || >- !static_cast<JSObject *>(args[1])->implementsCall()) { >- if (id == DefineGetter) >- return throwError(exec, SyntaxError, "invalid getter usage"); >- else >- return throwError(exec, SyntaxError, "invalid setter usage"); >- } >- >- if (id == DefineGetter) >- thisObj->defineGetter(exec, Identifier(args[0]->toString(exec)), static_cast<JSObject *>(args[1])); >- else >- thisObj->defineSetter(exec, Identifier(args[0]->toString(exec)), static_cast<JSObject *>(args[1])); >+ >+ if (!obj->prototype() || !obj->prototype()->isObject()) > return jsUndefined(); >+ obj = static_cast<JSObject*>(obj->prototype()); >+ } >+} >+ >+JSValue* objectProtoFuncLookupSetter(ExecState* exec, JSObject* thisObj, const List& args) >+{ >+ Identifier propertyName = Identifier(args[0]->toString(exec)); >+ JSObject* obj = thisObj; >+ while (true) { >+ JSValue* v = obj->getDirect(propertyName); >+ if (v) { >+ if (v->type() != GetterSetterType) >+ return jsUndefined(); >+ JSObject* funcObj = static_cast<GetterSetterImp*>(v)->getSetter(); >+ if (!funcObj) >+ return jsUndefined(); >+ return funcObj; > } >- case LookupGetter: >- case LookupSetter: { >- Identifier propertyName = Identifier(args[0]->toString(exec)); >- >- JSObject *obj = thisObj; >- while (true) { >- JSValue *v = obj->getDirect(propertyName); >- >- if (v) { >- if (v->type() != GetterSetterType) >- return jsUndefined(); >- >- JSObject *funcObj; >- >- if (id == LookupGetter) >- funcObj = static_cast<GetterSetterImp *>(v)->getGetter(); >- else >- funcObj = static_cast<GetterSetterImp *>(v)->getSetter(); >- >- if (!funcObj) >- return jsUndefined(); >- else >- return funcObj; >- } >- >- if (!obj->prototype() || !obj->prototype()->isObject()) >- return jsUndefined(); >- >- obj = static_cast<JSObject *>(obj->prototype()); >- } >- } >- case PropertyIsEnumerable: >- return jsBoolean(thisObj->propertyIsEnumerable(exec, Identifier(args[0]->toString(exec)))); >- case ToLocaleString: >- return jsString(thisObj->toString(exec)); >- case ToString: >- default: >- return jsString("[object " + thisObj->className() + "]"); >+ >+ if (!obj->prototype() || !obj->prototype()->isObject()) >+ return jsUndefined(); >+ obj = static_cast<JSObject*>(obj->prototype()); > } > } > >+JSValue* objectProtoFuncPropertyIsEnumerable(ExecState* exec, JSObject* thisObj, const List& args) >+{ >+ return jsBoolean(thisObj->propertyIsEnumerable(exec, Identifier(args[0]->toString(exec)))); >+} >+ >+JSValue* objectProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const List&) >+{ >+ return jsString(thisObj->toString(exec)); >+} >+ >+JSValue* objectProtoFuncToString(ExecState*, JSObject* thisObj, const List&) >+{ >+ return jsString("[object " + thisObj->className() + "]"); >+} >+ > // ------------------------------ ObjectObjectImp -------------------------------- > > ObjectObjectImp::ObjectObjectImp(ExecState* exec, ObjectPrototype* objProto, FunctionPrototype* funcProto) >@@ -191,3 +203,4 @@ JSValue* ObjectObjectImp::callAsFunction > return construct(exec, args); > } > >+} // namespace KJS >Index: kjs/object_object.h >=================================================================== >--- kjs/object_object.h (revision 29541) >+++ kjs/object_object.h (working copy) >@@ -1,7 +1,6 @@ >-// -*- c-basic-offset: 2 -*- > /* >- * This file is part of the KDE libraries > * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) >+ * Copyright (C) 2008 Apple Inc. All rights reserved. > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Lesser General Public >@@ -26,54 +25,42 @@ > > namespace KJS { > >- class FunctionPrototype; >+ /** >+ * @internal >+ * >+ * The initial value of Object.prototype (and thus all objects created >+ * with the Object constructor >+ */ >+ class ObjectPrototype : public JSObject { >+ public: >+ ObjectPrototype(ExecState*, FunctionPrototype*); >+ }; >+ >+ JSValue* objectProtoFuncValueOf(ExecState*, JSObject*, const List&); >+ JSValue* objectProtoFuncHasOwnProperty(ExecState*, JSObject*, const List&); >+ JSValue* objectProtoFuncIsPrototypeOf(ExecState*, JSObject*, const List&); >+ JSValue* objectProtoFuncDefineGetter(ExecState*, JSObject*, const List&); >+ JSValue* objectProtoFuncDefineSetter(ExecState*, JSObject*, const List&); >+ JSValue* objectProtoFuncLookupGetter(ExecState*, JSObject*, const List&); >+ JSValue* objectProtoFuncLookupSetter(ExecState*, JSObject*, const List&); >+ JSValue* objectProtoFuncPropertyIsEnumerable(ExecState*, JSObject*, const List&); >+ JSValue* objectProtoFuncToLocaleString(ExecState*, JSObject*, const List&); >+ JSValue* objectProtoFuncToString(ExecState*, JSObject*, const List&); >+ >+ /** >+ * @internal >+ * >+ * The initial value of the the global variable's "Object" property >+ */ >+ class ObjectObjectImp : public InternalFunctionImp { >+ public: >+ ObjectObjectImp(ExecState*, ObjectPrototype*, FunctionPrototype*); >+ >+ virtual bool implementsConstruct() const; >+ virtual JSObject* construct(ExecState*, const List&); >+ virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&); >+ }; > >- /** >- * @internal >- * >- * The initial value of Object.prototype (and thus all objects created >- * with the Object constructor >- */ >- class ObjectPrototype : public JSObject { >- public: >- ObjectPrototype(ExecState *exec, FunctionPrototype *funcProto); >- }; >- >- /** >- * @internal >- * >- * Class to implement all methods that are properties of the >- * Object.prototype object >- */ >- class ObjectProtoFunc : public InternalFunctionImp { >- public: >- ObjectProtoFunc(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier&); >- >- virtual JSValue *callAsFunction(ExecState *, JSObject *, const List &args); >- >- enum { ToString, ToLocaleString, ValueOf, HasOwnProperty, IsPrototypeOf, PropertyIsEnumerable, >- DefineGetter, DefineSetter, LookupGetter, LookupSetter }; >- private: >- int id; >- }; >- >- /** >- * @internal >- * >- * The initial value of the the global variable's "Object" property >- */ >- class ObjectObjectImp : public InternalFunctionImp { >- public: >- >- ObjectObjectImp(ExecState *exec, >- ObjectPrototype *objProto, >- FunctionPrototype *funcProto); >- >- virtual bool implementsConstruct() const; >- virtual JSObject *construct(ExecState *, const List &args); >- virtual JSValue *callAsFunction(ExecState *, JSObject *, const List &args); >- }; >+} // namespace KJS > >-} // namespace >- >-#endif >+#endif // _OBJECT_OBJECT_H_ >Index: kjs/regexp_object.cpp >=================================================================== >--- kjs/regexp_object.cpp (revision 29541) >+++ kjs/regexp_object.cpp (working copy) >@@ -1,6 +1,6 @@ > /* > * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) >- * Copyright (C) 2003, 2007 Apple Inc. All Rights Reserved. >+ * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved. > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Lesser General Public >@@ -43,84 +43,82 @@ namespace KJS { > > const ClassInfo RegExpPrototype::info = { "RegExpPrototype", 0, 0 }; > >-RegExpPrototype::RegExpPrototype(ExecState *exec, >- ObjectPrototype *objProto, >- FunctionPrototype *funcProto) >- : JSObject(objProto) >+RegExpPrototype::RegExpPrototype(ExecState* exec, ObjectPrototype* objectPrototype, FunctionPrototype* functionPrototype) >+ : JSObject(objectPrototype) > { >- static const Identifier* compilePropertyName = new Identifier("compile"); >- static const Identifier* execPropertyName = new Identifier("exec"); >- static const Identifier* testPropertyName = new Identifier("test"); >+ static const Identifier* compilePropertyName = new Identifier("compile"); >+ static const Identifier* execPropertyName = new Identifier("exec"); >+ static const Identifier* testPropertyName = new Identifier("test"); > >- putDirectFunction(new RegExpProtoFunc(exec, funcProto, RegExpProtoFunc::Compile, 0, *compilePropertyName), DontEnum); >- putDirectFunction(new RegExpProtoFunc(exec, funcProto, RegExpProtoFunc::Exec, 0, *execPropertyName), DontEnum); >- putDirectFunction(new RegExpProtoFunc(exec, funcProto, RegExpProtoFunc::Test, 0, *testPropertyName), DontEnum); >- putDirectFunction(new RegExpProtoFunc(exec, funcProto, RegExpProtoFunc::ToString, 0, exec->propertyNames().toString), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, *compilePropertyName, regExpProtoFuncCompile), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, *execPropertyName, regExpProtoFuncExec), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, *testPropertyName, regExpProtoFuncTest), DontEnum); >+ putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, regExpProtoFuncToString), DontEnum); > } > >-// ------------------------------ RegExpProtoFunc --------------------------- >+// ------------------------------ Functions --------------------------- >+ >+JSValue* regExpProtoFuncTest(ExecState* exec, JSObject* thisObj, const List& args) >+{ >+ if (!thisObj->inherits(&RegExpImp::info)) >+ return throwError(exec, TypeError); > >-RegExpProtoFunc::RegExpProtoFunc(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name) >- : InternalFunctionImp(funcProto, name), id(i) >+ return static_cast<RegExpImp*>(thisObj)->test(exec, args); >+} >+ >+JSValue* regExpProtoFuncExec(ExecState* exec, JSObject* thisObj, const List& args) > { >- putDirect(exec->propertyNames().length, len, DontDelete | ReadOnly | DontEnum); >+ if (!thisObj->inherits(&RegExpImp::info)) >+ return throwError(exec, TypeError); >+ >+ return static_cast<RegExpImp*>(thisObj)->exec(exec, args); > } > >-JSValue *RegExpProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) >+JSValue* regExpProtoFuncCompile(ExecState* exec, JSObject* thisObj, const List& args) > { >- if (!thisObj->inherits(&RegExpImp::info)) { >- if (thisObj->inherits(&RegExpPrototype::info)) { >- switch (id) { >- case ToString: return jsString("//"); >- } >- } >- >- return throwError(exec, TypeError); >- } >+ if (!thisObj->inherits(&RegExpImp::info)) >+ return throwError(exec, TypeError); > >- switch (id) { >- case Test: >- return static_cast<RegExpImp*>(thisObj)->test(exec, args); >- case Exec: >- return static_cast<RegExpImp*>(thisObj)->exec(exec, args); >- case Compile: >- { > RefPtr<RegExp> regExp; > JSValue* arg0 = args[0]; > JSValue* arg1 = args[1]; > > if (arg0->isObject(&RegExpImp::info)) { >- if (!arg1->isUndefined()) >- return throwError(exec, TypeError, "Cannot supply flags when constructing one RegExp from another."); >- regExp = static_cast<RegExpImp*>(arg0)->regExp(); >+ if (!arg1->isUndefined()) >+ return throwError(exec, TypeError, "Cannot supply flags when constructing one RegExp from another."); >+ regExp = static_cast<RegExpImp*>(arg0)->regExp(); > } else { >- UString pattern = args.isEmpty() ? UString("") : arg0->toString(exec); >- UString flags = arg1->isUndefined() ? UString("") : arg1->toString(exec); >- regExp = new RegExp(pattern, flags); >+ UString pattern = args.isEmpty() ? UString("") : arg0->toString(exec); >+ UString flags = arg1->isUndefined() ? UString("") : arg1->toString(exec); >+ regExp = new RegExp(pattern, flags); > } > > if (!regExp->isValid()) >- return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage())); >+ return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage())); > > static_cast<RegExpImp*>(thisObj)->setRegExp(regExp.release()); > static_cast<RegExpImp*>(thisObj)->put(exec, exec->propertyNames().lastIndex, jsNumber(0), DontDelete|DontEnum); > return jsUndefined(); >- } >- case ToString: >- UString result = "/" + thisObj->get(exec, exec->propertyNames().source)->toString(exec) + "/"; >- if (thisObj->get(exec, exec->propertyNames().global)->toBoolean(exec)) { >- result += "g"; >- } >- if (thisObj->get(exec, exec->propertyNames().ignoreCase)->toBoolean(exec)) { >- result += "i"; >- } >- if (thisObj->get(exec, exec->propertyNames().multiline)->toBoolean(exec)) { >- result += "m"; >+} >+ >+JSValue* regExpProtoFuncToString(ExecState* exec, JSObject* thisObj, const List&) >+{ >+ if (!thisObj->inherits(&RegExpImp::info)) { >+ if (thisObj->inherits(&RegExpPrototype::info)) >+ return jsString("//"); >+ return throwError(exec, TypeError); > } >+ >+ UString result = "/" + thisObj->get(exec, exec->propertyNames().source)->toString(exec) + "/"; >+ if (thisObj->get(exec, exec->propertyNames().global)->toBoolean(exec)) >+ result += "g"; >+ if (thisObj->get(exec, exec->propertyNames().ignoreCase)->toBoolean(exec)) >+ result += "i"; >+ if (thisObj->get(exec, exec->propertyNames().multiline)->toBoolean(exec)) >+ result += "m"; > return jsString(result); >- } > >- return jsUndefined(); >+ return jsUndefined(); > } > > // ------------------------------ RegExpImp ------------------------------------ >Index: kjs/regexp_object.h >=================================================================== >--- kjs/regexp_object.h (revision 29541) >+++ kjs/regexp_object.h (working copy) >@@ -1,6 +1,6 @@ > /* > * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) >- * Copyright (C) 2003, 2007 Apple Inc. All Rights Reserved. >+ * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved. > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Lesser General Public >@@ -31,20 +31,15 @@ namespace KJS { > class RegExpPrototype : public JSObject { > public: > RegExpPrototype(ExecState*, ObjectPrototype*, FunctionPrototype*); >+ > virtual const ClassInfo* classInfo() const { return &info; } > static const ClassInfo info; > }; > >- class RegExpProtoFunc : public InternalFunctionImp { >- public: >- enum { Compile, Exec, Test, ToString }; >- >- RegExpProtoFunc(ExecState*, FunctionPrototype*, int id, int len, const Identifier&); >- virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&); >- >- private: >- int id; >- }; >+ JSValue* regExpProtoFuncTest(ExecState*, JSObject*, const List&); >+ JSValue* regExpProtoFuncExec(ExecState*, JSObject*, const List&); >+ JSValue* regExpProtoFuncCompile(ExecState*, JSObject*, const List&); >+ JSValue* regExpProtoFuncToString(ExecState*, JSObject*, const List&); > > class RegExpImp : public JSObject { > public:
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
darin
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 16901
: 18490 |
18491