Changeset 34854 in webkit for trunk/JavaScriptCore/kjs


Ignore:
Timestamp:
Jun 28, 2008, 2:22:01 PM (17 years ago)
Author:
[email protected]
Message:

JavaScriptCore:

2008-06-28 Sam Weinig <[email protected]>

Rubber-stamped by Oliver Hunt.

Splits FunctionConstructor out of FunctionPrototype.h/cpp
Splits NumberConstructor and NumberPrototype out of NumberObject.h/cpp
Rename object_object.h/cpp to ObjectPrototype.h/cpp and split out ObjectConstructor.

  • API/JSCallbackConstructor.cpp:
  • API/JSClassRef.cpp:
  • API/JSObjectRef.cpp:
  • DerivedSources.make:
  • GNUmakefile.am:
  • JavaScriptCore.pri:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • JavaScriptCoreSources.bkl:
  • VM/Machine.cpp:
  • kjs/AllInOneFile.cpp:
  • kjs/ArrayConstructor.cpp:
  • kjs/ArrayConstructor.h:
  • kjs/FunctionConstructor.cpp: Copied from JavaScriptCore/kjs/FunctionPrototype.cpp.
  • kjs/FunctionConstructor.h: Copied from JavaScriptCore/kjs/FunctionPrototype.h.
  • kjs/FunctionPrototype.cpp:
  • kjs/FunctionPrototype.h:
  • kjs/JSFunction.cpp:
  • kjs/JSGlobalObject.cpp:
  • kjs/JSImmediate.cpp:
  • kjs/MathObject.h:
  • kjs/NumberConstructor.cpp: Copied from JavaScriptCore/kjs/NumberObject.cpp.
  • kjs/NumberConstructor.h: Copied from JavaScriptCore/kjs/NumberObject.h.
  • kjs/NumberObject.cpp:
  • kjs/NumberObject.h:
  • kjs/NumberPrototype.cpp: Copied from JavaScriptCore/kjs/NumberObject.cpp.
  • kjs/NumberPrototype.h: Copied from JavaScriptCore/kjs/NumberObject.h.
  • kjs/ObjectConstructor.cpp: Copied from JavaScriptCore/kjs/object_object.cpp.
  • kjs/ObjectConstructor.h: Copied from JavaScriptCore/kjs/object_object.h.
  • kjs/ObjectPrototype.cpp: Copied from JavaScriptCore/kjs/object_object.cpp.
  • kjs/ObjectPrototype.h: Copied from JavaScriptCore/kjs/object_object.h.
  • kjs/RegExpObject.h:
  • kjs/Shell.cpp:
  • kjs/error_object.h:
  • kjs/internal.cpp:
  • kjs/nodes.cpp:
  • kjs/object_object.cpp: Removed.
  • kjs/object_object.h: Removed.
  • kjs/string_object.h:

WebCore:

2008-06-28 Sam Weinig <[email protected]>

Rubber-stamped by Oliver Hunt.

Update includes after remaming object_object.h to ObjectPrototype.h and
splitting FunctionConstructor out of FunctionPrototype.h

  • ForwardingHeaders/kjs/FunctionConstructor.h: Added.
  • ForwardingHeaders/kjs/ObjectPrototype.h: Copied from WebCore/ForwardingHeaders/kjs/object_object.h.
  • ForwardingHeaders/kjs/object_object.h: Removed.
  • bindings/js/JSEventListener.cpp:
  • bindings/scripts/CodeGeneratorJS.pm:
  • bridge/qt/qt_instance.cpp:
Location:
trunk/JavaScriptCore/kjs
Files:
17 edited
8 copied
2 moved

