Changeset 29588 in webkit
- Timestamp:
- Jan 17, 2008 11:27:33 AM (16 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r29542 r29588 1 2008-01-16 Sam Weinig <sam@webkit.org> 2 3 Reviewed by Darin. 4 5 Fix for http://bugs.webkit.org/show_bug.cgi?id=16901 6 Convert remaining JS function objects to use the new PrototypeFunction class 7 8 - Moves Boolean, Function, RegExp, Number, Object and Global functions to their 9 own static function implementations so that they can be used with the 10 PrototypeFunction class. SunSpider says this is 1.003x as fast. 11 12 * kjs/JSGlobalObject.cpp: 13 (KJS::JSGlobalObject::reset): 14 * kjs/array_object.h: 15 * kjs/bool_object.cpp: 16 (KJS::BooleanInstance::BooleanInstance): 17 (KJS::BooleanPrototype::BooleanPrototype): 18 (KJS::booleanProtoFuncToString): 19 (KJS::booleanProtoFuncValueOf): 20 (KJS::BooleanObjectImp::BooleanObjectImp): 21 (KJS::BooleanObjectImp::implementsConstruct): 22 (KJS::BooleanObjectImp::construct): 23 (KJS::BooleanObjectImp::callAsFunction): 24 * kjs/bool_object.h: 25 (KJS::BooleanInstance::classInfo): 26 * kjs/error_object.cpp: 27 (KJS::ErrorPrototype::ErrorPrototype): 28 (KJS::errorProtoFuncToString): 29 * kjs/error_object.h: 30 * kjs/function.cpp: 31 (KJS::globalFuncEval): 32 (KJS::globalFuncParseInt): 33 (KJS::globalFuncParseFloat): 34 (KJS::globalFuncIsNaN): 35 (KJS::globalFuncIsFinite): 36 (KJS::globalFuncDecodeURI): 37 (KJS::globalFuncDecodeURIComponent): 38 (KJS::globalFuncEncodeURI): 39 (KJS::globalFuncEncodeURIComponent): 40 (KJS::globalFuncEscape): 41 (KJS::globalFuncUnEscape): 42 (KJS::globalFuncKJSPrint): 43 (KJS::PrototypeFunction::PrototypeFunction): 44 * kjs/function.h: 45 * kjs/function_object.cpp: 46 (KJS::FunctionPrototype::FunctionPrototype): 47 (KJS::functionProtoFuncToString): 48 (KJS::functionProtoFuncApply): 49 (KJS::functionProtoFuncCall): 50 * kjs/function_object.h: 51 * kjs/number_object.cpp: 52 (KJS::NumberPrototype::NumberPrototype): 53 (KJS::numberProtoFuncToString): 54 (KJS::numberProtoFuncToLocaleString): 55 (KJS::numberProtoFuncValueOf): 56 (KJS::numberProtoFuncToFixed): 57 (KJS::numberProtoFuncToExponential): 58 (KJS::numberProtoFuncToPrecision): 59 * kjs/number_object.h: 60 (KJS::NumberInstance::classInfo): 61 (KJS::NumberObjectImp::classInfo): 62 (KJS::NumberObjectImp::): 63 * kjs/object_object.cpp: 64 (KJS::ObjectPrototype::ObjectPrototype): 65 (KJS::objectProtoFuncValueOf): 66 (KJS::objectProtoFuncHasOwnProperty): 67 (KJS::objectProtoFuncIsPrototypeOf): 68 (KJS::objectProtoFuncDefineGetter): 69 (KJS::objectProtoFuncDefineSetter): 70 (KJS::objectProtoFuncLookupGetter): 71 (KJS::objectProtoFuncLookupSetter): 72 (KJS::objectProtoFuncPropertyIsEnumerable): 73 (KJS::objectProtoFuncToLocaleString): 74 (KJS::objectProtoFuncToString): 75 * kjs/object_object.h: 76 * kjs/regexp_object.cpp: 77 (KJS::RegExpPrototype::RegExpPrototype): 78 (KJS::regExpProtoFuncTest): 79 (KJS::regExpProtoFuncExec): 80 (KJS::regExpProtoFuncCompile): 81 (KJS::regExpProtoFuncToString): 82 * kjs/regexp_object.h: 83 1 84 2008-01-16 Cameron Zwarich <cwzwarich@uwaterloo.ca> 2 85 -
trunk/JavaScriptCore/kjs/JSGlobalObject.cpp
r29443 r29588 232 232 d()->numberPrototype = new NumberPrototype(exec, d()->objectPrototype, d()->functionPrototype); 233 233 d()->datePrototype = new DatePrototype(exec, d()->objectPrototype); 234 d()->regExpPrototype = new RegExpPrototype(exec, d()->objectPrototype, d()->functionPrototype); ;234 d()->regExpPrototype = new RegExpPrototype(exec, d()->objectPrototype, d()->functionPrototype); 235 235 d()->errorPrototype = new ErrorPrototype(exec, d()->objectPrototype, d()->functionPrototype); 236 236 … … 312 312 // Set global functions. 313 313 314 putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::Eval, 1, "eval"), DontEnum);315 putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::ParseInt, 2, "parseInt"), DontEnum);316 putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::ParseFloat, 1, "parseFloat"), DontEnum);317 putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::IsNaN, 1, "isNaN"), DontEnum);318 putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::IsFinite, 1, "isFinite"), DontEnum);319 putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::Escape, 1, "escape"), DontEnum);320 putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::UnEscape, 1, "unescape"), DontEnum);321 putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::DecodeURI, 1, "decodeURI"), DontEnum);322 putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::DecodeURIComponent, 1, "decodeURIComponent"), DontEnum);323 putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::EncodeURI, 1, "encodeURI"), DontEnum);324 putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::EncodeURIComponent, 1, "encodeURIComponent"), DontEnum);314 putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "eval", globalFuncEval), DontEnum); 315 putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 2, "parseInt", globalFuncParseInt), DontEnum); 316 putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "parseFloat", globalFuncParseFloat), DontEnum); 317 putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "isNaN", globalFuncIsNaN), DontEnum); 318 putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "isFinite", globalFuncIsFinite), DontEnum); 319 putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "escape", globalFuncEscape), DontEnum); 320 putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "unescape", globalFuncUnescape), DontEnum); 321 putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "decodeURI", globalFuncDecodeURI), DontEnum); 322 putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "decodeURIComponent", globalFuncDecodeURIComponent), DontEnum); 323 putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "encodeURI", globalFuncEncodeURI), DontEnum); 324 putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "encodeURIComponent", globalFuncEncodeURIComponent), DontEnum); 325 325 #ifndef NDEBUG 326 putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::KJSPrint, 1, "kjsprint"), DontEnum);326 putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "kjsprint", globalFuncKJSPrint), DontEnum); 327 327 #endif 328 328 -
trunk/JavaScriptCore/kjs/array_object.h
r29508 r29588 1 // -*- c-basic-offset: 2 -*-2 1 /* 3 * This file is part of the KDE libraries4 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 5 * Copyright (C) 2007 Apple Inc. All rights reserved.3 * Copyright (C) 2007 Apple Inc. All rights reserved. 6 4 * 7 5 * This library is free software; you can redistribute it and/or -
trunk/JavaScriptCore/kjs/bool_object.cpp
r28469 r29588 1 // -*- c-basic-offset: 2 -*-2 1 /* 3 * This file is part of the KDE libraries4 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 5 * Copyright (C) 2003 Apple Computer, Inc.3 * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. 6 4 * 7 5 * This library is free software; you can redistribute it and/or … … 29 27 #include <wtf/Assertions.h> 30 28 31 using namespace KJS; 29 namespace KJS { 32 30 33 31 // ------------------------------ BooleanInstance --------------------------- 34 32 35 const ClassInfo BooleanInstance::info = { "Boolean", 0, 0};33 const ClassInfo BooleanInstance::info = { "Boolean", 0, 0 }; 36 34 37 BooleanInstance::BooleanInstance(JSObject *proto)38 : JSWrapperObject(proto)35 BooleanInstance::BooleanInstance(JSObject* proto) 36 : JSWrapperObject(proto) 39 37 { 40 38 } … … 42 40 // ------------------------------ BooleanPrototype -------------------------- 43 41 42 // Functions 43 static JSValue* booleanProtoFuncToString(ExecState*, JSObject*, const List&); 44 static JSValue* booleanProtoFuncValueOf(ExecState*, JSObject*, const List&); 45 44 46 // ECMA 15.6.4 45 47 46 BooleanPrototype::BooleanPrototype(ExecState* exec, ObjectPrototype* objectProto , FunctionPrototype* funcProto)47 : BooleanInstance(objectProto)48 BooleanPrototype::BooleanPrototype(ExecState* exec, ObjectPrototype* objectPrototype, FunctionPrototype* functionPrototype) 49 : BooleanInstance(objectPrototype) 48 50 { 49 putDirectFunction(new BooleanProtoFunc(exec, funcProto, BooleanProtoFunc::ToString, 0, exec->propertyNames().toString), DontEnum); 50 putDirectFunction(new BooleanProtoFunc(exec, funcProto, BooleanProtoFunc::ValueOf, 0, exec->propertyNames().valueOf), DontEnum); 51 setInternalValue(jsBoolean(false)); 51 setInternalValue(jsBoolean(false)); 52 53 putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, booleanProtoFuncToString), DontEnum); 54 putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, booleanProtoFuncValueOf), DontEnum); 52 55 } 53 56 54 57 55 // ------------------------------ BooleanProtoFunc -------------------------- 56 57 BooleanProtoFunc::BooleanProtoFunc(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name) 58 : InternalFunctionImp(funcProto, name) 59 , id(i) 60 { 61 putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum); 62 } 63 58 // ------------------------------ Functions -------------------------- 64 59 65 60 // ECMA 15.6.4.2 + 15.6.4.3 66 JSValue *BooleanProtoFunc::callAsFunction(ExecState* exec, JSObject *thisObj, const List &/*args*/) 61 62 JSValue* booleanProtoFuncToString(ExecState* exec, JSObject* thisObj, const List&) 67 63 { 68 // no generic function. "this" has to be a Boolean object 69 if (!thisObj->inherits(&BooleanInstance::info)) 70 return throwError(exec, TypeError); 64 if (!thisObj->inherits(&BooleanInstance::info)) 65 return throwError(exec, TypeError); 71 66 72 // execute "toString()" or "valueOf()", respectively 67 JSValue* v = static_cast<BooleanInstance*>(thisObj)->internalValue(); 68 ASSERT(v); 73 69 74 JSValue *v = static_cast<BooleanInstance*>(thisObj)->internalValue(); 75 ASSERT(v); 70 return jsString(v->toString(exec)); 71 } 72 JSValue* booleanProtoFuncValueOf(ExecState* exec, JSObject* thisObj, const List&) 73 { 74 if (!thisObj->inherits(&BooleanInstance::info)) 75 return throwError(exec, TypeError); 76 76 77 if (id == ToString) 78 return jsString(v->toString(exec)); 79 return jsBoolean(v->toBoolean(exec)); /* TODO: optimize for bool case */ 77 JSValue* v = static_cast<BooleanInstance*>(thisObj)->internalValue(); 78 ASSERT(v); 79 80 // TODO: optimize for bool case 81 return jsBoolean(v->toBoolean(exec)); 80 82 } 81 83 … … 83 85 84 86 85 BooleanObjectImp::BooleanObjectImp(ExecState* exec, FunctionPrototype* func Proto, BooleanPrototype* booleanProto)86 : InternalFunctionImp(funcProto)87 BooleanObjectImp::BooleanObjectImp(ExecState* exec, FunctionPrototype* functionPrototype, BooleanPrototype* booleanPrototype) 88 : InternalFunctionImp(functionPrototype) 87 89 { 88 putDirect(exec->propertyNames().prototype, booleanProto, DontEnum|DontDelete|ReadOnly);90 putDirect(exec->propertyNames().prototype, booleanPrototype, DontEnum | DontDelete | ReadOnly); 89 91 90 // no. of arguments for constructor91 putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum);92 // no. of arguments for constructor 93 putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum); 92 94 } 93 95 … … 95 97 bool BooleanObjectImp::implementsConstruct() const 96 98 { 97 return true;99 return true; 98 100 } 99 101 100 102 // ECMA 15.6.2 101 JSObject *BooleanObjectImp::construct(ExecState *exec, const List &args)103 JSObject* BooleanObjectImp::construct(ExecState* exec, const List& args) 102 104 { 103 BooleanInstance *obj(new BooleanInstance(exec->lexicalGlobalObject()->booleanPrototype())); 104 105 bool b; 106 if (args.size() > 0) 107 b = args[0]->toBoolean(exec); 108 else 109 b = false; 110 111 obj->setInternalValue(jsBoolean(b)); 112 113 return obj; 105 BooleanInstance* obj(new BooleanInstance(exec->lexicalGlobalObject()->booleanPrototype())); 106 obj->setInternalValue(jsBoolean(args[0]->toBoolean(exec))); 107 return obj; 114 108 } 115 109 116 110 // ECMA 15.6.1 117 JSValue *BooleanObjectImp::callAsFunction(ExecState *exec, JSObject *, const List &args)111 JSValue* BooleanObjectImp::callAsFunction(ExecState* exec, JSObject*, const List& args) 118 112 { 119 if (args.isEmpty()) 120 return jsBoolean(false); 121 else 122 return jsBoolean(args[0]->toBoolean(exec)); /* TODO: optimize for bool case */ 113 // TODO: optimize for bool case 114 return jsBoolean(args[0]->toBoolean(exec)); 123 115 } 124 116 117 } // namespace KJS -
trunk/JavaScriptCore/kjs/bool_object.h
r28110 r29588 1 // -*- c-basic-offset: 2 -*-2 1 /* 3 * This file is part of the KDE libraries4 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2008 Apple Inc. All rights reserved. 5 4 * 6 5 * This library is free software; you can redistribute it and/or … … 28 27 namespace KJS { 29 28 30 class BooleanInstance : public JSWrapperObject {31 public:32 BooleanInstance(JSObject *proto);29 class BooleanInstance : public JSWrapperObject { 30 public: 31 BooleanInstance(JSObject* proto); 33 32 34 virtual const ClassInfo *classInfo() const { return &info; }35 static const ClassInfo info;36 };33 virtual const ClassInfo* classInfo() const { return &info; } 34 static const ClassInfo info; 35 }; 37 36 38 /** 39 * @internal 40 * 41 * The initial value of Boolean.prototype (and thus all objects created 42 * with the Boolean constructor 43 */ 44 class BooleanPrototype : public BooleanInstance { 45 public: 46 BooleanPrototype(ExecState *exec, 47 ObjectPrototype *objectProto, 48 FunctionPrototype *funcProto); 49 }; 37 /** 38 * @internal 39 * 40 * The initial value of Boolean.prototype (and thus all objects created 41 * with the Boolean constructor 42 */ 43 class BooleanPrototype : public BooleanInstance { 44 public: 45 BooleanPrototype(ExecState*, ObjectPrototype*, FunctionPrototype*); 46 }; 50 47 51 /** 52 * @internal 53 * 54 * Class to implement all methods that are properties of the 55 * Boolean.prototype object 56 */ 57 class BooleanProtoFunc : public InternalFunctionImp { 58 public: 59 BooleanProtoFunc(ExecState*, FunctionPrototype*, int i, int len, const Identifier&); 48 /** 49 * @internal 50 * 51 * The initial value of the the global variable's "Boolean" property 52 */ 53 class BooleanObjectImp : public InternalFunctionImp { 54 public: 55 BooleanObjectImp(ExecState*, FunctionPrototype*, BooleanPrototype*); 60 56 61 virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); 57 virtual bool implementsConstruct() const; 58 virtual JSObject* construct(ExecState*, const List&); 62 59 63 enum { ToString, ValueOf }; 64 private: 65 int id; 66 }; 60 virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&); 61 }; 67 62 68 /** 69 * @internal 70 * 71 * The initial value of the the global variable's "Boolean" property 72 */ 73 class BooleanObjectImp : public InternalFunctionImp { 74 friend class BooleanProtoFunc; 75 public: 76 BooleanObjectImp(ExecState *exec, FunctionPrototype *funcProto, 77 BooleanPrototype *booleanProto); 63 } // namespace KJS 78 64 79 virtual bool implementsConstruct() const; 80 virtual JSObject *construct(ExecState *exec, const List &args); 81 82 virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); 83 }; 84 85 } // namespace 86 87 #endif 65 #endif // BOOL_OBJECT_H_ -
trunk/JavaScriptCore/kjs/error_object.cpp
r29091 r29588 42 42 43 43 // ECMA 15.9.4 44 ErrorPrototype::ErrorPrototype(ExecState* exec, ObjectPrototype* objectProto , FunctionPrototype* funcProto)45 : JSObject(objectProto )44 ErrorPrototype::ErrorPrototype(ExecState* exec, ObjectPrototype* objectPrototype, FunctionPrototype* functionPrototype) 45 : JSObject(objectPrototype) 46 46 { 47 47 // The constructor will be added later in ErrorObjectImp's constructor … … 49 49 put(exec, exec->propertyNames().name, jsString("Error"), DontEnum); 50 50 put(exec, exec->propertyNames().message, jsString("Unknown error"), DontEnum); 51 putDirectFunction(new ErrorProtoFuncToString(exec, funcProto), DontEnum); 51 52 putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum); 52 53 } 53 54 54 // ------------------------------ ErrorProtoFunc ---------------------------- 55 56 ErrorProtoFuncToString::ErrorProtoFuncToString(ExecState* exec, FunctionPrototype* funcProto) 57 : InternalFunctionImp(funcProto, exec->propertyNames().toString) 58 { 59 putDirect(exec->propertyNames().length, jsNumber(0), DontDelete|ReadOnly|DontEnum); 60 } 61 62 JSValue* ErrorProtoFuncToString::callAsFunction(ExecState* exec, JSObject* thisObj, const List&) 55 JSValue* errorProtoFuncToString(ExecState* exec, JSObject* thisObj, const List&) 63 56 { 64 57 UString s = "Error"; -
trunk/JavaScriptCore/kjs/error_object.h
r29091 r29588 39 39 }; 40 40 41 class ErrorProtoFuncToString : public InternalFunctionImp { 42 public: 43 ErrorProtoFuncToString(ExecState*, FunctionPrototype*); 44 45 virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&); 46 }; 41 JSValue* errorProtoFuncToString(ExecState*, JSObject*, const List&); 47 42 48 43 class ErrorObjectImp : public InternalFunctionImp { -
trunk/JavaScriptCore/kjs/function.cpp
r29542 r29588 472 472 } 473 473 474 // ------------------------------ GlobalFunc ----------------------------------- 475 476 477 GlobalFuncImp::GlobalFuncImp(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name) 478 : InternalFunctionImp(funcProto, name) 479 , id(i) 480 { 481 putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum); 482 } 474 // ------------------------------ Global Functions ----------------------------------- 483 475 484 476 static JSValue* encode(ExecState* exec, const List& args, const char* do_not_escape) … … 701 693 } 702 694 703 JSValue* GlobalFuncImp::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args) 704 { 705 JSValue* res = jsUndefined(); 706 707 static const char do_not_escape[] = 708 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 709 "abcdefghijklmnopqrstuvwxyz" 710 "0123456789" 711 "*+-./@_"; 712 713 static const char do_not_escape_when_encoding_URI_component[] = 714 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 715 "abcdefghijklmnopqrstuvwxyz" 716 "0123456789" 717 "!'()*-._~"; 718 static const char do_not_escape_when_encoding_URI[] = 719 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 720 "abcdefghijklmnopqrstuvwxyz" 721 "0123456789" 722 "!#$&'()*+,-./:;=?@_~"; 723 static const char do_not_unescape_when_decoding_URI[] = 724 "#$&+,/:;=?@"; 725 726 switch (id) { 727 case Eval: { // eval() 728 JSValue* x = args[0]; 729 if (!x->isString()) 695 JSValue* globalFuncEval(ExecState* exec, JSObject* thisObj, const List& args) 696 { 697 JSValue* x = args[0]; 698 if (!x->isString()) 730 699 return x; 731 else { 732 733 734 735 736 737 738 739 740 741 742 700 701 UString s = x->toString(exec); 702 703 int sourceId; 704 int errLine; 705 UString errMsg; 706 RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(UString(), 0, s.data(), s.size(), &sourceId, &errLine, &errMsg); 707 708 Debugger* dbg = exec->dynamicGlobalObject()->debugger(); 709 if (dbg) { 710 bool cont = dbg->sourceParsed(exec, sourceId, UString(), s, 0, errLine, errMsg); 711 if (!cont) 743 712 return jsUndefined(); 744 } 745 746 // no program node means a syntax occurred 747 if (!evalNode) 748 return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL); 749 750 bool switchGlobal = thisObj && thisObj != exec->dynamicGlobalObject() && thisObj->isGlobalObject(); 751 752 // enter a new execution context 753 exec->dynamicGlobalObject()->tearOffActivation(exec); 754 JSGlobalObject* globalObject = switchGlobal ? static_cast<JSGlobalObject*>(thisObj) : exec->dynamicGlobalObject(); 755 ExecState newExec(globalObject, evalNode.get(), exec); 756 757 if (switchGlobal) { 758 newExec.pushScope(thisObj); 759 newExec.setVariableObject(static_cast<JSGlobalObject*>(thisObj)); 760 } 761 JSValue* value = evalNode->execute(&newExec); 762 if (switchGlobal) 763 newExec.popScope(); 764 765 if (newExec.completionType() == Throw) { 766 exec->setException(value); 767 return value; 768 } 769 return value ? value : jsUndefined(); 770 } 771 } 772 case ParseInt: 773 res = jsNumber(parseInt(args[0]->toString(exec), args[1]->toInt32(exec))); 774 break; 775 case ParseFloat: 776 res = jsNumber(parseFloat(args[0]->toString(exec))); 777 break; 778 case IsNaN: 779 res = jsBoolean(isnan(args[0]->toNumber(exec))); 780 break; 781 case IsFinite: { 713 } 714 715 // No program node means a syntax occurred 716 if (!evalNode) 717 return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL); 718 719 bool switchGlobal = thisObj && thisObj != exec->dynamicGlobalObject() && thisObj->isGlobalObject(); 720 721 // enter a new execution context 722 exec->dynamicGlobalObject()->tearOffActivation(exec); 723 JSGlobalObject* globalObject = switchGlobal ? static_cast<JSGlobalObject*>(thisObj) : exec->dynamicGlobalObject(); 724 ExecState newExec(globalObject, evalNode.get(), exec); 725 726 if (switchGlobal) { 727 newExec.pushScope(thisObj); 728 newExec.setVariableObject(static_cast<JSGlobalObject*>(thisObj)); 729 } 730 JSValue* value = evalNode->execute(&newExec); 731 if (switchGlobal) 732 newExec.popScope(); 733 734 if (newExec.completionType() == Throw) { 735 exec->setException(value); 736 return value; 737 } 738 739 return value ? value : jsUndefined(); 740 } 741 742 JSValue* globalFuncParseInt(ExecState* exec, JSObject*, const List& args) 743 { 744 return jsNumber(parseInt(args[0]->toString(exec), args[1]->toInt32(exec))); 745 } 746 747 JSValue* globalFuncParseFloat(ExecState* exec, JSObject*, const List& args) 748 { 749 return jsNumber(parseFloat(args[0]->toString(exec))); 750 } 751 752 JSValue* globalFuncIsNaN(ExecState* exec, JSObject*, const List& args) 753 { 754 return jsBoolean(isnan(args[0]->toNumber(exec))); 755 } 756 757 JSValue* globalFuncIsFinite(ExecState* exec, JSObject*, const List& args) 758 { 782 759 double n = args[0]->toNumber(exec); 783 res = jsBoolean(!isnan(n) && !isinf(n)); 784 break; 785 } 786 case DecodeURI: 787 res = decode(exec, args, do_not_unescape_when_decoding_URI, true); 788 break; 789 case DecodeURIComponent: 790 res = decode(exec, args, "", true); 791 break; 792 case EncodeURI: 793 res = encode(exec, args, do_not_escape_when_encoding_URI); 794 break; 795 case EncodeURIComponent: 796 res = encode(exec, args, do_not_escape_when_encoding_URI_component); 797 break; 798 case Escape: 799 { 800 UString r = "", s, str = args[0]->toString(exec); 801 const UChar* c = str.data(); 802 for (int k = 0; k < str.size(); k++, c++) { 760 return jsBoolean(!isnan(n) && !isinf(n)); 761 } 762 763 JSValue* globalFuncDecodeURI(ExecState* exec, JSObject*, const List& args) 764 { 765 static const char do_not_unescape_when_decoding_URI[] = 766 "#$&+,/:;=?@"; 767 768 return decode(exec, args, do_not_unescape_when_decoding_URI, true); 769 } 770 771 JSValue* globalFuncDecodeURIComponent(ExecState* exec, JSObject*, const List& args) 772 { 773 return decode(exec, args, "", true); 774 } 775 776 JSValue* globalFuncEncodeURI(ExecState* exec, JSObject*, const List& args) 777 { 778 static const char do_not_escape_when_encoding_URI[] = 779 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 780 "abcdefghijklmnopqrstuvwxyz" 781 "0123456789" 782 "!#$&'()*+,-./:;=?@_~"; 783 784 return encode(exec, args, do_not_escape_when_encoding_URI); 785 } 786 787 JSValue* globalFuncEncodeURIComponent(ExecState* exec, JSObject*, const List& args) 788 { 789 static const char do_not_escape_when_encoding_URI_component[] = 790 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 791 "abcdefghijklmnopqrstuvwxyz" 792 "0123456789" 793 "!'()*-._~"; 794 795 return encode(exec, args, do_not_escape_when_encoding_URI_component); 796 } 797 798 JSValue* globalFuncEscape(ExecState* exec, JSObject*, const List& args) 799 { 800 static const char do_not_escape[] = 801 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 802 "abcdefghijklmnopqrstuvwxyz" 803 "0123456789" 804 "*+-./@_"; 805 806 UString r = "", s, str = args[0]->toString(exec); 807 const UChar* c = str.data(); 808 for (int k = 0; k < str.size(); k++, c++) { 803 809 int u = c->uc; 804 810 if (u > 255) { 805 char tmp[7];806 sprintf(tmp, "%%u%04X", u);807 s = UString(tmp);808 } else if (u != 0 && strchr(do_not_escape, (char)u)) {809 s = UString(c, 1);810 }else {811 char tmp[4];812 sprintf(tmp, "%%%02X", u);813 s = UString(tmp);811 char tmp[7]; 812 sprintf(tmp, "%%u%04X", u); 813 s = UString(tmp); 814 } else if (u != 0 && strchr(do_not_escape, (char)u)) 815 s = UString(c, 1); 816 else { 817 char tmp[4]; 818 sprintf(tmp, "%%%02X", u); 819 s = UString(tmp); 814 820 } 815 821 r += s; 816 } 817 res = jsString(r); 818 break; 819 } 820 case UnEscape: 821 { 822 UString s = "", str = args[0]->toString(exec); 823 int k = 0, len = str.size(); 824 while (k < len) { 822 } 823 824 return jsString(r); 825 } 826 827 JSValue* globalFuncUnescape(ExecState* exec, JSObject*, const List& args) 828 { 829 UString s = "", str = args[0]->toString(exec); 830 int k = 0, len = str.size(); 831 while (k < len) { 825 832 const UChar* c = str.data() + k; 826 833 UChar u; 827 if (*c == UChar('%') && k <= len - 6 && *(c+1) == UChar('u')) { 828 if (Lexer::isHexDigit((c+2)->uc) && Lexer::isHexDigit((c+3)->uc) && 829 Lexer::isHexDigit((c+4)->uc) && Lexer::isHexDigit((c+5)->uc)) { 830 u = Lexer::convertUnicode((c+2)->uc, (c+3)->uc, 831 (c+4)->uc, (c+5)->uc); 832 c = &u; 833 k += 5; 834 } 835 } else if (*c == UChar('%') && k <= len - 3 && 836 Lexer::isHexDigit((c+1)->uc) && Lexer::isHexDigit((c+2)->uc)) { 837 u = UChar(Lexer::convertHex((c+1)->uc, (c+2)->uc)); 838 c = &u; 839 k += 2; 834 if (*c == UChar('%') && k <= len - 6 && *(c + 1) == UChar('u')) { 835 if (Lexer::isHexDigit((c + 2)->uc) && Lexer::isHexDigit((c + 3)->uc) && Lexer::isHexDigit((c + 4)->uc) && Lexer::isHexDigit((c + 5)->uc)) { 836 u = Lexer::convertUnicode((c + 2)->uc, (c + 3)->uc, (c + 4)->uc, (c + 5)->uc); 837 c = &u; 838 k += 5; 839 } 840 } else if (*c == UChar('%') && k <= len - 3 && Lexer::isHexDigit((c + 1)->uc) && Lexer::isHexDigit((c + 2)->uc)) { 841 u = UChar(Lexer::convertHex((c+1)->uc, (c+2)->uc)); 842 c = &u; 843 k += 2; 840 844 } 841 845 k++; 842 846 s += UString(c, 1); 843 } 844 res = jsString(s); 845 break; 846 } 847 } 848 849 return jsString(s); 850 } 851 847 852 #ifndef NDEBUG 848 case KJSPrint: 853 JSValue* globalFuncKJSPrint(ExecState* exec, JSObject*, const List& args) 854 { 849 855 puts(args[0]->toString(exec).ascii()); 850 break; 856 return jsUndefined(); 857 } 851 858 #endif 852 }853 854 return res;855 }856 859 857 860 // ------------------------------ PrototypeFunction ------------------------------- … … 865 868 } 866 869 870 PrototypeFunction::PrototypeFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, JSMemberFunction function) 871 : InternalFunctionImp(functionPrototype, name) 872 , m_function(function) 873 { 874 ASSERT_ARG(function, function); 875 put(exec, exec->propertyNames().length, jsNumber(len), DontDelete | ReadOnly | DontEnum); 876 } 877 867 878 JSValue* PrototypeFunction::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args) 868 879 { -
trunk/JavaScriptCore/kjs/function.h
r29508 r29588 55 55 private: 56 56 Identifier m_name; 57 };58 59 /**60 * @internal61 *62 * The initial value of Function.prototype (and thus all objects created63 * with the Function constructor)64 */65 class FunctionPrototype : public InternalFunctionImp {66 public:67 FunctionPrototype(ExecState *exec);68 virtual ~FunctionPrototype();69 70 virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);71 57 }; 72 58 … … 144 130 145 131 PrototypeFunction(ExecState*, int len, const Identifier&, JSMemberFunction); 132 PrototypeFunction(ExecState*, FunctionPrototype*, int len, const Identifier&, JSMemberFunction); 146 133 147 134 virtual JSValue* callAsFunction(ExecState* exec, JSObject* thisObj, const List&); … … 151 138 }; 152 139 153 class GlobalFuncImp : public InternalFunctionImp { 154 public: 155 GlobalFuncImp(ExecState*, FunctionPrototype*, int i, int len, const Identifier&); 156 virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List& args); 157 enum { Eval, ParseInt, ParseFloat, IsNaN, IsFinite, Escape, UnEscape, 158 DecodeURI, DecodeURIComponent, EncodeURI, EncodeURIComponent 140 141 // Global Functions 142 JSValue* globalFuncEval(ExecState*, JSObject*, const List&); 143 JSValue* globalFuncParseInt(ExecState*, JSObject*, const List&); 144 JSValue* globalFuncParseFloat(ExecState*, JSObject*, const List&); 145 JSValue* globalFuncIsNaN(ExecState*, JSObject*, const List&); 146 JSValue* globalFuncIsFinite(ExecState*, JSObject*, const List&); 147 JSValue* globalFuncDecodeURI(ExecState*, JSObject*, const List&); 148 JSValue* globalFuncDecodeURIComponent(ExecState*, JSObject*, const List&); 149 JSValue* globalFuncEncodeURI(ExecState*, JSObject*, const List&); 150 JSValue* globalFuncEncodeURIComponent(ExecState*, JSObject*, const List&); 151 JSValue* globalFuncEscape(ExecState*, JSObject*, const List&); 152 JSValue* globalFuncUnescape(ExecState*, JSObject*, const List&); 159 153 #ifndef NDEBUG 160 , KJSPrint154 JSValue* globalFuncKJSPrint(ExecState*, JSObject*, const List&); 161 155 #endif 162 };163 private:164 int id;165 };166 156 167 static const double mantissaOverflowLowerBound = 9007199254740992.0;168 double parseIntOverflow(const char* s, int length, int radix);157 static const double mantissaOverflowLowerBound = 9007199254740992.0; 158 double parseIntOverflow(const char*, int length, int radix); 169 159 170 160 } // namespace -
trunk/JavaScriptCore/kjs/function_object.cpp
r29067 r29588 37 37 #include <wtf/Assertions.h> 38 38 39 using namespace KJS; 39 namespace KJS { 40 40 41 41 // ------------------------------ FunctionPrototype ------------------------- 42 42 43 FunctionPrototype::FunctionPrototype(ExecState *exec) 44 { 45 static const Identifier* applyPropertyName = new Identifier("apply"); 46 static const Identifier* callPropertyName = new Identifier("call"); 47 48 putDirect(exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum); 49 putDirectFunction(new FunctionProtoFunc(exec, this, FunctionProtoFunc::ToString, 0, exec->propertyNames().toString), DontEnum); 50 putDirectFunction(new FunctionProtoFunc(exec, this, FunctionProtoFunc::Apply, 2, *applyPropertyName), DontEnum); 51 putDirectFunction(new FunctionProtoFunc(exec, this, FunctionProtoFunc::Call, 1, *callPropertyName), DontEnum); 52 } 53 54 FunctionPrototype::~FunctionPrototype() 55 { 43 static JSValue* functionProtoFuncToString(ExecState*, JSObject*, const List&); 44 static JSValue* functionProtoFuncApply(ExecState*, JSObject*, const List&); 45 static JSValue* functionProtoFuncCall(ExecState*, JSObject*, const List&); 46 47 FunctionPrototype::FunctionPrototype(ExecState* exec) 48 { 49 static const Identifier* applyPropertyName = new Identifier("apply"); 50 static const Identifier* callPropertyName = new Identifier("call"); 51 52 putDirect(exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum); 53 54 putDirectFunction(new PrototypeFunction(exec, this, 0, exec->propertyNames().toString, functionProtoFuncToString), DontEnum); 55 putDirectFunction(new PrototypeFunction(exec, this, 2, *applyPropertyName, functionProtoFuncApply), DontEnum); 56 putDirectFunction(new PrototypeFunction(exec, this, 1, *callPropertyName, functionProtoFuncCall), DontEnum); 56 57 } 57 58 58 59 // ECMA 15.3.4 59 JSValue *FunctionPrototype::callAsFunction(ExecState*, JSObject* /*thisObj*/, const List &/*args*/) 60 { 61 return jsUndefined(); 62 } 63 64 // ------------------------------ FunctionProtoFunc ------------------------- 65 66 FunctionProtoFunc::FunctionProtoFunc(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name) 67 : InternalFunctionImp(funcProto, name) 68 , id(i) 69 { 70 putDirect(exec->propertyNames().length, len, DontDelete | ReadOnly | DontEnum); 71 } 72 73 JSValue* FunctionProtoFunc::callAsFunction(ExecState* exec, JSObject* thisObj, const List &args) 74 { 75 JSValue* result = NULL; 76 77 switch (id) { 78 case ToString: 60 JSValue* FunctionPrototype::callAsFunction(ExecState*, JSObject*, const List&) 61 { 62 return jsUndefined(); 63 } 64 65 // Functions 66 67 JSValue* functionProtoFuncToString(ExecState* exec, JSObject* thisObj, const List&) 68 { 79 69 if (!thisObj || !thisObj->inherits(&InternalFunctionImp::info)) { 80 70 #ifndef NDEBUG 81 fprintf(stderr,"attempted toString() call on null or non-function object\n");71 fprintf(stderr,"attempted toString() call on null or non-function object\n"); 82 72 #endif 83 return throwError(exec, TypeError); 84 } 73 return throwError(exec, TypeError); 74 } 75 85 76 if (thisObj->inherits(&FunctionImp::info)) { 86 FunctionImp *fi = static_cast<FunctionImp*>(thisObj); 87 return jsString("function " + fi->functionName().ustring() + "(" + 88 fi->body->paramString() + ") " + fi->body->toString()); 89 } else if (thisObj->inherits(&InternalFunctionImp::info) && 90 !static_cast<InternalFunctionImp*>(thisObj)->functionName().isNull()) { 91 result = jsString("\nfunction " + static_cast<InternalFunctionImp*>(thisObj)->functionName().ustring() + "() {\n" 92 " [native code]\n}\n"); 93 } else { 94 result = jsString("[function]"); 95 } 96 break; 97 case Apply: { 98 JSValue *thisArg = args[0]; 99 JSValue *argArray = args[1]; 100 JSObject *func = thisObj; 101 102 if (!func->implementsCall()) 103 return throwError(exec, TypeError); 104 105 JSObject *applyThis; 77 FunctionImp* fi = static_cast<FunctionImp*>(thisObj); 78 return jsString("function " + fi->functionName().ustring() + "(" + fi->body->paramString() + ") " + fi->body->toString()); 79 } 80 81 if (thisObj->inherits(&InternalFunctionImp::info) && !static_cast<InternalFunctionImp*>(thisObj)->functionName().isNull()) 82 return jsString("\nfunction " + static_cast<InternalFunctionImp*>(thisObj)->functionName().ustring() + "() {\n [native code]\n}\n"); 83 84 return jsString("[function]"); 85 } 86 87 JSValue* functionProtoFuncApply(ExecState* exec, JSObject* thisObj, const List& args) 88 { 89 if (!thisObj->implementsCall()) 90 return throwError(exec, TypeError); 91 92 JSValue* thisArg = args[0]; 93 JSValue* argArray = args[1]; 94 95 JSObject* applyThis; 106 96 if (thisArg->isUndefinedOrNull()) 107 applyThis = exec->dynamicGlobalObject();97 applyThis = exec->dynamicGlobalObject(); 108 98 else 109 applyThis = thisArg->toObject(exec);99 applyThis = thisArg->toObject(exec); 110 100 111 101 List applyArgs; 112 102 if (!argArray->isUndefinedOrNull()) { 113 if (argArray->isObject() && 114 (static_cast<JSObject *>(argArray)->inherits(&ArrayInstance::info) || 115 static_cast<JSObject *>(argArray)->inherits(&Arguments::info))) { 116 117 JSObject *argArrayObj = static_cast<JSObject *>(argArray); 118 unsigned int length = argArrayObj->get(exec, exec->propertyNames().length)->toUInt32(exec); 119 for (unsigned int i = 0; i < length; i++) 120 applyArgs.append(argArrayObj->get(exec,i)); 121 } 122 else 103 if (argArray->isObject() && 104 (static_cast<JSObject*>(argArray)->inherits(&ArrayInstance::info) || 105 static_cast<JSObject*>(argArray)->inherits(&Arguments::info))) { 106 107 JSObject* argArrayObj = static_cast<JSObject*>(argArray); 108 unsigned int length = argArrayObj->get(exec, exec->propertyNames().length)->toUInt32(exec); 109 for (unsigned int i = 0; i < length; i++) 110 applyArgs.append(argArrayObj->get(exec, i)); 111 } else 112 return throwError(exec, TypeError); 113 } 114 115 return thisObj->call(exec, applyThis, applyArgs); 116 } 117 118 JSValue* functionProtoFuncCall(ExecState* exec, JSObject* thisObj, const List& args) 119 { 120 if (!thisObj->implementsCall()) 123 121 return throwError(exec, TypeError); 124 } 125 result = func->call(exec,applyThis,applyArgs); 126 } 127 break; 128 case Call: { 129 JSValue *thisArg = args[0]; 130 JSObject *func = thisObj; 131 132 if (!func->implementsCall()) 133 return throwError(exec, TypeError); 134 135 JSObject *callThis; 122 123 JSValue* thisArg = args[0]; 124 125 JSObject* callThis; 136 126 if (thisArg->isUndefinedOrNull()) 137 callThis = exec->dynamicGlobalObject();127 callThis = exec->dynamicGlobalObject(); 138 128 else 139 callThis = thisArg->toObject(exec);129 callThis = thisArg->toObject(exec); 140 130 141 131 List argsTail; 142 132 args.getSlice(1, argsTail); 143 result = func->call(exec, callThis, argsTail); 144 } 145 break; 146 } 147 148 return result; 133 return thisObj->call(exec, callThis, argsTail); 149 134 } 150 135 151 136 // ------------------------------ FunctionObjectImp ---------------------------- 152 137 153 FunctionObjectImp::FunctionObjectImp(ExecState* exec, FunctionPrototype* funcProto) 154 : InternalFunctionImp(funcProto) 155 { 156 putDirect(exec->propertyNames().prototype, funcProto, DontEnum|DontDelete|ReadOnly); 157 158 // no. of arguments for constructor 159 putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum); 160 } 161 162 FunctionObjectImp::~FunctionObjectImp() 163 { 138 FunctionObjectImp::FunctionObjectImp(ExecState* exec, FunctionPrototype* functionPrototype) 139 : InternalFunctionImp(functionPrototype) 140 { 141 putDirect(exec->propertyNames().prototype, functionPrototype, DontEnum | DontDelete | ReadOnly); 142 143 // Number of arguments for constructor 144 putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum); 164 145 } 165 146 166 147 bool FunctionObjectImp::implementsConstruct() const 167 148 { 168 return true;149 return true; 169 150 } 170 151 … … 172 153 JSObject* FunctionObjectImp::construct(ExecState* exec, const List& args, const Identifier& functionName, const UString& sourceURL, int lineNumber) 173 154 { 174 UString p(""); 175 UString body; 176 int argsSize = args.size(); 177 if (argsSize == 0) { 178 body = ""; 179 } else if (argsSize == 1) { 180 body = args[0]->toString(exec); 181 } else { 182 p = args[0]->toString(exec); 183 for (int k = 1; k < argsSize - 1; k++) 184 p += "," + args[k]->toString(exec); 185 body = args[argsSize-1]->toString(exec); 186 } 187 188 // parse the source code 189 int sourceId; 190 int errLine; 191 UString errMsg; 192 RefPtr<FunctionBodyNode> functionBody = parser().parse<FunctionBodyNode>(sourceURL, lineNumber, body.data(), body.size(), &sourceId, &errLine, &errMsg); 193 194 // notify debugger that source has been parsed 195 Debugger *dbg = exec->dynamicGlobalObject()->debugger(); 196 if (dbg) { 197 // send empty sourceURL to indicate constructed code 198 bool cont = dbg->sourceParsed(exec, sourceId, UString(), body, lineNumber, errLine, errMsg); 199 if (!cont) { 200 dbg->imp()->abort(); 201 return new JSObject(); 202 } 203 } 204 205 // no program node == syntax error - throw a syntax error 206 if (!functionBody) 207 // we can't return a Completion(Throw) here, so just set the exception 208 // and return it 209 return throwError(exec, SyntaxError, errMsg, errLine, sourceId, sourceURL); 210 211 ScopeChain scopeChain; 212 scopeChain.push(exec->lexicalGlobalObject()); 213 214 FunctionImp* fimp = new FunctionImp(exec, functionName, functionBody.get(), scopeChain); 155 UString p(""); 156 UString body; 157 int argsSize = args.size(); 158 if (argsSize == 0) 159 body = ""; 160 else if (argsSize == 1) 161 body = args[0]->toString(exec); 162 else { 163 p = args[0]->toString(exec); 164 for (int k = 1; k < argsSize - 1; k++) 165 p += "," + args[k]->toString(exec); 166 body = args[argsSize - 1]->toString(exec); 167 } 168 169 // parse the source code 170 int sourceId; 171 int errLine; 172 UString errMsg; 173 RefPtr<FunctionBodyNode> functionBody = parser().parse<FunctionBodyNode>(sourceURL, lineNumber, body.data(), body.size(), &sourceId, &errLine, &errMsg); 174 175 // notify debugger that source has been parsed 176 Debugger* dbg = exec->dynamicGlobalObject()->debugger(); 177 if (dbg) { 178 // send empty sourceURL to indicate constructed code 179 bool cont = dbg->sourceParsed(exec, sourceId, UString(), body, lineNumber, errLine, errMsg); 180 if (!cont) { 181 dbg->imp()->abort(); 182 return new JSObject(); 183 } 184 } 185 186 // No program node == syntax error - throw a syntax error 187 if (!functionBody) 188 // We can't return a Completion(Throw) here, so just set the exception 189 // and return it 190 return throwError(exec, SyntaxError, errMsg, errLine, sourceId, sourceURL); 191 192 ScopeChain scopeChain; 193 scopeChain.push(exec->lexicalGlobalObject()); 194 195 FunctionImp* fimp = new FunctionImp(exec, functionName, functionBody.get(), scopeChain); 196 197 // parse parameter list. throw syntax error on illegal identifiers 198 int len = p.size(); 199 const UChar* c = p.data(); 200 int i = 0, params = 0; 201 UString param; 202 while (i < len) { 203 while (*c == ' ' && i < len) 204 c++, i++; 205 if (Lexer::isIdentStart(c->uc)) { // else error 206 param = UString(c, 1); 207 c++, i++; 208 while (i < len && (Lexer::isIdentPart(c->uc))) { 209 param += UString(c, 1); 210 c++, i++; 211 } 212 while (i < len && *c == ' ') 213 c++, i++; 214 if (i == len) { 215 functionBody->parameters().append(Identifier(param)); 216 params++; 217 break; 218 } else if (*c == ',') { 219 functionBody->parameters().append(Identifier(param)); 220 params++; 221 c++, i++; 222 continue; 223 } // else error 224 } 225 return throwError(exec, SyntaxError, "Syntax error in parameter list"); 226 } 215 227 216 // parse parameter list. throw syntax error on illegal identifiers 217 int len = p.size(); 218 const UChar *c = p.data(); 219 int i = 0, params = 0; 220 UString param; 221 while (i < len) { 222 while (*c == ' ' && i < len) 223 c++, i++; 224 if (Lexer::isIdentStart(c->uc)) { // else error 225 param = UString(c, 1); 226 c++, i++; 227 while (i < len && (Lexer::isIdentPart(c->uc))) { 228 param += UString(c, 1); 229 c++, i++; 230 } 231 while (i < len && *c == ' ') 232 c++, i++; 233 if (i == len) { 234 functionBody->parameters().append(Identifier(param)); 235 params++; 236 break; 237 } else if (*c == ',') { 238 functionBody->parameters().append(Identifier(param)); 239 params++; 240 c++, i++; 241 continue; 242 } // else error 243 } 244 return throwError(exec, SyntaxError, "Syntax error in parameter list"); 245 } 246 247 List consArgs; 248 249 JSObject* objCons = exec->lexicalGlobalObject()->objectConstructor(); 250 JSObject* prototype = objCons->construct(exec, exec->emptyList()); 251 prototype->put(exec, exec->propertyNames().constructor, fimp, DontEnum|DontDelete|ReadOnly); 252 fimp->put(exec, exec->propertyNames().prototype, prototype, Internal|DontDelete); 253 return fimp; 228 List consArgs; 229 230 JSObject* objCons = exec->lexicalGlobalObject()->objectConstructor(); 231 JSObject* prototype = objCons->construct(exec, exec->emptyList()); 232 prototype->put(exec, exec->propertyNames().constructor, fimp, DontEnum | DontDelete | ReadOnly); 233 fimp->put(exec, exec->propertyNames().prototype, prototype, Internal | DontDelete); 234 return fimp; 254 235 } 255 236 … … 257 238 JSObject* FunctionObjectImp::construct(ExecState* exec, const List& args) 258 239 { 259 return construct(exec, args, "anonymous", UString(), 0);240 return construct(exec, args, "anonymous", UString(), 0); 260 241 } 261 242 262 243 // ECMA 15.3.1 The Function Constructor Called as a Function 263 JSValue* FunctionObjectImp::callAsFunction(ExecState* exec, JSObject* /*thisObj*/, const List &args) 264 { 265 return construct(exec, args); 266 } 244 JSValue* FunctionObjectImp::callAsFunction(ExecState* exec, JSObject*, const List& args) 245 { 246 return construct(exec, args); 247 } 248 249 } // namespace KJS -
trunk/JavaScriptCore/kjs/function_object.h
r21889 r29588 29 29 namespace KJS { 30 30 31 /**32 * @internal33 *34 * Class to implement all methods that are properties of the35 * Function.prototype object36 */37 class FunctionProtoFunc: public InternalFunctionImp {38 public:39 FunctionProtoFunc(ExecState*, FunctionPrototype*, int i, int len, const Identifier&);31 /** 32 * @internal 33 * 34 * The initial value of Function.prototype (and thus all objects created 35 * with the Function constructor) 36 */ 37 class FunctionPrototype : public InternalFunctionImp { 38 public: 39 FunctionPrototype(ExecState*); 40 40 41 virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); 41 virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&); 42 }; 42 43 43 enum { ToString, Apply, Call }; 44 private: 45 int id; 46 }; 44 /** 45 * @internal 46 * 47 * The initial value of the the global variable's "Function" property 48 */ 49 class FunctionObjectImp : public InternalFunctionImp { 50 public: 51 FunctionObjectImp(ExecState*, FunctionPrototype*); 47 52 48 /** 49 * @internal 50 * 51 * The initial value of the the global variable's "Function" property 52 */ 53 class FunctionObjectImp : public InternalFunctionImp { 54 public: 55 FunctionObjectImp(ExecState*, FunctionPrototype*); 56 virtual ~FunctionObjectImp(); 53 virtual bool implementsConstruct() const; 54 virtual JSObject* construct(ExecState*, const List&); 55 virtual JSObject* construct(ExecState*, const List&, const Identifier& functionName, const UString& sourceURL, int lineNumber); 56 virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&); 57 }; 57 58 58 virtual bool implementsConstruct() const; 59 virtual JSObject* construct(ExecState*, const List& args); 60 virtual JSObject* construct(ExecState*, const List& args, const Identifier& functionName, const UString& sourceURL, int lineNumber); 61 virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List& args); 62 }; 63 64 } // namespace 59 } // namespace KJS 65 60 66 61 #endif // _FUNCTION_OBJECT_H_ -
trunk/JavaScriptCore/kjs/number_object.cpp
r29036 r29588 42 42 { 43 43 } 44 44 45 // ------------------------------ NumberPrototype --------------------------- 45 46 47 static JSValue* numberProtoFuncToString(ExecState*, JSObject*, const List&); 48 static JSValue* numberProtoFuncToLocaleString(ExecState*, JSObject*, const List&); 49 static JSValue* numberProtoFuncValueOf(ExecState*, JSObject*, const List&); 50 static JSValue* numberProtoFuncToFixed(ExecState*, JSObject*, const List&); 51 static JSValue* numberProtoFuncToExponential(ExecState*, JSObject*, const List&); 52 static JSValue* numberProtoFuncToPrecision(ExecState*, JSObject*, const List&); 53 46 54 // ECMA 15.7.4 47 55 48 NumberPrototype::NumberPrototype(ExecState* exec, ObjectPrototype* obj Proto, FunctionPrototype* funcProto)49 : NumberInstance(obj Proto)56 NumberPrototype::NumberPrototype(ExecState* exec, ObjectPrototype* objectPrototype, FunctionPrototype* functionPrototype) 57 : NumberInstance(objectPrototype) 50 58 { 51 59 setInternalValue(jsNumber(0)); … … 53 61 // The constructor will be added later, after NumberObjectImp has been constructed 54 62 55 putDirectFunction(new NumberProtoFunc(exec, funcProto, NumberProtoFunc::ToString, 1, exec->propertyNames().toString), DontEnum); 56 putDirectFunction(new NumberProtoFunc(exec, funcProto, NumberProtoFunc::ToLocaleString, 0, exec->propertyNames().toLocaleString), DontEnum); 57 putDirectFunction(new NumberProtoFunc(exec, funcProto, NumberProtoFunc::ValueOf, 0, exec->propertyNames().valueOf), DontEnum); 58 putDirectFunction(new NumberProtoFunc(exec, funcProto, NumberProtoFunc::ToFixed, 1, exec->propertyNames().toFixed), DontEnum); 59 putDirectFunction(new NumberProtoFunc(exec, funcProto, NumberProtoFunc::ToExponential, 1, exec->propertyNames().toExponential), DontEnum); 60 putDirectFunction(new NumberProtoFunc(exec, funcProto, NumberProtoFunc::ToPrecision, 1, exec->propertyNames().toPrecision), DontEnum); 61 } 62 63 64 // ------------------------------ NumberProtoFunc --------------------------- 65 66 NumberProtoFunc::NumberProtoFunc(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name) 67 : InternalFunctionImp(funcProto, name) 68 , id(i) 69 { 70 putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum); 71 } 63 putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toString, numberProtoFuncToString), DontEnum); 64 putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toLocaleString, numberProtoFuncToLocaleString), DontEnum); 65 putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, numberProtoFuncValueOf), DontEnum); 66 putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toFixed, numberProtoFuncToFixed), DontEnum); 67 putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toExponential, numberProtoFuncToExponential), DontEnum); 68 putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toPrecision, numberProtoFuncToPrecision), DontEnum); 69 } 70 71 // ------------------------------ Functions --------------------------- 72 73 // ECMA 15.7.4.2 - 15.7.4.7 72 74 73 75 static UString integer_part_noexp(double d) … … 141 143 } 142 144 143 static JSValue* numberToString(ExecState* exec, JSValue* v, const List& args) 144 { 145 146 JSValue* numberProtoFuncToString(ExecState* exec, JSObject* thisObj, const List& args) 147 { 148 if (!thisObj->inherits(&NumberInstance::info)) 149 return throwError(exec, TypeError); 150 151 JSValue* v = static_cast<NumberInstance*>(thisObj)->internalValue(); 152 145 153 double radixAsDouble = args[0]->toInteger(exec); // nan -> 0 146 154 if (radixAsDouble == 10 || args[0]->isUndefined()) … … 201 209 } 202 210 203 static JSValue* numberToFixed(ExecState* exec, JSValue* v, const List& args) 204 { 211 JSValue* numberProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const List&) 212 { 213 if (!thisObj->inherits(&NumberInstance::info)) 214 return throwError(exec, TypeError); 215 216 // TODO 217 return jsString(static_cast<NumberInstance*>(thisObj)->internalValue()->toString(exec)); 218 } 219 220 JSValue* numberProtoFuncValueOf(ExecState* exec, JSObject* thisObj, const List&) 221 { 222 if (!thisObj->inherits(&NumberInstance::info)) 223 return throwError(exec, TypeError); 224 225 return static_cast<NumberInstance*>(thisObj)->internalValue()->toJSNumber(exec); 226 } 227 228 JSValue* numberProtoFuncToFixed(ExecState* exec, JSObject* thisObj, const List& args) 229 { 230 if (!thisObj->inherits(&NumberInstance::info)) 231 return throwError(exec, TypeError); 232 233 JSValue* v = static_cast<NumberInstance*>(thisObj)->internalValue(); 234 205 235 JSValue* fractionDigits = args[0]; 206 236 double df = fractionDigits->toInteger(exec); … … 282 312 } 283 313 284 static JSValue* numberToExponential(ExecState* exec, JSValue* v, const List& args) 285 { 314 JSValue* numberProtoFuncToExponential(ExecState* exec, JSObject* thisObj, const List& args) 315 { 316 if (!thisObj->inherits(&NumberInstance::info)) 317 return throwError(exec, TypeError); 318 319 JSValue* v = static_cast<NumberInstance*>(thisObj)->internalValue(); 320 286 321 double x = v->toNumber(exec); 287 322 … … 347 382 return jsString(buf); 348 383 } 349 350 static JSValue* numberToPrecision(ExecState* exec, JSValue* v, const List& args) 351 { 384 385 JSValue* numberProtoFuncToPrecision(ExecState* exec, JSObject* thisObj, const List& args) 386 { 387 if (!thisObj->inherits(&NumberInstance::info)) 388 return throwError(exec, TypeError); 389 390 JSValue* v = static_cast<NumberInstance*>(thisObj)->internalValue(); 391 352 392 double doublePrecision = args[0]->toIntegerPreserveNaN(exec); 353 393 double x = v->toNumber(exec); … … 408 448 } 409 449 return jsString(s + "0." + char_sequence('0', -(e + 1)) + m); 410 }411 412 // ECMA 15.7.4.2 - 15.7.4.7413 JSValue* NumberProtoFunc::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)414 {415 // no generic function. "this" has to be a Number object416 if (!thisObj->inherits(&NumberInstance::info))417 return throwError(exec, TypeError);418 419 JSValue* v = static_cast<NumberInstance*>(thisObj)->internalValue();420 switch (id) {421 case ToString:422 return numberToString(exec, v, args);423 case ToLocaleString: /* TODO */424 return jsString(v->toString(exec));425 case ValueOf:426 return v->toJSNumber(exec);427 case ToFixed:428 return numberToFixed(exec, v, args);429 case ToExponential:430 return numberToExponential(exec, v, args);431 case ToPrecision:432 return numberToPrecision(exec, v, args);433 }434 return 0;435 450 } 436 451 -
trunk/JavaScriptCore/kjs/number_object.h
r28907 r29588 28 28 namespace KJS { 29 29 30 class NumberInstance : public JSWrapperObject {31 public:32 NumberInstance(JSObject *proto);30 class NumberInstance : public JSWrapperObject { 31 public: 32 NumberInstance(JSObject* prototype); 33 33 34 virtual const ClassInfo *classInfo() const { return &info; }35 static const ClassInfo info;36 };34 virtual const ClassInfo* classInfo() const { return &info; } 35 static const ClassInfo info; 36 }; 37 37 38 /** 39 * @internal 40 * 41 * The initial value of Number.prototype (and thus all objects created 42 * with the Number constructor 43 */ 44 class NumberPrototype : public NumberInstance { 45 public: 46 NumberPrototype(ExecState *exec, 47 ObjectPrototype *objProto, 48 FunctionPrototype *funcProto); 49 }; 38 /** 39 * @internal 40 * 41 * The initial value of Number.prototype (and thus all objects created 42 * with the Number constructor 43 */ 44 class NumberPrototype : public NumberInstance { 45 public: 46 NumberPrototype(ExecState*, ObjectPrototype*, FunctionPrototype*); 47 }; 50 48 51 /** 52 * @internal 53 * 54 * Class to implement all methods that are properties of the 55 * Number.prototype object 56 */ 57 class NumberProtoFunc : public InternalFunctionImp { 58 public: 59 NumberProtoFunc(ExecState*, FunctionPrototype*, int i, int len, const Identifier&); 49 /** 50 * @internal 51 * 52 * The initial value of the the global variable's "Number" property 53 */ 54 class NumberObjectImp : public InternalFunctionImp { 55 public: 56 NumberObjectImp(ExecState*, FunctionPrototype*, NumberPrototype*); 60 57 61 virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); 58 virtual bool implementsConstruct() const; 59 virtual JSObject* construct(ExecState*, const List&); 62 60 63 enum { ToString, ToLocaleString, ValueOf, ToFixed, ToExponential, ToPrecision }; 64 private: 65 int id; 66 }; 61 virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&); 67 62 68 /** 69 * @internal 70 * 71 * The initial value of the the global variable's "Number" property 72 */ 73 class NumberObjectImp : public InternalFunctionImp { 74 public: 75 NumberObjectImp(ExecState *exec, 76 FunctionPrototype *funcProto, 77 NumberPrototype *numberProto); 63 bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 64 JSValue* getValueProperty(ExecState*, int token) const; 78 65 79 virtual bool implementsConstruct() const;80 virtual JSObject *construct(ExecState *exec, const List &args);66 virtual const ClassInfo* classInfo() const { return &info; } 67 static const ClassInfo info; 81 68 82 virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);69 enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue }; 83 70 84 bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);85 JSValue *getValueProperty(ExecState *exec, int token) const;71 JSObject* construct(const List&); 72 }; 86 73 87 virtual const ClassInfo *classInfo() const { return &info; } 88 static const ClassInfo info; 89 enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue }; 74 } // namespace KJS 90 75 91 JSObject *construct(const List &); 92 }; 93 94 } // namespace 95 96 #endif 76 #endif // NUMBER_OBJECT_H_ -
trunk/JavaScriptCore/kjs/object_object.cpp
r28884 r29588 1 // -*- c-basic-offset: 2 -*-2 1 /* 3 * This file is part of the KDE libraries4 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2008 Apple Inc. All rights reserved. 5 4 * 6 5 * This library is free software; you can redistribute it and/or … … 28 27 #include <stdio.h> 29 28 30 using namespace KJS; 29 namespace KJS { 31 30 32 31 // ------------------------------ ObjectPrototype -------------------------------- 33 32 34 ObjectPrototype::ObjectPrototype(ExecState* exec, FunctionPrototype* funcProto) 35 : JSObject() // [[Prototype]] is null 33 static JSValue* objectProtoFuncValueOf(ExecState*, JSObject*, const List&); 34 static JSValue* objectProtoFuncHasOwnProperty(ExecState*, JSObject*, const List&); 35 static JSValue* objectProtoFuncIsPrototypeOf(ExecState*, JSObject*, const List&); 36 static JSValue* objectProtoFuncDefineGetter(ExecState*, JSObject*, const List&); 37 static JSValue* objectProtoFuncDefineSetter(ExecState*, JSObject*, const List&); 38 static JSValue* objectProtoFuncLookupGetter(ExecState*, JSObject*, const List&); 39 static JSValue* objectProtoFuncLookupSetter(ExecState*, JSObject*, const List&); 40 static JSValue* objectProtoFuncPropertyIsEnumerable(ExecState*, JSObject*, const List&); 41 static JSValue* objectProtoFuncToLocaleString(ExecState*, JSObject*, const List&); 42 static JSValue* objectProtoFuncToString(ExecState*, JSObject*, const List&); 43 44 ObjectPrototype::ObjectPrototype(ExecState* exec, FunctionPrototype* functionPrototype) 45 : JSObject() // [[Prototype]] is null 36 46 { 37 47 static const Identifier* hasOwnPropertyPropertyName = new Identifier("hasOwnProperty"); … … 43 53 static const Identifier* lookupSetterPropertyName = new Identifier("__lookupSetter__"); 44 54 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); 51 61 52 62 // 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 -------------------------------- 69 71 70 72 // ECMA 15.2.4.2, 15.2.4.4, 15.2.4.5, 15.2.4.7 71 73 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 } 74 JSValue* objectProtoFuncValueOf(ExecState*, JSObject* thisObj, const List&) 75 { 76 return thisObj; 77 } 78 79 JSValue* objectProtoFuncHasOwnProperty(ExecState* exec, JSObject* thisObj, const List& args) 80 { 81 return jsBoolean(thisObj->hasOwnProperty(exec, Identifier(args[0]->toString(exec)))); 82 } 83 84 JSValue* 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 101 JSValue* 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 110 JSValue* 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 119 JSValue* 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; 95 132 } 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()) 110 135 return jsUndefined(); 136 obj = static_cast<JSObject*>(obj->prototype()); 137 } 138 } 139 140 JSValue* 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; 111 153 } 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()); 150 158 } 159 } 160 161 JSValue* objectProtoFuncPropertyIsEnumerable(ExecState* exec, JSObject* thisObj, const List& args) 162 { 163 return jsBoolean(thisObj->propertyIsEnumerable(exec, Identifier(args[0]->toString(exec)))); 164 } 165 166 JSValue* objectProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const List&) 167 { 168 return jsString(thisObj->toString(exec)); 169 } 170 171 JSValue* objectProtoFuncToString(ExecState*, JSObject* thisObj, const List&) 172 { 173 return jsString("[object " + thisObj->className() + "]"); 151 174 } 152 175 … … 193 216 } 194 217 218 } // namespace KJS -
trunk/JavaScriptCore/kjs/object_object.h
r21889 r29588 1 // -*- c-basic-offset: 2 -*-2 1 /* 3 * This file is part of the KDE libraries4 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2008 Apple Inc. All rights reserved. 5 4 * 6 5 * This library is free software; you can redistribute it and/or … … 27 26 namespace KJS { 28 27 29 class FunctionPrototype; 28 /** 29 * @internal 30 * 31 * The initial value of Object.prototype (and thus all objects created 32 * with the Object constructor 33 */ 34 class ObjectPrototype : public JSObject { 35 public: 36 ObjectPrototype(ExecState*, FunctionPrototype*); 37 }; 30 38 31 /** 32 * @internal 33 * 34 * The initial value of Object.prototype (and thus all objects created 35 * with the Object constructor 36 */ 37 class ObjectPrototype : public JSObject { 38 public: 39 ObjectPrototype(ExecState *exec, FunctionPrototype *funcProto); 40 }; 39 /** 40 * @internal 41 * 42 * The initial value of the the global variable's "Object" property 43 */ 44 class ObjectObjectImp : public InternalFunctionImp { 45 public: 46 ObjectObjectImp(ExecState*, ObjectPrototype*, FunctionPrototype*); 41 47 42 /** 43 * @internal 44 * 45 * Class to implement all methods that are properties of the 46 * Object.prototype object 47 */ 48 class ObjectProtoFunc : public InternalFunctionImp { 49 public: 50 ObjectProtoFunc(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier&); 48 virtual bool implementsConstruct() const; 49 virtual JSObject* construct(ExecState*, const List&); 50 virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&); 51 }; 51 52 52 virtual JSValue *callAsFunction(ExecState *, JSObject *, const List &args); 53 } // namespace KJS 53 54 54 enum { ToString, ToLocaleString, ValueOf, HasOwnProperty, IsPrototypeOf, PropertyIsEnumerable, 55 DefineGetter, DefineSetter, LookupGetter, LookupSetter }; 56 private: 57 int id; 58 }; 59 60 /** 61 * @internal 62 * 63 * The initial value of the the global variable's "Object" property 64 */ 65 class ObjectObjectImp : public InternalFunctionImp { 66 public: 67 68 ObjectObjectImp(ExecState *exec, 69 ObjectPrototype *objProto, 70 FunctionPrototype *funcProto); 71 72 virtual bool implementsConstruct() const; 73 virtual JSObject *construct(ExecState *, const List &args); 74 virtual JSValue *callAsFunction(ExecState *, JSObject *, const List &args); 75 }; 76 77 } // namespace 78 79 #endif 55 #endif // _OBJECT_OBJECT_H_ -
trunk/JavaScriptCore/kjs/regexp_object.cpp
r28476 r29588 1 1 /* 2 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2003, 2007 Apple Inc. All Rights Reserved.3 * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved. 4 4 * 5 5 * This library is free software; you can redistribute it and/or … … 40 40 // ------------------------------ RegExpPrototype --------------------------- 41 41 42 static JSValue* regExpProtoFuncTest(ExecState*, JSObject*, const List&); 43 static JSValue* regExpProtoFuncExec(ExecState*, JSObject*, const List&); 44 static JSValue* regExpProtoFuncCompile(ExecState*, JSObject*, const List&); 45 static JSValue* regExpProtoFuncToString(ExecState*, JSObject*, const List&); 46 42 47 // ECMA 15.10.5 43 48 44 49 const ClassInfo RegExpPrototype::info = { "RegExpPrototype", 0, 0 }; 45 50 46 RegExpPrototype::RegExpPrototype(ExecState *exec, 47 ObjectPrototype *objProto, 48 FunctionPrototype *funcProto) 49 : JSObject(objProto) 50 { 51 static const Identifier* compilePropertyName = new Identifier("compile"); 52 static const Identifier* execPropertyName = new Identifier("exec"); 53 static const Identifier* testPropertyName = new Identifier("test"); 54 55 putDirectFunction(new RegExpProtoFunc(exec, funcProto, RegExpProtoFunc::Compile, 0, *compilePropertyName), DontEnum); 56 putDirectFunction(new RegExpProtoFunc(exec, funcProto, RegExpProtoFunc::Exec, 0, *execPropertyName), DontEnum); 57 putDirectFunction(new RegExpProtoFunc(exec, funcProto, RegExpProtoFunc::Test, 0, *testPropertyName), DontEnum); 58 putDirectFunction(new RegExpProtoFunc(exec, funcProto, RegExpProtoFunc::ToString, 0, exec->propertyNames().toString), DontEnum); 59 } 60 61 // ------------------------------ RegExpProtoFunc --------------------------- 62 63 RegExpProtoFunc::RegExpProtoFunc(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name) 64 : InternalFunctionImp(funcProto, name), id(i) 65 { 66 putDirect(exec->propertyNames().length, len, DontDelete | ReadOnly | DontEnum); 67 } 68 69 JSValue *RegExpProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 70 { 71 if (!thisObj->inherits(&RegExpImp::info)) { 72 if (thisObj->inherits(&RegExpPrototype::info)) { 73 switch (id) { 74 case ToString: return jsString("//"); 75 } 76 } 51 RegExpPrototype::RegExpPrototype(ExecState* exec, ObjectPrototype* objectPrototype, FunctionPrototype* functionPrototype) 52 : JSObject(objectPrototype) 53 { 54 static const Identifier* compilePropertyName = new Identifier("compile"); 55 static const Identifier* execPropertyName = new Identifier("exec"); 56 static const Identifier* testPropertyName = new Identifier("test"); 57 58 putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, *compilePropertyName, regExpProtoFuncCompile), DontEnum); 59 putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, *execPropertyName, regExpProtoFuncExec), DontEnum); 60 putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, *testPropertyName, regExpProtoFuncTest), DontEnum); 61 putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, regExpProtoFuncToString), DontEnum); 62 } 63 64 // ------------------------------ Functions --------------------------- 77 65 78 return throwError(exec, TypeError); 79 } 80 81 switch (id) { 82 case Test: 83 return static_cast<RegExpImp*>(thisObj)->test(exec, args); 84 case Exec: 85 return static_cast<RegExpImp*>(thisObj)->exec(exec, args); 86 case Compile: 87 { 66 JSValue* regExpProtoFuncTest(ExecState* exec, JSObject* thisObj, const List& args) 67 { 68 if (!thisObj->inherits(&RegExpImp::info)) 69 return throwError(exec, TypeError); 70 71 return static_cast<RegExpImp*>(thisObj)->test(exec, args); 72 } 73 74 JSValue* regExpProtoFuncExec(ExecState* exec, JSObject* thisObj, const List& args) 75 { 76 if (!thisObj->inherits(&RegExpImp::info)) 77 return throwError(exec, TypeError); 78 79 return static_cast<RegExpImp*>(thisObj)->exec(exec, args); 80 } 81 82 JSValue* regExpProtoFuncCompile(ExecState* exec, JSObject* thisObj, const List& args) 83 { 84 if (!thisObj->inherits(&RegExpImp::info)) 85 return throwError(exec, TypeError); 86 88 87 RefPtr<RegExp> regExp; 89 88 JSValue* arg0 = args[0]; … … 91 90 92 91 if (arg0->isObject(&RegExpImp::info)) { 93 if (!arg1->isUndefined())94 return throwError(exec, TypeError, "Cannot supply flags when constructing one RegExp from another.");95 regExp = static_cast<RegExpImp*>(arg0)->regExp();92 if (!arg1->isUndefined()) 93 return throwError(exec, TypeError, "Cannot supply flags when constructing one RegExp from another."); 94 regExp = static_cast<RegExpImp*>(arg0)->regExp(); 96 95 } else { 97 UString pattern = args.isEmpty() ? UString("") : arg0->toString(exec);98 UString flags = arg1->isUndefined() ? UString("") : arg1->toString(exec);99 regExp = new RegExp(pattern, flags);96 UString pattern = args.isEmpty() ? UString("") : arg0->toString(exec); 97 UString flags = arg1->isUndefined() ? UString("") : arg1->toString(exec); 98 regExp = new RegExp(pattern, flags); 100 99 } 101 100 102 101 if (!regExp->isValid()) 103 return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));102 return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage())); 104 103 105 104 static_cast<RegExpImp*>(thisObj)->setRegExp(regExp.release()); 106 105 static_cast<RegExpImp*>(thisObj)->put(exec, exec->propertyNames().lastIndex, jsNumber(0), DontDelete|DontEnum); 107 106 return jsUndefined(); 108 } 109 case ToString: 107 } 108 109 JSValue* regExpProtoFuncToString(ExecState* exec, JSObject* thisObj, const List&) 110 { 111 if (!thisObj->inherits(&RegExpImp::info)) { 112 if (thisObj->inherits(&RegExpPrototype::info)) 113 return jsString("//"); 114 return throwError(exec, TypeError); 115 } 116 110 117 UString result = "/" + thisObj->get(exec, exec->propertyNames().source)->toString(exec) + "/"; 111 if (thisObj->get(exec, exec->propertyNames().global)->toBoolean(exec)) { 112 result += "g"; 113 } 114 if (thisObj->get(exec, exec->propertyNames().ignoreCase)->toBoolean(exec)) { 115 result += "i"; 116 } 117 if (thisObj->get(exec, exec->propertyNames().multiline)->toBoolean(exec)) { 118 result += "m"; 119 } 118 if (thisObj->get(exec, exec->propertyNames().global)->toBoolean(exec)) 119 result += "g"; 120 if (thisObj->get(exec, exec->propertyNames().ignoreCase)->toBoolean(exec)) 121 result += "i"; 122 if (thisObj->get(exec, exec->propertyNames().multiline)->toBoolean(exec)) 123 result += "m"; 120 124 return jsString(result); 121 } 122 123 return jsUndefined(); 125 126 return jsUndefined(); 124 127 } 125 128 -
trunk/JavaScriptCore/kjs/regexp_object.h
r27702 r29588 1 1 /* 2 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2003, 2007 Apple Inc. All Rights Reserved.3 * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved. 4 4 * 5 5 * This library is free software; you can redistribute it and/or … … 32 32 public: 33 33 RegExpPrototype(ExecState*, ObjectPrototype*, FunctionPrototype*); 34 34 35 virtual const ClassInfo* classInfo() const { return &info; } 35 36 static const ClassInfo info; 36 };37 38 class RegExpProtoFunc : public InternalFunctionImp {39 public:40 enum { Compile, Exec, Test, ToString };41 42 RegExpProtoFunc(ExecState*, FunctionPrototype*, int id, int len, const Identifier&);43 virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&);44 45 private:46 int id;47 37 }; 48 38
Note: See TracChangeset
for help on using the changeset viewer.