Legend:

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

    r34843 r34854  
    4444#include "dtoa.cpp"
    4545#include "error_object.cpp"
     46#include "FunctionConstructor.cpp"
    4647#include "FunctionPrototype.cpp"
    4748#include "grammar.cpp"
     
    5859#include "nodes.cpp"
    5960#include "nodes2string.cpp"
     61#include "NumberConstructor.cpp"
    6062#include "NumberObject.cpp"
     63#include "NumberPrototype.cpp"
    6164#include "JSObject.cpp"
    6265#include "JSGlobalObject.cpp"
    63 #include "object_object.cpp"
     66#include "ObjectConstructor.cpp"
     67#include "ObjectPrototype.cpp"
    6468#include "operations.cpp"
    6569#include "Parser.cpp"
     
    7377#include "ustring.cpp"
    7478#include "JSValue.cpp"
     79#include "JSVariableObject.cpp"
    7580#include "wtf/FastMalloc.cpp"
    7681#include "wtf/TCSystemAlloc.cpp"
  • trunk/JavaScriptCore/kjs/ArrayConstructor.cpp

    r34843 r34854  
    2626
    2727#include "ArrayPrototype.h"
     28#include "FunctionPrototype.h"
    2829#include "JSArray.h"
    2930#include "error_object.h"
  • trunk/JavaScriptCore/kjs/ArrayConstructor.h

    r34843 r34854  
    2222#define ArrayConstructor_h
    2323
    24 #include "FunctionPrototype.h"
     24#include "JSFunction.h"
    2525
    2626namespace KJS {
    2727
    2828  class ArrayPrototype;
     29  class FunctionPrototype;
    2930
    3031  class ArrayConstructor : public InternalFunction {
  • trunk/JavaScriptCore/kjs/FunctionConstructor.cpp

    r34853 r34854  
    2020
    2121#include "config.h"
     22#include "FunctionConstructor.h"
     23
    2224#include "FunctionPrototype.h"
    23 
     25#include "JSFunction.h"
    2426#include "JSGlobalObject.h"
     27#include "JSString.h"
    2528#include "Parser.h"
    2629#include "debugger.h"
    27 #include "JSArray.h"
    28 #include "JSFunction.h"
    29 #include "JSString.h"
    3030#include "lexer.h"
    3131#include "nodes.h"
    32 #include "JSObject.h"
    33 #include <stdio.h>
    34 #include <string.h>
    35 #include <wtf/Assertions.h>
    3632
    3733namespace KJS {
    38 
    39 // ------------------------------ FunctionPrototype -------------------------
    40 
    41 static JSValue* functionProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
    42 static JSValue* functionProtoFuncApply(ExecState*, JSObject*, JSValue*, const ArgList&);
    43 static JSValue* functionProtoFuncCall(ExecState*, JSObject*, JSValue*, const ArgList&);
    44 
    45 FunctionPrototype::FunctionPrototype(ExecState* exec)
    46 {
    47     putDirect(exec->propertyNames().length, jsNumber(exec, 0), DontDelete | ReadOnly | DontEnum);
    48 
    49     putDirectFunction(new (exec) PrototypeFunction(exec, this, 0, exec->propertyNames().toString, functionProtoFuncToString), DontEnum);
    50     putDirectFunction(new (exec) PrototypeFunction(exec, this, 2, exec->propertyNames().apply, functionProtoFuncApply), DontEnum);
    51     putDirectFunction(new (exec) PrototypeFunction(exec, this, 1, exec->propertyNames().call, functionProtoFuncCall), DontEnum);
    52 }
    53 
    54 static JSValue* callFunctionPrototype(ExecState*, JSObject*, JSValue*, const ArgList&)
    55 {
    56     return jsUndefined();
    57 }
    58 
    59 // ECMA 15.3.4
    60 CallType FunctionPrototype::getCallData(CallData& callData)
    61 {
    62     callData.native.function = callFunctionPrototype;
    63     return CallTypeNative;
    64 }
    65 
    66 // Functions
    67 
    68 JSValue* functionProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    69 {
    70     if (!thisValue->isObject(&InternalFunction::info))
    71         return throwError(exec, TypeError);
    72 
    73     InternalFunction* function = static_cast<InternalFunction*>(thisValue);
    74 
    75     if (function->inherits(&JSFunction::info)) {
    76         JSFunction* fi = static_cast<JSFunction*>(thisValue);
    77         return jsString(exec, "function " + fi->functionName().ustring() + "(" + fi->body->paramString() + ") " + fi->body->toSourceString());
    78     }
    79 
    80     return jsString(exec, "function " + function->functionName().ustring() + "() {\n    [native code]\n}");
    81 }
    82 
    83 JSValue* functionProtoFuncApply(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    84 {
    85     CallData callData;
    86     CallType callType = thisValue->getCallData(callData);
    87     if (callType == CallTypeNone)
    88         return throwError(exec, TypeError);
    89 
    90     JSValue* thisArg = args[0];
    91     JSValue* argArray = args[1];
    92 
    93     JSValue* applyThis;
    94     if (thisArg->isUndefinedOrNull())
    95         applyThis = exec->globalThisValue();
    96     else
    97         applyThis = thisArg->toObject(exec);
    98 
    99     ArgList applyArgs;
    100     if (!argArray->isUndefinedOrNull()) {
    101         if (argArray->isObject() &&
    102             (static_cast<JSObject*>(argArray)->inherits(&JSArray::info) ||
    103              static_cast<JSObject*>(argArray)->inherits(&Arguments::info))) {
    104 
    105             JSObject* argArrayObj = static_cast<JSObject*>(argArray);
    106             unsigned int length = argArrayObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
    107             for (unsigned int i = 0; i < length; i++)
    108                 applyArgs.append(argArrayObj->get(exec, i));
    109         } else
    110             return throwError(exec, TypeError);
    111     }
    112 
    113     return call(exec, thisValue, callType, callData, applyThis, applyArgs);
    114 }
    115 
    116 JSValue* functionProtoFuncCall(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    117 {
    118     CallData callData;
    119     CallType callType = thisValue->getCallData(callData);
    120     if (callType == CallTypeNone)
    121         return throwError(exec, TypeError);
    122 
    123     JSValue* thisArg = args[0];
    124 
    125     JSObject* callThis;
    126     if (thisArg->isUndefinedOrNull())
    127         callThis = exec->globalThisValue();
    128     else
    129         callThis = thisArg->toObject(exec);
    130 
    131     ArgList argsTail;
    132     args.getSlice(1, argsTail);
    133     return call(exec, thisValue, callType, callData, callThis, argsTail);
    134 }
    135 
    136 // ------------------------------ FunctionConstructor ----------------------------
    13734
    13835FunctionConstructor::FunctionConstructor(ExecState* exec, FunctionPrototype* functionPrototype)
  • trunk/JavaScriptCore/kjs/FunctionConstructor.h

    r34853 r34854  
    2121 */
    2222
    23 #ifndef FunctionPrototype_h
    24 #define FunctionPrototype_h
     23#ifndef FunctionConstructor_h
     24#define FunctionConstructor_h
    2525
    26 #include "object_object.h"
    2726#include "JSFunction.h"
    2827
    2928namespace KJS {
    3029
    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 InternalFunction {
    38     public:
    39         FunctionPrototype(ExecState*);
    40     private:
    41         virtual CallType getCallData(CallData&);
    42     };
     30    class FunctionPrototype;
    4331
    4432    /**
     
    6048} // namespace KJS
    6149
    62 #endif // _FUNCTION_OBJECT_H_
     50#endif // FunctionConstructor_h
  • trunk/JavaScriptCore/kjs/FunctionPrototype.cpp

    r34844 r34854  
    2222#include "FunctionPrototype.h"
    2323
    24 #include "JSGlobalObject.h"
    25 #include "Parser.h"
    26 #include "debugger.h"
    27 #include "JSArray.h"
    28 #include "JSFunction.h"
    2924#include "JSString.h"
    30 #include "lexer.h"
    31 #include "nodes.h"
    32 #include "JSObject.h"
    33 #include <stdio.h>
    34 #include <string.h>
    35 #include <wtf/Assertions.h>
    3625
    3726namespace KJS {
    38 
    39 // ------------------------------ FunctionPrototype -------------------------
    4027
    4128static JSValue* functionProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
     
    134121}
    135122
    136 // ------------------------------ FunctionConstructor ----------------------------
    137 
    138 FunctionConstructor::FunctionConstructor(ExecState* exec, FunctionPrototype* functionPrototype)
    139     : InternalFunction(functionPrototype, Identifier(exec, functionPrototype->classInfo()->className))
    140 {
    141     putDirect(exec->propertyNames().prototype, functionPrototype, DontEnum | DontDelete | ReadOnly);
    142 
    143     // Number of arguments for constructor
    144     putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontDelete | DontEnum);
    145 }
    146 
    147 static JSObject* constructWithFunctionConstructor(ExecState* exec, JSObject*, const ArgList& args)
    148 {
    149     return constructFunction(exec, args);
    150 }
    151 
    152 ConstructType FunctionConstructor::getConstructData(ConstructData& constructData)
    153 {
    154     constructData.native.function = constructWithFunctionConstructor;
    155     return ConstructTypeNative;
    156 }
    157 
    158 static JSValue* callFunctionConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    159 {
    160     return constructFunction(exec, args);
    161 }
    162 
    163 // ECMA 15.3.1 The Function Constructor Called as a Function
    164 CallType FunctionConstructor::getCallData(CallData& callData)
    165 {
    166     callData.native.function = callFunctionConstructor;
    167     return CallTypeNative;
    168 }
    169 
    170 // ECMA 15.3.2 The Function Constructor
    171 JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber)
    172 {
    173     UString p("");
    174     UString body;
    175     int argsSize = args.size();
    176     if (argsSize == 0)
    177         body = "";
    178     else if (argsSize == 1)
    179         body = args[0]->toString(exec);
    180     else {
    181         p = args[0]->toString(exec);
    182         for (int k = 1; k < argsSize - 1; k++)
    183             p += "," + args[k]->toString(exec);
    184         body = args[argsSize - 1]->toString(exec);
    185     }
    186 
    187     // parse the source code
    188     int sourceId;
    189     int errLine;
    190     UString errMsg;
    191     RefPtr<SourceProvider> source = UStringSourceProvider::create(body);
    192     RefPtr<FunctionBodyNode> functionBody = exec->parser()->parse<FunctionBodyNode>(exec, sourceURL, lineNumber, source, &sourceId, &errLine, &errMsg);
    193 
    194     // No program node == syntax error - throw a syntax error
    195     if (!functionBody)
    196         // We can't return a Completion(Throw) here, so just set the exception
    197         // and return it
    198         return throwError(exec, SyntaxError, errMsg, errLine, sourceId, sourceURL);
    199    
    200     functionBody->setSource(SourceRange(source, 0, source->length()));
    201     ScopeChain scopeChain(exec->lexicalGlobalObject(), exec->globalThisValue());
    202 
    203     JSFunction* function = new (exec) JSFunction(exec, functionName, functionBody.get(), scopeChain.node());
    204 
    205     // parse parameter list. throw syntax error on illegal identifiers
    206     int len = p.size();
    207     const UChar* c = p.data();
    208     int i = 0, params = 0;
    209     UString param;
    210     while (i < len) {
    211         while (*c == ' ' && i < len)
    212             c++, i++;
    213         if (Lexer::isIdentStart(c[0])) {  // else error
    214             param = UString(c, 1);
    215             c++, i++;
    216             while (i < len && (Lexer::isIdentPart(c[0]))) {
    217                 param.append(*c);
    218                 c++, i++;
    219             }
    220             while (i < len && *c == ' ')
    221                 c++, i++;
    222             if (i == len) {
    223                 functionBody->parameters().append(Identifier(exec, param));
    224                 params++;
    225                 break;
    226             } else if (*c == ',') {
    227                 functionBody->parameters().append(Identifier(exec, param));
    228                 params++;
    229                 c++, i++;
    230                 continue;
    231             } // else error
    232         }
    233         return throwError(exec, SyntaxError, "Syntax error in parameter list");
    234     }
    235  
    236     JSObject* prototype = constructEmptyObject(exec);
    237     prototype->putDirect(exec->propertyNames().constructor, function, DontEnum);
    238     function->putDirect(exec->propertyNames().prototype, prototype, DontDelete);
    239     return function;
    240 }
    241 
    242 // ECMA 15.3.2 The Function Constructor
    243 JSObject* constructFunction(ExecState* exec, const ArgList& args)
    244 {
    245     return constructFunction(exec, args, Identifier(exec, "anonymous"), UString(), 1);
    246 }
    247 
    248123} // namespace KJS
  • trunk/JavaScriptCore/kjs/FunctionPrototype.h

    r34754 r34854  
    2424#define FunctionPrototype_h
    2525
    26 #include "object_object.h"
    2726#include "JSFunction.h"
    2827
     
    4241    };
    4342
    44     /**
    45      * @internal
    46      *
    47      * The initial value of the the global variable's "Function" property
    48      */
    49     class FunctionConstructor : public InternalFunction {
    50     public:
    51         FunctionConstructor(ExecState*, FunctionPrototype*);
    52     private:
    53         virtual ConstructType getConstructData(ConstructData&);
    54         virtual CallType getCallData(CallData&);
    55     };
    56 
    57     JSObject* constructFunction(ExecState*, const ArgList&, const Identifier& functionName, const UString& sourceURL, int lineNumber);
    58     JSObject* constructFunction(ExecState*, const ArgList&);
    59 
    6043} // namespace KJS
    6144
    62 #endif // _FUNCTION_OBJECT_H_
     45#endif // FunctionPrototype_h
  • trunk/JavaScriptCore/kjs/JSFunction.cpp

    r34838 r34854  
    2828
    2929#include "ExecState.h"
     30#include "FunctionPrototype.h"
    3031#include "JSActivation.h"
    3132#include "JSGlobalObject.h"
     33#include "JSString.h"
    3234#include "Machine.h"
     35#include "ObjectPrototype.h"
    3336#include "Parser.h"
    3437#include "PropertyNameArray.h"
     38#include "ScopeChainMark.h"
    3539#include "debugger.h"
    3640#include "dtoa.h"
    37 #include "FunctionPrototype.h"
    38 #include "JSString.h"
    3941#include "lexer.h"
    4042#include "nodes.h"
    4143#include "operations.h"
    42 #include "ScopeChainMark.h"
    4344#include <errno.h>
    4445#include <profiler/Profiler.h>
  • trunk/JavaScriptCore/kjs/JSGlobalObject.cpp

    r34843 r34854  
    3131#include "JSGlobalObject.h"
    3232
     33#include "ArrayConstructor.h"
     34#include "ArrayPrototype.h"
     35#include "BooleanConstructor.h"
     36#include "BooleanPrototype.h"
    3337#include "CodeBlock.h"
    34 #include "ArrayPrototype.h"
    35 #include "ArrayConstructor.h"
    36 #include "BooleanPrototype.h"
    37 #include "BooleanConstructor.h"
     38#include "FunctionConstructor.h"
     39#include "FunctionPrototype.h"
     40#include "Machine.h"
     41#include "MathObject.h"
     42#include "NumberConstructor.h"
     43#include "NumberPrototype.h"
     44#include "ObjectConstructor.h"
     45#include "ObjectPrototype.h"
     46#include "RegExpObject.h"
     47#include "ScopeChainMark.h"
    3848#include "date_object.h"
    3949#include "debugger.h"
    4050#include "error_object.h"
    41 #include "FunctionPrototype.h"
    42 #include "Machine.h"
    43 #include "MathObject.h"
    44 #include "NumberObject.h"
    45 #include "object_object.h"
    46 #include "RegExpObject.h"
    47 #include "ScopeChainMark.h"
    4851#include "string_object.h"
    4952
  • trunk/JavaScriptCore/kjs/JSImmediate.cpp

    r34843 r34854  
    2525#include "JSGlobalObject.h"
    2626#include "JSNotAnObject.h"
    27 #include "NumberObject.h"
     27#include "NumberPrototype.h"
    2828
    2929namespace KJS {
  • trunk/JavaScriptCore/kjs/MathObject.h

    r34754 r34854  
    2121#define MathObject_h
    2222
    23 #include "FunctionPrototype.h"
     23#include "JSObject.h"
    2424#include "lookup.h"
    2525
  • trunk/JavaScriptCore/kjs/NumberConstructor.cpp

    r34853 r34854  
    2121
    2222#include "config.h"
     23#include "NumberConstructor.h"
     24#include "NumberConstructor.lut.h"
     25
    2326#include "NumberObject.h"
    24 #include "NumberObject.lut.h"
    25 
    26 #include "dtoa.h"
    27 #include "error_object.h"
    28 #include "operations.h"
    29 #include <wtf/Assertions.h>
    30 #include <wtf/MathExtras.h>
    31 #include <wtf/Vector.h>
     27#include "NumberPrototype.h"
    3228
    3329namespace KJS {
    3430
    35 // ------------------------------ NumberObject ----------------------------
    36 
    37 const ClassInfo NumberObject::info = { "Number", 0, 0, 0 };
    38 
    39 NumberObject::NumberObject(JSObject* proto)
    40     : JSWrapperObject(proto)
    41 {
    42 }
    43 
    44 JSValue* NumberObject::getJSNumber()
    45 {
    46     return internalValue();
    47 }
    48 
    49 // ------------------------------ NumberPrototype ---------------------------
    50 
    51 static JSValue* numberProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
    52 static JSValue* numberProtoFuncToLocaleString(ExecState*, JSObject*, JSValue*, const ArgList&);
    53 static JSValue* numberProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
    54 static JSValue* numberProtoFuncToFixed(ExecState*, JSObject*, JSValue*, const ArgList&);
    55 static JSValue* numberProtoFuncToExponential(ExecState*, JSObject*, JSValue*, const ArgList&);
    56 static JSValue* numberProtoFuncToPrecision(ExecState*, JSObject*, JSValue*, const ArgList&);
    57 
    58 // ECMA 15.7.4
    59 
    60 NumberPrototype::NumberPrototype(ExecState* exec, ObjectPrototype* objectPrototype, FunctionPrototype* functionPrototype)
    61     : NumberObject(objectPrototype)
    62 {
    63     setInternalValue(jsNumber(exec, 0));
    64 
    65     // The constructor will be added later, after NumberConstructor has been constructed
    66 
    67     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toString, numberProtoFuncToString), DontEnum);
    68     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toLocaleString, numberProtoFuncToLocaleString), DontEnum);
    69     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, numberProtoFuncValueOf), DontEnum);
    70     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toFixed, numberProtoFuncToFixed), DontEnum);
    71     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toExponential, numberProtoFuncToExponential), DontEnum);
    72     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toPrecision, numberProtoFuncToPrecision), DontEnum);
    73 }
    74 
    75 // ------------------------------ Functions ---------------------------
    76 
    77 // ECMA 15.7.4.2 - 15.7.4.7
    78 
    79 static UString integer_part_noexp(double d)
    80 {
    81     int decimalPoint;
    82     int sign;
    83     char* result = dtoa(d, 0, &decimalPoint, &sign, NULL);
    84     bool resultIsInfOrNan = (decimalPoint == 9999);
    85     size_t length = strlen(result);
    86 
    87     UString str = sign ? "-" : "";
    88     if (resultIsInfOrNan)
    89         str += result;
    90     else if (decimalPoint <= 0)
    91         str += "0";
    92     else {
    93         Vector<char, 1024> buf(decimalPoint + 1);
    94 
    95         if (static_cast<int>(length) <= decimalPoint) {
    96             strcpy(buf.data(), result);
    97             memset(buf.data() + length, '0', decimalPoint - length);
    98         } else
    99             strncpy(buf.data(), result, decimalPoint);
    100 
    101         buf[decimalPoint] = '\0';
    102         str.append(buf.data());
    103     }
    104 
    105     freedtoa(result);
    106 
    107     return str;
    108 }
    109 
    110 static UString char_sequence(char c, int count)
    111 {
    112     Vector<char, 2048> buf(count + 1, c);
    113     buf[count] = '\0';
    114 
    115     return UString(buf.data());
    116 }
    117 
    118 static double intPow10(int e)
    119 {
    120     // This function uses the "exponentiation by squaring" algorithm and
    121     // long double to quickly and precisely calculate integer powers of 10.0.
    122 
    123     // This is a handy workaround for <rdar://problem/4494756>
    124 
    125     if (e == 0)
    126         return 1.0;
    127 
    128     bool negative = e < 0;
    129     unsigned exp = negative ? -e : e;
    130 
    131     long double result = 10.0;
    132     bool foundOne = false;
    133     for (int bit = 31; bit >= 0; bit--) {
    134         if (!foundOne) {
    135             if ((exp >> bit) & 1)
    136                 foundOne = true;
    137         } else {
    138             result = result * result;
    139             if ((exp >> bit) & 1)
    140                 result = result * 10.0;
    141         }
    142     }
    143 
    144     if (negative)
    145         return static_cast<double>(1.0 / result);
    146     return static_cast<double>(result);
    147 }
    148 
    149 
    150 JSValue* numberProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    151 {
    152     JSValue* v = thisValue->getJSNumber();
    153     if (!v)
    154         return throwError(exec, TypeError);
    155 
    156     double radixAsDouble = args[0]->toInteger(exec); // nan -> 0
    157     if (radixAsDouble == 10 || args[0]->isUndefined())
    158         return jsString(exec, v->toString(exec));
    159 
    160     if (radixAsDouble < 2 || radixAsDouble > 36)
    161         return throwError(exec, RangeError, "toString() radix argument must be between 2 and 36");
    162 
    163     int radix = static_cast<int>(radixAsDouble);
    164     const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
    165     // INT_MAX results in 1024 characters left of the dot with radix 2
    166     // give the same space on the right side. safety checks are in place
    167     // unless someone finds a precise rule.
    168     char s[2048 + 3];
    169     const char* lastCharInString = s + sizeof(s) - 1;
    170     double x = v->uncheckedGetNumber();
    171     if (isnan(x) || isinf(x))
    172         return jsString(exec, UString::from(x));
    173 
    174     bool isNegative = x < 0.0;
    175     if (isNegative)
    176         x = -x;
    177 
    178     double integerPart = floor(x);
    179     char* decimalPoint = s + sizeof(s) / 2;
    180 
    181     // convert integer portion
    182     char* p = decimalPoint;
    183     double d = integerPart;
    184     do {
    185         int remainderDigit = static_cast<int>(fmod(d, radix));
    186         *--p = digits[remainderDigit];
    187         d /= radix;
    188     } while ((d <= -1.0 || d >= 1.0) && s < p);
    189 
    190     if (isNegative)
    191         *--p = '-';
    192     char* startOfResultString = p;
    193     ASSERT(s <= startOfResultString);
    194 
    195     d = x - integerPart;
    196     p = decimalPoint;
    197     const double epsilon = 0.001; // TODO: guessed. base on radix ?
    198     bool hasFractionalPart = (d < -epsilon || d > epsilon);
    199     if (hasFractionalPart) {
    200         *p++ = '.';
    201         do {
    202             d *= radix;
    203             const int digit = static_cast<int>(d);
    204             *p++ = digits[digit];
    205             d -= digit;
    206         } while ((d < -epsilon || d > epsilon) && p < lastCharInString);
    207     }
    208     *p = '\0';
    209     ASSERT(p < s + sizeof(s));
    210 
    211     return jsString(exec, startOfResultString);
    212 }
    213 
    214 JSValue* numberProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    215 {
    216     // FIXME: Not implemented yet.
    217 
    218     JSValue* v = thisValue->getJSNumber();
    219     if (!v)
    220         return throwError(exec, TypeError);
    221 
    222     return jsString(exec, v->toString(exec));
    223 }
    224 
    225 JSValue* numberProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    226 {
    227     JSValue* v = thisValue->getJSNumber();
    228     if (!v)
    229         return throwError(exec, TypeError);
    230 
    231     return v;
    232 }
    233 
    234 JSValue* numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    235 {
    236     JSValue* v = thisValue->getJSNumber();
    237     if (!v)
    238         return throwError(exec, TypeError);
    239 
    240     JSValue* fractionDigits = args[0];
    241     double df = fractionDigits->toInteger(exec);
    242     if (!(df >= 0 && df <= 20))
    243         return throwError(exec, RangeError, "toFixed() digits argument must be between 0 and 20");
    244     int f = (int)df;
    245 
    246     double x = v->uncheckedGetNumber();
    247     if (isnan(x))
    248         return jsString(exec, "NaN");
    249 
    250     UString s;
    251     if (x < 0) {
    252         s.append('-');
    253         x = -x;
    254     } else if (x == -0.0)
    255         x = 0;
    256 
    257     if (x >= pow(10.0, 21.0))
    258         return jsString(exec, s + UString::from(x));
    259 
    260     const double tenToTheF = pow(10.0, f);
    261     double n = floor(x * tenToTheF);
    262     if (fabs(n / tenToTheF - x) >= fabs((n + 1) / tenToTheF - x))
    263         n++;
    264 
    265     UString m = integer_part_noexp(n);
    266 
    267     int k = m.size();
    268     if (k <= f) {
    269         UString z;
    270         for (int i = 0; i < f + 1 - k; i++)
    271             z.append('0');
    272         m = z + m;
    273         k = f + 1;
    274         ASSERT(k == m.size());
    275     }
    276     int kMinusf = k - f;
    277     if (kMinusf < m.size())
    278         return jsString(exec, s + m.substr(0, kMinusf) + "." + m.substr(kMinusf));
    279     return jsString(exec, s + m.substr(0, kMinusf));
    280 }
    281 
    282 static void fractionalPartToString(char* buf, int& i, const char* result, int resultLength, int fractionalDigits)
    283 {
    284     if (fractionalDigits <= 0)
    285         return;
    286 
    287     int fDigitsInResult = static_cast<int>(resultLength) - 1;
    288     buf[i++] = '.';
    289     if (fDigitsInResult > 0) {
    290         if (fractionalDigits < fDigitsInResult) {
    291             strncpy(buf + i, result + 1, fractionalDigits);
    292             i += fractionalDigits;
    293         } else {
    294             strcpy(buf + i, result + 1);
    295             i += static_cast<int>(resultLength) - 1;
    296         }
    297     }
    298 
    299     for (int j = 0; j < fractionalDigits - fDigitsInResult; j++)
    300         buf[i++] = '0';
    301 }
    302 
    303 static void exponentialPartToString(char* buf, int& i, int decimalPoint)
    304 {
    305     buf[i++] = 'e';
    306     buf[i++] = (decimalPoint >= 0) ? '+' : '-';
    307     // decimalPoint can't be more than 3 digits decimal given the
    308     // nature of float representation
    309     int exponential = decimalPoint - 1;
    310     if (exponential < 0)
    311         exponential *= -1;
    312     if (exponential >= 100)
    313         buf[i++] = static_cast<char>('0' + exponential / 100);
    314     if (exponential >= 10)
    315         buf[i++] = static_cast<char>('0' + (exponential % 100) / 10);
    316     buf[i++] = static_cast<char>('0' + exponential % 10);
    317 }
    318 
    319 JSValue* numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    320 {
    321     JSValue* v = thisValue->getJSNumber();
    322     if (!v)
    323         return throwError(exec, TypeError);
    324 
    325     double x = v->uncheckedGetNumber();
    326 
    327     if (isnan(x) || isinf(x))
    328         return jsString(exec, UString::from(x));
    329 
    330     JSValue* fractionalDigitsValue = args[0];
    331     double df = fractionalDigitsValue->toInteger(exec);
    332     if (!(df >= 0 && df <= 20))
    333         return throwError(exec, RangeError, "toExponential() argument must between 0 and 20");
    334     int fractionalDigits = (int)df;
    335     bool includeAllDigits = fractionalDigitsValue->isUndefined();
    336 
    337     int decimalAdjust = 0;
    338     if (x && !includeAllDigits) {
    339         double logx = floor(log10(fabs(x)));
    340         x /= pow(10.0, logx);
    341         const double tenToTheF = pow(10.0, fractionalDigits);
    342         double fx = floor(x * tenToTheF) / tenToTheF;
    343         double cx = ceil(x * tenToTheF) / tenToTheF;
    344 
    345         if (fabs(fx - x) < fabs(cx - x))
    346             x = fx;
    347         else
    348             x = cx;
    349 
    350         decimalAdjust = static_cast<int>(logx);
    351     }
    352 
    353     if (isnan(x))
    354         return jsString(exec, "NaN");
    355 
    356     if (x == -0.0) // (-0.0).toExponential() should print as 0 instead of -0
    357         x = 0;
    358 
    359     int decimalPoint;
    360     int sign;
    361     char* result = dtoa(x, 0, &decimalPoint, &sign, NULL);
    362     size_t resultLength = strlen(result);
    363     decimalPoint += decimalAdjust;
    364 
    365     int i = 0;
    366     char buf[80]; // digit + '.' + fractionDigits (max 20) + 'e' + sign + exponent (max?)
    367     if (sign)
    368         buf[i++] = '-';
    369 
    370     if (decimalPoint == 999) // ? 9999 is the magical "result is Inf or NaN" value.  what's 999??
    371         strcpy(buf + i, result);
    372     else {
    373         buf[i++] = result[0];
    374 
    375         if (includeAllDigits)
    376             fractionalDigits = static_cast<int>(resultLength) - 1;
    377 
    378         fractionalPartToString(buf, i, result, resultLength, fractionalDigits);
    379         exponentialPartToString(buf, i, decimalPoint);
    380         buf[i++] = '\0';
    381     }
    382     ASSERT(i <= 80);
    383 
    384     freedtoa(result);
    385 
    386     return jsString(exec, buf);
    387 }
    388 
    389 JSValue* numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    390 {
    391     JSValue* v = thisValue->getJSNumber();
    392     if (!v)
    393         return throwError(exec, TypeError);
    394 
    395     double doublePrecision = args[0]->toIntegerPreserveNaN(exec);
    396     double x = v->uncheckedGetNumber();
    397     if (args[0]->isUndefined() || isnan(x) || isinf(x))
    398         return jsString(exec, v->toString(exec));
    399 
    400     UString s;
    401     if (x < 0) {
    402         s = "-";
    403         x = -x;
    404     }
    405 
    406     if (!(doublePrecision >= 1 && doublePrecision <= 21)) // true for NaN
    407         return throwError(exec, RangeError, "toPrecision() argument must be between 1 and 21");
    408     int precision = (int)doublePrecision;
    409 
    410     int e = 0;
    411     UString m;
    412     if (x) {
    413         e = static_cast<int>(log10(x));
    414         double tens = intPow10(e - precision + 1);
    415         double n = floor(x / tens);
    416         if (n < intPow10(precision - 1)) {
    417             e = e - 1;
    418             tens = intPow10(e - precision + 1);
    419             n = floor(x / tens);
    420         }
    421 
    422         if (fabs((n + 1.0) * tens - x) <= fabs(n * tens - x))
    423             ++n;
    424         // maintain n < 10^(precision)
    425         if (n >= intPow10(precision)) {
    426             n /= 10.0;
    427             e += 1;
    428         }
    429         ASSERT(intPow10(precision - 1) <= n);
    430         ASSERT(n < intPow10(precision));
    431 
    432         m = integer_part_noexp(n);
    433         if (e < -6 || e >= precision) {
    434             if (m.size() > 1)
    435                 m = m.substr(0, 1) + "." + m.substr(1);
    436             if (e >= 0)
    437                 return jsString(exec, s + m + "e+" + UString::from(e));
    438             return jsString(exec, s + m + "e-" + UString::from(-e));
    439         }
    440     } else {
    441         m = char_sequence('0', precision);
    442         e = 0;
    443     }
    444 
    445     if (e == precision - 1)
    446         return jsString(exec, s + m);
    447     if (e >= 0) {
    448         if (e + 1 < m.size())
    449             return jsString(exec, s + m.substr(0, e + 1) + "." + m.substr(e + 1));
    450         return jsString(exec, s + m);
    451     }
    452     return jsString(exec, s + "0." + char_sequence('0', -(e + 1)) + m);
    453 }
    454 
    455 // ------------------------------ NumberConstructor ------------------------------
    45631
    45732const ClassInfo NumberConstructor::info = { "Function", &InternalFunction::info, 0, ExecState::numberTable };
  • trunk/JavaScriptCore/kjs/NumberConstructor.h

    r34853 r34854  
    2020 */
    2121
    22 #ifndef NumberObject_h
    23 #define NumberObject_h
     22#ifndef NumberConstructor_h
     23#define NumberConstructor_h
    2424
    25 #include "FunctionPrototype.h"
    26 #include "JSWrapperObject.h"
     25#include "JSFunction.h"
    2726
    2827namespace KJS {
    2928
    30     class JSNumberCell;
    31 
    32     class NumberObject : public JSWrapperObject {
    33     public:
    34         NumberObject(JSObject* prototype);
    35         static const ClassInfo info;
    36 
    37     private:
    38         virtual const ClassInfo* classInfo() const { return &info; }
    39         virtual JSValue* getJSNumber();
    40     };
    41 
    42     NumberObject* constructNumber(ExecState*, JSNumberCell*);
    43     NumberObject* constructNumberFromImmediateNumber(ExecState*, JSValue*);
    44 
    45     /**
    46      * @internal
    47      *
    48      * The initial value of Number.prototype (and thus all objects created
    49      * with the Number constructor
    50      */
    51     class NumberPrototype : public NumberObject {
    52     public:
    53         NumberPrototype(ExecState*, ObjectPrototype*, FunctionPrototype*);
    54     };
     29    class FunctionPrototype;
     30    class NumberPrototype;
    5531
    5632    /**
     
    7854} // namespace KJS
    7955
    80 #endif // NumberObject_h
     56#endif // NumberConstructor_h
  • trunk/JavaScriptCore/kjs/NumberObject.cpp

    r34821 r34854  
    2222#include "config.h"
    2323#include "NumberObject.h"
    24 #include "NumberObject.lut.h"
    25 
    26 #include "dtoa.h"
    27 #include "error_object.h"
    28 #include "operations.h"
    29 #include <wtf/Assertions.h>
    30 #include <wtf/MathExtras.h>
    31 #include <wtf/Vector.h>
    3224
    3325namespace KJS {
    34 
    35 // ------------------------------ NumberObject ----------------------------
    3626
    3727const ClassInfo NumberObject::info = { "Number", 0, 0, 0 };
     
    4737}
    4838
    49 // ------------------------------ NumberPrototype ---------------------------
    50 
    51 static JSValue* numberProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
    52 static JSValue* numberProtoFuncToLocaleString(ExecState*, JSObject*, JSValue*, const ArgList&);
    53 static JSValue* numberProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
    54 static JSValue* numberProtoFuncToFixed(ExecState*, JSObject*, JSValue*, const ArgList&);
    55 static JSValue* numberProtoFuncToExponential(ExecState*, JSObject*, JSValue*, const ArgList&);
    56 static JSValue* numberProtoFuncToPrecision(ExecState*, JSObject*, JSValue*, const ArgList&);
    57 
    58 // ECMA 15.7.4
    59 
    60 NumberPrototype::NumberPrototype(ExecState* exec, ObjectPrototype* objectPrototype, FunctionPrototype* functionPrototype)
    61     : NumberObject(objectPrototype)
    62 {
    63     setInternalValue(jsNumber(exec, 0));
    64 
    65     // The constructor will be added later, after NumberConstructor has been constructed
    66 
    67     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toString, numberProtoFuncToString), DontEnum);
    68     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toLocaleString, numberProtoFuncToLocaleString), DontEnum);
    69     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, numberProtoFuncValueOf), DontEnum);
    70     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toFixed, numberProtoFuncToFixed), DontEnum);
    71     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toExponential, numberProtoFuncToExponential), DontEnum);
    72     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toPrecision, numberProtoFuncToPrecision), DontEnum);
    73 }
    74 
    75 // ------------------------------ Functions ---------------------------
    76 
    77 // ECMA 15.7.4.2 - 15.7.4.7
    78 
    79 static UString integer_part_noexp(double d)
    80 {
    81     int decimalPoint;
    82     int sign;
    83     char* result = dtoa(d, 0, &decimalPoint, &sign, NULL);
    84     bool resultIsInfOrNan = (decimalPoint == 9999);
    85     size_t length = strlen(result);
    86 
    87     UString str = sign ? "-" : "";
    88     if (resultIsInfOrNan)
    89         str += result;
    90     else if (decimalPoint <= 0)
    91         str += "0";
    92     else {
    93         Vector<char, 1024> buf(decimalPoint + 1);
    94 
    95         if (static_cast<int>(length) <= decimalPoint) {
    96             strcpy(buf.data(), result);
    97             memset(buf.data() + length, '0', decimalPoint - length);
    98         } else
    99             strncpy(buf.data(), result, decimalPoint);
    100 
    101         buf[decimalPoint] = '\0';
    102         str.append(buf.data());
    103     }
    104 
    105     freedtoa(result);
    106 
    107     return str;
    108 }
    109 
    110 static UString char_sequence(char c, int count)
    111 {
    112     Vector<char, 2048> buf(count + 1, c);
    113     buf[count] = '\0';
    114 
    115     return UString(buf.data());
    116 }
    117 
    118 static double intPow10(int e)
    119 {
    120     // This function uses the "exponentiation by squaring" algorithm and
    121     // long double to quickly and precisely calculate integer powers of 10.0.
    122 
    123     // This is a handy workaround for <rdar://problem/4494756>
    124 
    125     if (e == 0)
    126         return 1.0;
    127 
    128     bool negative = e < 0;
    129     unsigned exp = negative ? -e : e;
    130 
    131     long double result = 10.0;
    132     bool foundOne = false;
    133     for (int bit = 31; bit >= 0; bit--) {
    134         if (!foundOne) {
    135             if ((exp >> bit) & 1)
    136                 foundOne = true;
    137         } else {
    138             result = result * result;
    139             if ((exp >> bit) & 1)
    140                 result = result * 10.0;
    141         }
    142     }
    143 
    144     if (negative)
    145         return static_cast<double>(1.0 / result);
    146     return static_cast<double>(result);
    147 }
    148 
    149 
    150 JSValue* numberProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    151 {
    152     JSValue* v = thisValue->getJSNumber();
    153     if (!v)
    154         return throwError(exec, TypeError);
    155 
    156     double radixAsDouble = args[0]->toInteger(exec); // nan -> 0
    157     if (radixAsDouble == 10 || args[0]->isUndefined())
    158         return jsString(exec, v->toString(exec));
    159 
    160     if (radixAsDouble < 2 || radixAsDouble > 36)
    161         return throwError(exec, RangeError, "toString() radix argument must be between 2 and 36");
    162 
    163     int radix = static_cast<int>(radixAsDouble);
    164     const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
    165     // INT_MAX results in 1024 characters left of the dot with radix 2
    166     // give the same space on the right side. safety checks are in place
    167     // unless someone finds a precise rule.
    168     char s[2048 + 3];
    169     const char* lastCharInString = s + sizeof(s) - 1;
    170     double x = v->uncheckedGetNumber();
    171     if (isnan(x) || isinf(x))
    172         return jsString(exec, UString::from(x));
    173 
    174     bool isNegative = x < 0.0;
    175     if (isNegative)
    176         x = -x;
    177 
    178     double integerPart = floor(x);
    179     char* decimalPoint = s + sizeof(s) / 2;
    180 
    181     // convert integer portion
    182     char* p = decimalPoint;
    183     double d = integerPart;
    184     do {
    185         int remainderDigit = static_cast<int>(fmod(d, radix));
    186         *--p = digits[remainderDigit];
    187         d /= radix;
    188     } while ((d <= -1.0 || d >= 1.0) && s < p);
    189 
    190     if (isNegative)
    191         *--p = '-';
    192     char* startOfResultString = p;
    193     ASSERT(s <= startOfResultString);
    194 
    195     d = x - integerPart;
    196     p = decimalPoint;
    197     const double epsilon = 0.001; // TODO: guessed. base on radix ?
    198     bool hasFractionalPart = (d < -epsilon || d > epsilon);
    199     if (hasFractionalPart) {
    200         *p++ = '.';
    201         do {
    202             d *= radix;
    203             const int digit = static_cast<int>(d);
    204             *p++ = digits[digit];
    205             d -= digit;
    206         } while ((d < -epsilon || d > epsilon) && p < lastCharInString);
    207     }
    208     *p = '\0';
    209     ASSERT(p < s + sizeof(s));
    210 
    211     return jsString(exec, startOfResultString);
    212 }
    213 
    214 JSValue* numberProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    215 {
    216     // FIXME: Not implemented yet.
    217 
    218     JSValue* v = thisValue->getJSNumber();
    219     if (!v)
    220         return throwError(exec, TypeError);
    221 
    222     return jsString(exec, v->toString(exec));
    223 }
    224 
    225 JSValue* numberProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    226 {
    227     JSValue* v = thisValue->getJSNumber();
    228     if (!v)
    229         return throwError(exec, TypeError);
    230 
    231     return v;
    232 }
    233 
    234 JSValue* numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    235 {
    236     JSValue* v = thisValue->getJSNumber();
    237     if (!v)
    238         return throwError(exec, TypeError);
    239 
    240     JSValue* fractionDigits = args[0];
    241     double df = fractionDigits->toInteger(exec);
    242     if (!(df >= 0 && df <= 20))
    243         return throwError(exec, RangeError, "toFixed() digits argument must be between 0 and 20");
    244     int f = (int)df;
    245 
    246     double x = v->uncheckedGetNumber();
    247     if (isnan(x))
    248         return jsString(exec, "NaN");
    249 
    250     UString s;
    251     if (x < 0) {
    252         s.append('-');
    253         x = -x;
    254     } else if (x == -0.0)
    255         x = 0;
    256 
    257     if (x >= pow(10.0, 21.0))
    258         return jsString(exec, s + UString::from(x));
    259 
    260     const double tenToTheF = pow(10.0, f);
    261     double n = floor(x * tenToTheF);
    262     if (fabs(n / tenToTheF - x) >= fabs((n + 1) / tenToTheF - x))
    263         n++;
    264 
    265     UString m = integer_part_noexp(n);
    266 
    267     int k = m.size();
    268     if (k <= f) {
    269         UString z;
    270         for (int i = 0; i < f + 1 - k; i++)
    271             z.append('0');
    272         m = z + m;
    273         k = f + 1;
    274         ASSERT(k == m.size());
    275     }
    276     int kMinusf = k - f;
    277     if (kMinusf < m.size())
    278         return jsString(exec, s + m.substr(0, kMinusf) + "." + m.substr(kMinusf));
    279     return jsString(exec, s + m.substr(0, kMinusf));
    280 }
    281 
    282 static void fractionalPartToString(char* buf, int& i, const char* result, int resultLength, int fractionalDigits)
    283 {
    284     if (fractionalDigits <= 0)
    285         return;
    286 
    287     int fDigitsInResult = static_cast<int>(resultLength) - 1;
    288     buf[i++] = '.';
    289     if (fDigitsInResult > 0) {
    290         if (fractionalDigits < fDigitsInResult) {
    291             strncpy(buf + i, result + 1, fractionalDigits);
    292             i += fractionalDigits;
    293         } else {
    294             strcpy(buf + i, result + 1);
    295             i += static_cast<int>(resultLength) - 1;
    296         }
    297     }
    298 
    299     for (int j = 0; j < fractionalDigits - fDigitsInResult; j++)
    300         buf[i++] = '0';
    301 }
    302 
    303 static void exponentialPartToString(char* buf, int& i, int decimalPoint)
    304 {
    305     buf[i++] = 'e';
    306     buf[i++] = (decimalPoint >= 0) ? '+' : '-';
    307     // decimalPoint can't be more than 3 digits decimal given the
    308     // nature of float representation
    309     int exponential = decimalPoint - 1;
    310     if (exponential < 0)
    311         exponential *= -1;
    312     if (exponential >= 100)
    313         buf[i++] = static_cast<char>('0' + exponential / 100);
    314     if (exponential >= 10)
    315         buf[i++] = static_cast<char>('0' + (exponential % 100) / 10);
    316     buf[i++] = static_cast<char>('0' + exponential % 10);
    317 }
    318 
    319 JSValue* numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    320 {
    321     JSValue* v = thisValue->getJSNumber();
    322     if (!v)
    323         return throwError(exec, TypeError);
    324 
    325     double x = v->uncheckedGetNumber();
    326 
    327     if (isnan(x) || isinf(x))
    328         return jsString(exec, UString::from(x));
    329 
    330     JSValue* fractionalDigitsValue = args[0];
    331     double df = fractionalDigitsValue->toInteger(exec);
    332     if (!(df >= 0 && df <= 20))
    333         return throwError(exec, RangeError, "toExponential() argument must between 0 and 20");
    334     int fractionalDigits = (int)df;
    335     bool includeAllDigits = fractionalDigitsValue->isUndefined();
    336 
    337     int decimalAdjust = 0;
    338     if (x && !includeAllDigits) {
    339         double logx = floor(log10(fabs(x)));
    340         x /= pow(10.0, logx);
    341         const double tenToTheF = pow(10.0, fractionalDigits);
    342         double fx = floor(x * tenToTheF) / tenToTheF;
    343         double cx = ceil(x * tenToTheF) / tenToTheF;
    344 
    345         if (fabs(fx - x) < fabs(cx - x))
    346             x = fx;
    347         else
    348             x = cx;
    349 
    350         decimalAdjust = static_cast<int>(logx);
    351     }
    352 
    353     if (isnan(x))
    354         return jsString(exec, "NaN");
    355 
    356     if (x == -0.0) // (-0.0).toExponential() should print as 0 instead of -0
    357         x = 0;
    358 
    359     int decimalPoint;
    360     int sign;
    361     char* result = dtoa(x, 0, &decimalPoint, &sign, NULL);
    362     size_t resultLength = strlen(result);
    363     decimalPoint += decimalAdjust;
    364 
    365     int i = 0;
    366     char buf[80]; // digit + '.' + fractionDigits (max 20) + 'e' + sign + exponent (max?)
    367     if (sign)
    368         buf[i++] = '-';
    369 
    370     if (decimalPoint == 999) // ? 9999 is the magical "result is Inf or NaN" value.  what's 999??
    371         strcpy(buf + i, result);
    372     else {
    373         buf[i++] = result[0];
    374 
    375         if (includeAllDigits)
    376             fractionalDigits = static_cast<int>(resultLength) - 1;
    377 
    378         fractionalPartToString(buf, i, result, resultLength, fractionalDigits);
    379         exponentialPartToString(buf, i, decimalPoint);
    380         buf[i++] = '\0';
    381     }
    382     ASSERT(i <= 80);
    383 
    384     freedtoa(result);
    385 
    386     return jsString(exec, buf);
    387 }
    388 
    389 JSValue* numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    390 {
    391     JSValue* v = thisValue->getJSNumber();
    392     if (!v)
    393         return throwError(exec, TypeError);
    394 
    395     double doublePrecision = args[0]->toIntegerPreserveNaN(exec);
    396     double x = v->uncheckedGetNumber();
    397     if (args[0]->isUndefined() || isnan(x) || isinf(x))
    398         return jsString(exec, v->toString(exec));
    399 
    400     UString s;
    401     if (x < 0) {
    402         s = "-";
    403         x = -x;
    404     }
    405 
    406     if (!(doublePrecision >= 1 && doublePrecision <= 21)) // true for NaN
    407         return throwError(exec, RangeError, "toPrecision() argument must be between 1 and 21");
    408     int precision = (int)doublePrecision;
    409 
    410     int e = 0;
    411     UString m;
    412     if (x) {
    413         e = static_cast<int>(log10(x));
    414         double tens = intPow10(e - precision + 1);
    415         double n = floor(x / tens);
    416         if (n < intPow10(precision - 1)) {
    417             e = e - 1;
    418             tens = intPow10(e - precision + 1);
    419             n = floor(x / tens);
    420         }
    421 
    422         if (fabs((n + 1.0) * tens - x) <= fabs(n * tens - x))
    423             ++n;
    424         // maintain n < 10^(precision)
    425         if (n >= intPow10(precision)) {
    426             n /= 10.0;
    427             e += 1;
    428         }
    429         ASSERT(intPow10(precision - 1) <= n);
    430         ASSERT(n < intPow10(precision));
    431 
    432         m = integer_part_noexp(n);
    433         if (e < -6 || e >= precision) {
    434             if (m.size() > 1)
    435                 m = m.substr(0, 1) + "." + m.substr(1);
    436             if (e >= 0)
    437                 return jsString(exec, s + m + "e+" + UString::from(e));
    438             return jsString(exec, s + m + "e-" + UString::from(-e));
    439         }
    440     } else {
    441         m = char_sequence('0', precision);
    442         e = 0;
    443     }
    444 
    445     if (e == precision - 1)
    446         return jsString(exec, s + m);
    447     if (e >= 0) {
    448         if (e + 1 < m.size())
    449             return jsString(exec, s + m.substr(0, e + 1) + "." + m.substr(e + 1));
    450         return jsString(exec, s + m);
    451     }
    452     return jsString(exec, s + "0." + char_sequence('0', -(e + 1)) + m);
    453 }
    454 
    455 // ------------------------------ NumberConstructor ------------------------------
    456 
    457 const ClassInfo NumberConstructor::info = { "Function", &InternalFunction::info, 0, ExecState::numberTable };
    458 
    459 /* Source for NumberObject.lut.h
    460 @begin numberTable
    461   NaN                   NumberConstructor::NaNValue       DontEnum|DontDelete|ReadOnly
    462   NEGATIVE_INFINITY     NumberConstructor::NegInfinity    DontEnum|DontDelete|ReadOnly
    463   POSITIVE_INFINITY     NumberConstructor::PosInfinity    DontEnum|DontDelete|ReadOnly
    464   MAX_VALUE             NumberConstructor::MaxValue       DontEnum|DontDelete|ReadOnly
    465   MIN_VALUE             NumberConstructor::MinValue       DontEnum|DontDelete|ReadOnly
    466 @end
    467 */
    468 NumberConstructor::NumberConstructor(ExecState* exec, FunctionPrototype* funcProto, NumberPrototype* numberProto)
    469     : InternalFunction(funcProto, Identifier(exec, numberProto->info.className))
    470 {
    471     // Number.Prototype
    472     putDirect(exec->propertyNames().prototype, numberProto, DontEnum|DontDelete|ReadOnly);
    473 
    474     // no. of arguments for constructor
    475     putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete);
    476 }
    477 
    478 bool NumberConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
    479 {
    480     return getStaticValueSlot<NumberConstructor, InternalFunction>(exec, ExecState::numberTable(exec), this, propertyName, slot);
    481 }
    482 
    483 JSValue* NumberConstructor::getValueProperty(ExecState* exec, int token) const
    484 {
    485     // ECMA 15.7.3
    486     switch (token) {
    487         case NaNValue:
    488             return jsNaN(exec);
    489         case NegInfinity:
    490             return jsNumberCell(exec, -Inf);
    491         case PosInfinity:
    492             return jsNumberCell(exec, Inf);
    493         case MaxValue:
    494             return jsNumberCell(exec, 1.7976931348623157E+308);
    495         case MinValue:
    496             return jsNumberCell(exec, 5E-324);
    497     }
    498     ASSERT_NOT_REACHED();
    499     return jsNull();
    500 }
    501 
    502 // ECMA 15.7.1
    503 static JSObject* constructWithNumberConstructor(ExecState* exec, JSObject*, const ArgList& args)
    504 {
    505     NumberObject* obj = new (exec) NumberObject(exec->lexicalGlobalObject()->numberPrototype());
    506     double n = args.isEmpty() ? 0 : args[0]->toNumber(exec);
    507     obj->setInternalValue(jsNumber(exec, n));
    508     return obj;
    509 }
    510 
    511 ConstructType NumberConstructor::getConstructData(ConstructData& constructData)
    512 {
    513     constructData.native.function = constructWithNumberConstructor;
    514     return ConstructTypeNative;
    515 }
    516 
    517 // ECMA 15.7.2
    518 static JSValue* callNumberConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    519 {
    520     return jsNumber(exec, args.isEmpty() ? 0 : args[0]->toNumber(exec));
    521 }
    522 
    523 CallType NumberConstructor::getCallData(CallData& callData)
    524 {
    525     callData.native.function = callNumberConstructor;
    526     return CallTypeNative;
    527 }
    528 
    529 NumberObject* constructNumber(ExecState* exec, JSNumberCell* number)
    530 {
    531     NumberObject* obj = new (exec) NumberObject(exec->lexicalGlobalObject()->numberPrototype());
    532     obj->setInternalValue(number);
    533     return obj;
    534 }
    535 
    536 NumberObject* constructNumberFromImmediateNumber(ExecState* exec, JSValue* value)
    537 {
    538     NumberObject* obj = new (exec) NumberObject(exec->lexicalGlobalObject()->numberPrototype());
    539     obj->setInternalValue(value);
    540     return obj;
    541 }
    542 
    54339} // namespace KJS
  • trunk/JavaScriptCore/kjs/NumberObject.h

    r34821 r34854  
    11// -*- c-basic-offset: 2 -*-
    22/*
    3  *  This file is part of the KDE libraries
    43 *  Copyright (C) 1999-2000 Harri Porten ([email protected])
     4 *  Copyright (C) 2008 Apple Inc. All rights reserved.
    55 *
    66 *  This library is free software; you can redistribute it and/or
     
    2323#define NumberObject_h
    2424
    25 #include "FunctionPrototype.h"
    2625#include "JSWrapperObject.h"
    2726
     
    4342    NumberObject* constructNumberFromImmediateNumber(ExecState*, JSValue*);
    4443
    45     /**
    46      * @internal
    47      *
    48      * The initial value of Number.prototype (and thus all objects created
    49      * with the Number constructor
    50      */
    51     class NumberPrototype : public NumberObject {
    52     public:
    53         NumberPrototype(ExecState*, ObjectPrototype*, FunctionPrototype*);
    54     };
    55 
    56     /**
    57      * @internal
    58      *
    59      * The initial value of the the global variable's "Number" property
    60      */
    61     class NumberConstructor : public InternalFunction {
    62     public:
    63         NumberConstructor(ExecState*, FunctionPrototype*, NumberPrototype*);
    64 
    65         bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    66         JSValue* getValueProperty(ExecState*, int token) const;
    67 
    68         static const ClassInfo info;
    69 
    70         enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
    71 
    72     private:
    73         virtual ConstructType getConstructData(ConstructData&);
    74         virtual CallType getCallData(CallData&);
    75         virtual const ClassInfo* classInfo() const { return &info; }
    76     };
    77 
    7844} // namespace KJS
    7945
  • trunk/JavaScriptCore/kjs/NumberPrototype.cpp

    r34853 r34854  
    2121
    2222#include "config.h"
    23 #include "NumberObject.h"
    24 #include "NumberObject.lut.h"
     23#include "NumberPrototype.h"
    2524
    2625#include "dtoa.h"
     
    3332namespace KJS {
    3433
    35 // ------------------------------ NumberObject ----------------------------
    36 
    37 const ClassInfo NumberObject::info = { "Number", 0, 0, 0 };
    38 
    39 NumberObject::NumberObject(JSObject* proto)
    40     : JSWrapperObject(proto)
    41 {
    42 }
    43 
    44 JSValue* NumberObject::getJSNumber()
    45 {
    46     return internalValue();
    47 }
    48 
    49 // ------------------------------ NumberPrototype ---------------------------
    5034
    5135static JSValue* numberProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
     
    453437}
    454438
    455 // ------------------------------ NumberConstructor ------------------------------
    456 
    457 const ClassInfo NumberConstructor::info = { "Function", &InternalFunction::info, 0, ExecState::numberTable };
    458 
    459 /* Source for NumberObject.lut.h
    460 @begin numberTable
    461   NaN                   NumberConstructor::NaNValue       DontEnum|DontDelete|ReadOnly
    462   NEGATIVE_INFINITY     NumberConstructor::NegInfinity    DontEnum|DontDelete|ReadOnly
    463   POSITIVE_INFINITY     NumberConstructor::PosInfinity    DontEnum|DontDelete|ReadOnly
    464   MAX_VALUE             NumberConstructor::MaxValue       DontEnum|DontDelete|ReadOnly
    465   MIN_VALUE             NumberConstructor::MinValue       DontEnum|DontDelete|ReadOnly
    466 @end
    467 */
    468 NumberConstructor::NumberConstructor(ExecState* exec, FunctionPrototype* funcProto, NumberPrototype* numberProto)
    469     : InternalFunction(funcProto, Identifier(exec, numberProto->info.className))
    470 {
    471     // Number.Prototype
    472     putDirect(exec->propertyNames().prototype, numberProto, DontEnum|DontDelete|ReadOnly);
    473 
    474     // no. of arguments for constructor
    475     putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete);
    476 }
    477 
    478 bool NumberConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
    479 {
    480     return getStaticValueSlot<NumberConstructor, InternalFunction>(exec, ExecState::numberTable(exec), this, propertyName, slot);
    481 }
    482 
    483 JSValue* NumberConstructor::getValueProperty(ExecState* exec, int token) const
    484 {
    485     // ECMA 15.7.3
    486     switch (token) {
    487         case NaNValue:
    488             return jsNaN(exec);
    489         case NegInfinity:
    490             return jsNumberCell(exec, -Inf);
    491         case PosInfinity:
    492             return jsNumberCell(exec, Inf);
    493         case MaxValue:
    494             return jsNumberCell(exec, 1.7976931348623157E+308);
    495         case MinValue:
    496             return jsNumberCell(exec, 5E-324);
    497     }
    498     ASSERT_NOT_REACHED();
    499     return jsNull();
    500 }
    501 
    502 // ECMA 15.7.1
    503 static JSObject* constructWithNumberConstructor(ExecState* exec, JSObject*, const ArgList& args)
    504 {
    505     NumberObject* obj = new (exec) NumberObject(exec->lexicalGlobalObject()->numberPrototype());
    506     double n = args.isEmpty() ? 0 : args[0]->toNumber(exec);
    507     obj->setInternalValue(jsNumber(exec, n));
    508     return obj;
    509 }
    510 
    511 ConstructType NumberConstructor::getConstructData(ConstructData& constructData)
    512 {
    513     constructData.native.function = constructWithNumberConstructor;
    514     return ConstructTypeNative;
    515 }
    516 
    517 // ECMA 15.7.2
    518 static JSValue* callNumberConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    519 {
    520     return jsNumber(exec, args.isEmpty() ? 0 : args[0]->toNumber(exec));
    521 }
    522 
    523 CallType NumberConstructor::getCallData(CallData& callData)
    524 {
    525     callData.native.function = callNumberConstructor;
    526     return CallTypeNative;
    527 }
    528 
    529 NumberObject* constructNumber(ExecState* exec, JSNumberCell* number)
    530 {
    531     NumberObject* obj = new (exec) NumberObject(exec->lexicalGlobalObject()->numberPrototype());
    532     obj->setInternalValue(number);
    533     return obj;
    534 }
    535 
    536 NumberObject* constructNumberFromImmediateNumber(ExecState* exec, JSValue* value)
    537 {
    538     NumberObject* obj = new (exec) NumberObject(exec->lexicalGlobalObject()->numberPrototype());
    539     obj->setInternalValue(value);
    540     return obj;
    541 }
    542 
    543439} // namespace KJS
  • trunk/JavaScriptCore/kjs/NumberPrototype.h

    r34853 r34854  
    2020 */
    2121
    22 #ifndef NumberObject_h
    23 #define NumberObject_h
     22#ifndef NumberPrototype_h
     23#define NumberPrototype_h
    2424
    25 #include "FunctionPrototype.h"
    26 #include "JSWrapperObject.h"
     25#include "NumberObject.h"
    2726
    2827namespace KJS {
    29 
    30     class JSNumberCell;
    31 
    32     class NumberObject : public JSWrapperObject {
    33     public:
    34         NumberObject(JSObject* prototype);
    35         static const ClassInfo info;
    36 
    37     private:
    38         virtual const ClassInfo* classInfo() const { return &info; }
    39         virtual JSValue* getJSNumber();
    40     };
    41 
    42     NumberObject* constructNumber(ExecState*, JSNumberCell*);
    43     NumberObject* constructNumberFromImmediateNumber(ExecState*, JSValue*);
    4428
    4529    /**
     
    5438    };
    5539
    56     /**
    57      * @internal
    58      *
    59      * The initial value of the the global variable's "Number" property
    60      */
    61     class NumberConstructor : public InternalFunction {
    62     public:
    63         NumberConstructor(ExecState*, FunctionPrototype*, NumberPrototype*);
    64 
    65         bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    66         JSValue* getValueProperty(ExecState*, int token) const;
    67 
    68         static const ClassInfo info;
    69 
    70         enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
    71 
    72     private:
    73         virtual ConstructType getConstructData(ConstructData&);
    74         virtual CallType getCallData(CallData&);
    75         virtual const ClassInfo* classInfo() const { return &info; }
    76     };
    77 
    7840} // namespace KJS
    7941
    80 #endif // NumberObject_h
     42#endif // NumberPrototype_h
  • trunk/JavaScriptCore/kjs/ObjectConstructor.cpp

    r34853 r34854  
    2020
    2121#include "config.h"
    22 #include "object_object.h"
     22#include "ObjectConstructor.h"
    2323
    2424#include "JSGlobalObject.h"
    25 #include "operations.h"
    2625#include "FunctionPrototype.h"
    27 #include <stdio.h>
    2826
    2927namespace KJS {
    30 
    31 // ------------------------------ ObjectPrototype --------------------------------
    32 
    33 static JSValue* objectProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
    34 static JSValue* objectProtoFuncHasOwnProperty(ExecState*, JSObject*, JSValue*, const ArgList&);
    35 static JSValue* objectProtoFuncIsPrototypeOf(ExecState*, JSObject*, JSValue*, const ArgList&);
    36 static JSValue* objectProtoFuncDefineGetter(ExecState*, JSObject*, JSValue*, const ArgList&);
    37 static JSValue* objectProtoFuncDefineSetter(ExecState*, JSObject*, JSValue*, const ArgList&);
    38 static JSValue* objectProtoFuncLookupGetter(ExecState*, JSObject*, JSValue*, const ArgList&);
    39 static JSValue* objectProtoFuncLookupSetter(ExecState*, JSObject*, JSValue*, const ArgList&);
    40 static JSValue* objectProtoFuncPropertyIsEnumerable(ExecState*, JSObject*, JSValue*, const ArgList&);
    41 static JSValue* objectProtoFuncToLocaleString(ExecState*, JSObject*, JSValue*, const ArgList&);
    42 
    43 ObjectPrototype::ObjectPrototype(ExecState* exec, FunctionPrototype* functionPrototype)
    44     : JSObject() // [[Prototype]] is null
    45 {
    46     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
    47     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum);
    48     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum);
    49     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().hasOwnProperty, objectProtoFuncHasOwnProperty), DontEnum);
    50     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().propertyIsEnumerable, objectProtoFuncPropertyIsEnumerable), DontEnum);
    51     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().isPrototypeOf, objectProtoFuncIsPrototypeOf), DontEnum);
    52 
    53     // Mozilla extensions
    54     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 2, exec->propertyNames().__defineGetter__, objectProtoFuncDefineGetter), DontEnum);
    55     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 2, exec->propertyNames().__defineSetter__, objectProtoFuncDefineSetter), DontEnum);
    56     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().__lookupGetter__, objectProtoFuncLookupGetter), DontEnum);
    57     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().__lookupSetter__, objectProtoFuncLookupSetter), DontEnum);
    58 }
    59 
    60 
    61 // ------------------------------ Functions --------------------------------
    62 
    63 // ECMA 15.2.4.2, 15.2.4.4, 15.2.4.5, 15.2.4.7
    64 
    65 JSValue* objectProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    66 {
    67     return thisValue->toThisObject(exec);
    68 }
    69 
    70 JSValue* objectProtoFuncHasOwnProperty(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    71 {
    72     return jsBoolean(thisValue->toThisObject(exec)->hasOwnProperty(exec, Identifier(exec, args[0]->toString(exec))));
    73 }
    74 
    75 JSValue* objectProtoFuncIsPrototypeOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    76 {
    77     JSObject* thisObj = thisValue->toThisObject(exec);
    78 
    79     if (!args[0]->isObject())
    80         return jsBoolean(false);
    81 
    82     JSValue* v = static_cast<JSObject*>(args[0])->prototype();
    83 
    84     while (true) {
    85         if (!v->isObject())
    86             return jsBoolean(false);
    87         if (thisObj == v)
    88 
    89             return jsBoolean(true);
    90         v = static_cast<JSObject*>(v)->prototype();
    91     }
    92 }
    93 
    94 JSValue* objectProtoFuncDefineGetter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    95 {
    96     CallData callData;
    97     if (args[1]->getCallData(callData) == CallTypeNone)
    98         return throwError(exec, SyntaxError, "invalid getter usage");
    99     thisValue->toThisObject(exec)->defineGetter(exec, Identifier(exec, args[0]->toString(exec)), static_cast<JSObject*>(args[1]));
    100     return jsUndefined();
    101 }
    102 
    103 JSValue* objectProtoFuncDefineSetter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    104 {
    105     CallData callData;
    106     if (args[1]->getCallData(callData) == CallTypeNone)
    107         return throwError(exec, SyntaxError, "invalid setter usage");
    108     thisValue->toThisObject(exec)->defineSetter(exec, Identifier(exec, args[0]->toString(exec)), static_cast<JSObject*>(args[1]));
    109     return jsUndefined();
    110 }
    111 
    112 JSValue* objectProtoFuncLookupGetter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    113 {
    114     return thisValue->toThisObject(exec)->lookupGetter(exec, Identifier(exec, args[0]->toString(exec)));
    115 }
    116 
    117 JSValue* objectProtoFuncLookupSetter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    118 {
    119     return thisValue->toThisObject(exec)->lookupSetter(exec, Identifier(exec, args[0]->toString(exec)));
    120 }
    121 
    122 JSValue* objectProtoFuncPropertyIsEnumerable(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    123 {
    124     return jsBoolean(thisValue->toThisObject(exec)->propertyIsEnumerable(exec, Identifier(exec, args[0]->toString(exec))));
    125 }
    126 
    127 JSValue* objectProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    128 {
    129     return jsString(exec, thisValue->toThisObject(exec)->toString(exec));
    130 }
    131 
    132 JSValue* objectProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    133 {
    134     return jsString(exec, "[object " + thisValue->toThisObject(exec)->className() + "]");
    135 }
    136 
    137 // ------------------------------ ObjectConstructor --------------------------------
    13828
    13929ObjectConstructor::ObjectConstructor(ExecState* exec, ObjectPrototype* objProto, FunctionPrototype* funcProto)
  • trunk/JavaScriptCore/kjs/ObjectConstructor.h

    r34853 r34854  
    1919 */
    2020
    21 #ifndef _OBJECT_OBJECT_H_
    22 #define _OBJECT_OBJECT_H_
     21#ifndef ObjectConstructor_h
     22#define ObjectConstructor_h
    2323
    2424#include "JSFunction.h"
     
    2626namespace KJS {
    2727
    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     };
    38 
    39     JSValue* objectProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
     28    class FunctionPrototype;
     29    class ObjectPrototype;
    4030
    4131    /**
     
    5444} // namespace KJS
    5545
    56 #endif // _OBJECT_OBJECT_H_
     46#endif // ObjectConstructor_h
  • trunk/JavaScriptCore/kjs/ObjectPrototype.cpp

    r34853 r34854  
    2020
    2121#include "config.h"
    22 #include "object_object.h"
     22#include "ObjectPrototype.h"
    2323
    24 #include "JSGlobalObject.h"
    2524#include "operations.h"
    2625#include "FunctionPrototype.h"
    27 #include <stdio.h>
    2826
    2927namespace KJS {
    30 
    31 // ------------------------------ ObjectPrototype --------------------------------
    3228
    3329static JSValue* objectProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
     
    135131}
    136132
    137 // ------------------------------ ObjectConstructor --------------------------------
    138 
    139 ObjectConstructor::ObjectConstructor(ExecState* exec, ObjectPrototype* objProto, FunctionPrototype* funcProto)
    140   : InternalFunction(funcProto, Identifier(exec, "Object"))
    141 {
    142   // ECMA 15.2.3.1
    143   putDirect(exec->propertyNames().prototype, objProto, DontEnum|DontDelete|ReadOnly);
    144 
    145   // no. of arguments for constructor
    146   putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete);
    147 }
    148 
    149 // ECMA 15.2.2
    150 static ALWAYS_INLINE JSObject* constructObject(ExecState* exec, const ArgList& args)
    151 {
    152     JSValue* arg = args[0];
    153     if (arg->isUndefinedOrNull())
    154         return new (exec) JSObject(exec->lexicalGlobalObject()->objectPrototype());
    155     return arg->toObject(exec);
    156 }
    157 
    158 static JSObject* constructWithObjectConstructor(ExecState* exec, JSObject*, const ArgList& args)
    159 {
    160     return constructObject(exec, args);
    161 }
    162 
    163 ConstructType ObjectConstructor::getConstructData(ConstructData& constructData)
    164 {
    165     constructData.native.function = constructWithObjectConstructor;
    166     return ConstructTypeNative;
    167 }
    168 
    169 static JSValue* callObjectConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    170 {
    171     return constructObject(exec, args);
    172 }
    173 
    174 CallType ObjectConstructor::getCallData(CallData& callData)
    175 {
    176     callData.native.function = callObjectConstructor;
    177     return CallTypeNative;
    178 }
    179 
    180133} // namespace KJS
  • trunk/JavaScriptCore/kjs/ObjectPrototype.h

    r34853 r34854  
    1919 */
    2020
    21 #ifndef _OBJECT_OBJECT_H_
    22 #define _OBJECT_OBJECT_H_
     21#ifndef ObjectPrototype_h
     22#define ObjectPrototype_h
    2323
    24 #include "JSFunction.h"
     24#include "JSObject.h"
    2525
    2626namespace KJS {
     27
     28    class FunctionPrototype;
    2729
    2830    /**
     
    3941    JSValue* objectProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
    4042
    41     /**
    42      * @internal
    43      *
    44      * The initial value of the the global variable's "Object" property
    45      */
    46     class ObjectConstructor : public InternalFunction {
    47     public:
    48         ObjectConstructor(ExecState*, ObjectPrototype*, FunctionPrototype*);
    49     private:
    50         virtual ConstructType getConstructData(ConstructData&);
    51         virtual CallType getCallData(CallData&);
    52     };
    53 
    5443} // namespace KJS
    5544
    56 #endif // _OBJECT_OBJECT_H_
     45#endif // ObjectPrototype_h
  • trunk/JavaScriptCore/kjs/RegExpObject.h

    r34754 r34854  
    2222#define RegExpObject_h
    2323
    24 #include "FunctionPrototype.h"
    2524#include "regexp.h"
    2625
    2726namespace KJS {
    2827
     28    class FunctionPrototype;
    2929    struct RegExpConstructorPrivate;
    3030
  • trunk/JavaScriptCore/kjs/Shell.cpp

    r34843 r34854  
    2323#include "config.h"
    2424
     25#include "ObjectPrototype.h"
     26#include "ObjectConstructor.h"
     27
    2528#include "CodeGenerator.h"
    2629#include "InitializeThreading.h"
  • trunk/JavaScriptCore/kjs/error_object.h

    r34754 r34854  
    2222#define ERROR_OBJECT_H_
    2323
    24 #include "FunctionPrototype.h"
     24#include "JSFunction.h"
    2525
    2626namespace KJS {
     27
     28    class FunctionPrototype;
    2729
    2830    class ErrorInstance : public JSObject {
  • trunk/JavaScriptCore/kjs/internal.cpp

    r34843 r34854  
    2525
    2626#include "ExecState.h"
     27#include "FunctionPrototype.h"
     28#include "JSObject.h"
     29#include "MathObject.h"
     30#include "NumberObject.h"
     31#include "RegExpObject.h"
    2732#include "collector.h"
    2833#include "date_object.h"
    2934#include "debugger.h"
    3035#include "error_object.h"
    31 #include "FunctionPrototype.h"
    3236#include "lexer.h"
    33 #include "MathObject.h"
    3437#include "nodes.h"
    35 #include "NumberObject.h"
    36 #include "JSObject.h"
    37 #include "object_object.h"
    3838#include "operations.h"
    39 #include "RegExpObject.h"
    4039#include "string_object.h"
    4140#include <math.h>
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r34852 r34854  
    2929#include "CodeGenerator.h"
    3030#include "ExecState.h"
    31 #include "FunctionPrototype.h"
    3231#include "JSGlobalObject.h"
    3332#include "Parser.h"
  • trunk/JavaScriptCore/kjs/string_object.h

    r34821 r34854  
    2323#define STRING_OBJECT_H_
    2424
    25 #include "FunctionPrototype.h"
    2625#include "JSWrapperObject.h"
    2726#include "JSString.h"
     
    2928
    3029namespace KJS {
     30
     31  class FunctionPrototype;
    3132
    3233  class StringObject : public JSWrapperObject {
Note: See TracChangeset for help on using the changeset viewer.