Changeset 35016 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Jul 5, 2008, 4:19:36 PM (17 years ago)
Author:
[email protected]
Message:

JavaScriptCore:

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

Rubber-stamped by Cameron Zwarich.

Split Arguments, IndexToNameMap, PrototypeFunction, GlobalEvalFunction and
the functions on the global object out of JSFunction.h/cpp.

  • GNUmakefile.am:
  • JavaScriptCore.pri:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • JavaScriptCoreSources.bkl:
  • VM/Machine.cpp:
  • kjs/AllInOneFile.cpp:
  • kjs/Arguments.cpp: Copied from JavaScriptCore/kjs/JSFunction.cpp.
  • kjs/Arguments.h: Copied from JavaScriptCore/kjs/JSFunction.h.
  • kjs/GlobalEvalFunction.cpp: Copied from JavaScriptCore/kjs/JSFunction.cpp.
  • kjs/GlobalEvalFunction.h: Copied from JavaScriptCore/kjs/JSFunction.h.
  • kjs/IndexToNameMap.cpp: Copied from JavaScriptCore/kjs/JSFunction.cpp.
  • kjs/IndexToNameMap.h: Copied from JavaScriptCore/kjs/JSFunction.h.
  • kjs/JSActivation.cpp:
  • kjs/JSFunction.cpp:
  • kjs/JSFunction.h:
  • kjs/JSGlobalObject.cpp:
  • kjs/JSGlobalObjectFunctions.cpp: Copied from JavaScriptCore/kjs/JSFunction.cpp.
  • kjs/JSGlobalObjectFunctions.h: Copied from JavaScriptCore/kjs/JSFunction.h. The functions on the global object should be in JSGlobalObject.cpp, but putting them there was a 0.5% regression.
  • kjs/PrototypeFunction.cpp: Copied from JavaScriptCore/kjs/JSFunction.cpp.
  • kjs/PrototypeFunction.h: Copied from JavaScriptCore/kjs/JSFunction.h.
  • kjs/Shell.cpp:
  • kjs/lexer.cpp:
  • kjs/ustring.cpp:

WebCore:

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

Rubber-stamped by Cameron Zwarich.

Split Arguments, IndexToNameMap, PrototypeFunction, GlobalEvalFunction and
the functions on the global object out of JSFunction.h/cpp.

  • ForwardingHeaders/kjs/PrototypeFunction.h: Added.
  • bindings/js/JSDOMBinding.cpp:
Location:
trunk/JavaScriptCore
Files:
15 edited
10 copied

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r35011 r35016  
     12008-07-05  Sam Weinig  <[email protected]>
     2
     3        Rubber-stamped by Cameron Zwarich.
     4
     5        Split Arguments, IndexToNameMap, PrototypeFunction, GlobalEvalFunction and
     6        the functions on the global object out of JSFunction.h/cpp.
     7
     8        * GNUmakefile.am:
     9        * JavaScriptCore.pri:
     10        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
     11        * JavaScriptCore.xcodeproj/project.pbxproj:
     12        * JavaScriptCoreSources.bkl:
     13        * VM/Machine.cpp:
     14        * kjs/AllInOneFile.cpp:
     15        * kjs/Arguments.cpp: Copied from JavaScriptCore/kjs/JSFunction.cpp.
     16        * kjs/Arguments.h: Copied from JavaScriptCore/kjs/JSFunction.h.
     17        * kjs/GlobalEvalFunction.cpp: Copied from JavaScriptCore/kjs/JSFunction.cpp.
     18        * kjs/GlobalEvalFunction.h: Copied from JavaScriptCore/kjs/JSFunction.h.
     19        * kjs/IndexToNameMap.cpp: Copied from JavaScriptCore/kjs/JSFunction.cpp.
     20        * kjs/IndexToNameMap.h: Copied from JavaScriptCore/kjs/JSFunction.h.
     21        * kjs/JSActivation.cpp:
     22        * kjs/JSFunction.cpp:
     23        * kjs/JSFunction.h:
     24        * kjs/JSGlobalObject.cpp:
     25        * kjs/JSGlobalObjectFunctions.cpp: Copied from JavaScriptCore/kjs/JSFunction.cpp.
     26        * kjs/JSGlobalObjectFunctions.h: Copied from JavaScriptCore/kjs/JSFunction.h.
     27        The functions on the global object should be in JSGlobalObject.cpp, but putting them there
     28        was a 0.5% regression.
     29
     30        * kjs/PrototypeFunction.cpp: Copied from JavaScriptCore/kjs/JSFunction.cpp.
     31        * kjs/PrototypeFunction.h: Copied from JavaScriptCore/kjs/JSFunction.h.
     32        * kjs/Shell.cpp:
     33        * kjs/lexer.cpp:
     34        * kjs/ustring.cpp:
     35
    1362008-07-04  Sam Weinig  <[email protected]>
    237
  • trunk/JavaScriptCore/GNUmakefile.am

    r35007 r35016  
    7575
    7676javascriptcore_sources += \
    77         JavaScriptCore/kjs/CommonIdentifiers.cpp \
    78         JavaScriptCore/kjs/DateMath.cpp \
    79         JavaScriptCore/kjs/JSImmediate.cpp \
    80         JavaScriptCore/kjs/JSLock.cpp \
    81         JavaScriptCore/kjs/JSWrapperObject.cpp \
    82         JavaScriptCore/kjs/Parser.cpp \
    83         JavaScriptCore/kjs/PropertyNameArray.cpp \
    84         JavaScriptCore/kjs/JSArray.cpp \
     77        JavaScriptCore/kjs/Arguments.cpp \
    8578        JavaScriptCore/kjs/ArrayConstructor.cpp \
    8679        JavaScriptCore/kjs/ArrayPrototype.cpp \
     
    8982        JavaScriptCore/kjs/BooleanPrototype.cpp \
    9083        JavaScriptCore/kjs/collector.cpp \
     84        JavaScriptCore/kjs/CommonIdentifiers.cpp \
     85        JavaScriptCore/kjs/DateConstructor.cpp \
    9186        JavaScriptCore/kjs/DateInstance.cpp \
    92         JavaScriptCore/kjs/DateConstructor.cpp \
     87        JavaScriptCore/kjs/DateMath.cpp \
    9388        JavaScriptCore/kjs/DatePrototype.cpp \
    9489        JavaScriptCore/kjs/debugger.cpp \
     
    9893        JavaScriptCore/kjs/ErrorInstance.cpp \
    9994        JavaScriptCore/kjs/ErrorPrototype.cpp \
     95        JavaScriptCore/kjs/FunctionConstructor.cpp \
     96        JavaScriptCore/kjs/FunctionPrototype.cpp \
    10097        JavaScriptCore/kjs/GetterSetter.cpp \
     98        JavaScriptCore/kjs/GlobalEvalFunction.cpp \
     99        JavaScriptCore/kjs/identifier.cpp \
     100        JavaScriptCore/kjs/IndexToNameMap.cpp \
     101        JavaScriptCore/kjs/InternalFunction.cpp \
     102        JavaScriptCore/kjs/interpreter.cpp \
     103        JavaScriptCore/kjs/JSArray.cpp \
    101104        JavaScriptCore/kjs/JSCell.cpp \
    102105        JavaScriptCore/kjs/JSFunction.cpp \
     106        JavaScriptCore/kjs/JSGlobalObject.cpp \
     107        JavaScriptCore/kjs/JSGlobalObjectFunctions.cpp \
     108        JavaScriptCore/kjs/JSImmediate.cpp \
     109        JavaScriptCore/kjs/JSLock.cpp \
    103110        JavaScriptCore/kjs/JSNumberCell.cpp \
     111        JavaScriptCore/kjs/JSObject.cpp \
    104112        JavaScriptCore/kjs/JSString.cpp \
     113        JavaScriptCore/kjs/JSValue.cpp \
    105114        JavaScriptCore/kjs/JSVariableObject.cpp \
    106         JavaScriptCore/kjs/FunctionConstructor.cpp \
    107         JavaScriptCore/kjs/FunctionPrototype.cpp \
    108         JavaScriptCore/kjs/identifier.cpp \
    109         JavaScriptCore/kjs/InternalFunction.cpp \
    110         JavaScriptCore/kjs/interpreter.cpp \
     115        JavaScriptCore/kjs/JSWrapperObject.cpp \
    111116        JavaScriptCore/kjs/LabelStack.cpp \
    112117        JavaScriptCore/kjs/lexer.cpp \
     
    114119        JavaScriptCore/kjs/lookup.cpp \
    115120        JavaScriptCore/kjs/MathObject.cpp \
     121        JavaScriptCore/kjs/NativeErrorConstructor.cpp \
     122        JavaScriptCore/kjs/NativeErrorPrototype.cpp \
    116123        JavaScriptCore/kjs/nodes.cpp \
    117124        JavaScriptCore/kjs/nodes2string.cpp \
    118         JavaScriptCore/kjs/NativeErrorConstructor.cpp \
    119         JavaScriptCore/kjs/NativeErrorPrototype.cpp \
    120125        JavaScriptCore/kjs/NumberConstructor.cpp \
    121126        JavaScriptCore/kjs/NumberObject.cpp \
    122127        JavaScriptCore/kjs/NumberPrototype.cpp \
    123         JavaScriptCore/kjs/JSObject.cpp \
    124         JavaScriptCore/kjs/JSGlobalObject.cpp \
    125128        JavaScriptCore/kjs/ObjectConstructor.cpp \
    126129        JavaScriptCore/kjs/ObjectPrototype.cpp \
    127130        JavaScriptCore/kjs/operations.cpp \
     131        JavaScriptCore/kjs/Parser.cpp \
    128132        JavaScriptCore/kjs/PropertyMap.cpp \
     133        JavaScriptCore/kjs/PropertyNameArray.cpp \
    129134        JavaScriptCore/kjs/PropertySlot.cpp \
     135        JavaScriptCore/kjs/PrototypeFunction.cpp \
    130136        JavaScriptCore/kjs/regexp.cpp \
    131137        JavaScriptCore/kjs/RegExpConstructor.cpp \
     
    137143        JavaScriptCore/kjs/StringPrototype.cpp \
    138144        JavaScriptCore/kjs/ustring.cpp \
    139         JavaScriptCore/kjs/JSValue.cpp \
    140145        JavaScriptCore/wtf/FastMalloc.cpp \
    141146        JavaScriptCore/wtf/TCSystemAlloc.cpp \
  • trunk/JavaScriptCore/JavaScriptCore.pri

    r35007 r35016  
    6262# Other compilers may be able to do this at link time
    6363SOURCES += \
    64     kjs/JSFunction.cpp \
    65     kjs/debugger.cpp \
    66     kjs/JSArray.cpp \
     64    kjs/Arguments.cpp \
    6765    kjs/ArrayConstructor.cpp \
    6866    kjs/ArrayPrototype.cpp \
     
    7270    kjs/collector.cpp \
    7371    kjs/CommonIdentifiers.cpp \
     72    kjs/DateConstructor.cpp \
    7473    kjs/DateInstance.cpp \
    75     kjs/DateConstructor.cpp \
    7674    kjs/DateMath.cpp \
    7775    kjs/DatePrototype.cpp \
     76    kjs/debugger.cpp \
    7877    kjs/DebuggerCallFrame.cpp \
    7978    kjs/dtoa.cpp \
     
    8685    kjs/FunctionPrototype.cpp \
    8786    kjs/GetterSetter.cpp \
     87    kjs/GlobalEvalFunction.cpp \
    8888    kjs/identifier.cpp \
     89    kjs/IndexToNameMap.cpp \
    8990    kjs/InternalFunction.cpp \
    9091    kjs/interpreter.cpp \
     92    kjs/JSArray.cpp \
    9193    kjs/JSCell.cpp \
     94    kjs/JSFunction.cpp \
     95    kjs/JSGlobalObjectFunctions.cpp \
    9296    kjs/JSImmediate.cpp \
    9397    kjs/JSLock.cpp \
    9498    kjs/JSNumberCell.cpp \
     99    kjs/JSObject.cpp \
    95100    kjs/JSString.cpp \
     101    kjs/JSValue.cpp \
    96102    kjs/JSWrapperObject.cpp \
    97103    kjs/LabelStack.cpp \
     
    107113    kjs/NumberObject.cpp \
    108114    kjs/NumberPrototype.cpp \
    109     kjs/JSObject.cpp \
    110115    kjs/ObjectConstructor.cpp \
    111116    kjs/ObjectPrototype.cpp \
     
    113118    kjs/Parser.cpp \
    114119    kjs/PropertyMap.cpp \
     120    kjs/PropertyNameArray.cpp \
    115121    kjs/PropertySlot.cpp \
    116     kjs/PropertyNameArray.cpp \
     122    kjs/PrototypeFunction.cpp \
    117123    kjs/regexp.cpp \
    118124    kjs/RegExpConstructor.cpp \
     
    124130    kjs/StringPrototype.cpp \
    125131    kjs/ustring.cpp \
    126     kjs/JSValue.cpp \
     132    profiler/Profile.cpp \
    127133    profiler/ProfileNode.cpp \
    128     profiler/Profile.cpp \
    129134    profiler/Profiler.cpp \
    130135    profiler/TreeProfile.cpp \
  • trunk/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj

    r35007 r35016  
    274274                        </File>
    275275                        <File
     276                                RelativePath="..\..\kjs\Arguments.cpp"
     277                                >
     278                        </File>
     279                        <File
     280                                RelativePath="..\..\kjs\Arguments.h"
     281                                >
     282                        </File>
     283                        <File
    276284                                RelativePath="..\..\kjs\ArrayConstructor.cpp"
    277285                                >
     
    450458                        </File>
    451459                        <File
     460                                RelativePath="..\..\kjs\GlobalEvalFunction.cpp"
     461                                >
     462                        </File>
     463                        <File
     464                                RelativePath="..\..\kjs\GlobalEvalFunction.h"
     465                                >
     466                        </File>
     467                        <File
    452468                                RelativePath="..\..\kjs\identifier.cpp"
    453469                                >
     
    458474                        </File>
    459475                        <File
     476                                RelativePath="..\..\kjs\IndexToNameMap.cpp"
     477                                >
     478                        </File>
     479                        <File
     480                                RelativePath="..\..\kjs\IndexToNameMap.h"
     481                                >
     482                        </File>
     483                        <File
    460484                                RelativePath="..\..\kjs\InitializeThreading.cpp"
    461485                                >
     
    530554                        </File>
    531555                        <File
     556                                RelativePath="..\..\kjs\JSGlobalObjectFunctions.cpp"
     557                                >
     558                        </File>
     559                        <File
     560                                RelativePath="..\..\kjs\JSGlobalObjectFunctions.h"
     561                                >
     562                        </File>
     563                        <File
    532564                                RelativePath="..\..\kjs\JSImmediate.cpp"
    533565                                >
     
    731763                        <File
    732764                                RelativePath="..\..\kjs\protect.h"
     765                                >
     766                        </File>
     767                        <File
     768                                RelativePath="..\..\kjs\PrototypeFunction.cpp"
     769                                >
     770                        </File>
     771                        <File
     772                                RelativePath="..\..\kjs\PrototypeFunction.h"
    733773                                >
    734774                        </File>
  • trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r35011 r35016  
    254254                BC18C52E0E16FCE100B34460 /* lexer.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C52D0E16FCE100B34460 /* lexer.lut.h */; };
    255255                BC18C5300E16FCEB00B34460 /* grammar.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C52F0E16FCEB00B34460 /* grammar.h */; };
     256                BC257DE80E1F51C50016B6C9 /* Arguments.h in Headers */ = {isa = PBXBuildFile; fileRef = BC257DE60E1F51C50016B6C9 /* Arguments.h */; };
     257                BC257DEC0E1F52BA0016B6C9 /* IndexToNameMap.h in Headers */ = {isa = PBXBuildFile; fileRef = BC257DEA0E1F52BA0016B6C9 /* IndexToNameMap.h */; };
     258                BC257DF00E1F52ED0016B6C9 /* GlobalEvalFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = BC257DEE0E1F52ED0016B6C9 /* GlobalEvalFunction.h */; };
     259                BC257DF40E1F53740016B6C9 /* PrototypeFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = BC257DF20E1F53740016B6C9 /* PrototypeFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
    256260                BC3046070E1F497F003232CF /* Error.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3046060E1F497F003232CF /* Error.h */; settings = {ATTRIBUTES = (Private, ); }; };
    257261                BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
     262                BC756FC90E2031B200DE7D12 /* JSGlobalObjectFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */; };
    258263                BC7F8FB90E19D1C3008632C0 /* JSNumberCell.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7F8FB80E19D1C3008632C0 /* JSNumberCell.h */; settings = {ATTRIBUTES = (Private, ); }; };
    259264                BCD202C20E1706A7002C7E82 /* RegExpConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD202BE0E1706A7002C7E82 /* RegExpConstructor.h */; };
     
    634639                BC22A3990E16E14800AF21C8 /* JSObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSObject.h; sourceTree = "<group>"; };
    635640                BC22A39A0E16E14800AF21C8 /* JSVariableObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSVariableObject.cpp; sourceTree = "<group>"; };
     641                BC257DE50E1F51C50016B6C9 /* Arguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Arguments.cpp; sourceTree = "<group>"; };
     642                BC257DE60E1F51C50016B6C9 /* Arguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Arguments.h; sourceTree = "<group>"; };
     643                BC257DE90E1F52BA0016B6C9 /* IndexToNameMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IndexToNameMap.cpp; sourceTree = "<group>"; };
     644                BC257DEA0E1F52BA0016B6C9 /* IndexToNameMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IndexToNameMap.h; sourceTree = "<group>"; };
     645                BC257DED0E1F52ED0016B6C9 /* GlobalEvalFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GlobalEvalFunction.cpp; sourceTree = "<group>"; };
     646                BC257DEE0E1F52ED0016B6C9 /* GlobalEvalFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlobalEvalFunction.h; sourceTree = "<group>"; };
     647                BC257DF10E1F53740016B6C9 /* PrototypeFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrototypeFunction.cpp; sourceTree = "<group>"; };
     648                BC257DF20E1F53740016B6C9 /* PrototypeFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrototypeFunction.h; sourceTree = "<group>"; };
    636649                BC2680C00E16D4E900A06E92 /* FunctionConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionConstructor.cpp; sourceTree = "<group>"; };
    637650                BC2680C10E16D4E900A06E92 /* FunctionConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionConstructor.h; sourceTree = "<group>"; };
     
    649662                BC337BEA0E1B00CB0076918A /* Error.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Error.cpp; sourceTree = "<group>"; };
    650663                BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClassInfo.h; sourceTree = "<group>"; };
     664                BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalObjectFunctions.cpp; sourceTree = "<group>"; };
     665                BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObjectFunctions.h; sourceTree = "<group>"; };
    651666                BC7952060E15E8A800A898AB /* ArrayConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayConstructor.cpp; sourceTree = "<group>"; };
    652667                BC7952070E15E8A800A898AB /* ArrayConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayConstructor.h; sourceTree = "<group>"; };
     
    10501065                        children = (
    10511066                                659126BC0BDD1728001921FB /* AllInOneFile.cpp */,
     1067                                BC257DE50E1F51C50016B6C9 /* Arguments.cpp */,
     1068                                BC257DE60E1F51C50016B6C9 /* Arguments.h */,
    10521069                                BC7952060E15E8A800A898AB /* ArrayConstructor.cpp */,
    10531070                                BC7952070E15E8A800A898AB /* ArrayConstructor.h */,
     
    10991116                                BC02E9B80E184545000F9297 /* GetterSetter.cpp */,
    11001117                                BC337BDE0E1AF0B80076918A /* GetterSetter.h */,
     1118                                BC257DED0E1F52ED0016B6C9 /* GlobalEvalFunction.cpp */,
     1119                                BC257DEE0E1F52ED0016B6C9 /* GlobalEvalFunction.h */,
    11011120                                933A349D038AE80F008635CE /* identifier.cpp */,
    11021121                                933A349A038AE7C6008635CE /* identifier.h */,
     1122                                BC257DE90E1F52BA0016B6C9 /* IndexToNameMap.cpp */,
     1123                                BC257DEA0E1F52BA0016B6C9 /* IndexToNameMap.h */,
    11031124                                E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */,
    11041125                                E178633F0D9BEC0000D74E75 /* InitializeThreading.h */,
     
    11191140                                14DE0D680D02431400AACCA2 /* JSGlobalObject.cpp */,
    11201141                                A8E894330CD0603F00367179 /* JSGlobalObject.h */,
     1142                                BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */,
     1143                                BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */,
    11211144                                14760863099C633800437128 /* JSImmediate.cpp */,
    11221145                                1483B589099BC1950016E4F0 /* JSImmediate.h */,
     
    11691192                                65621E6B089E859700760F35 /* PropertySlot.cpp */,
    11701193                                65621E6C089E859700760F35 /* PropertySlot.h */,
     1194                                BC257DF10E1F53740016B6C9 /* PrototypeFunction.cpp */,
     1195                                BC257DF20E1F53740016B6C9 /* PrototypeFunction.h */,
    11711196                                65C02FBB0637462A003E7EE6 /* protect.h */,
    11721197                                F692A87D0255597D01FF60F7 /* regexp.cpp */,
     
    14561481                                BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */,
    14571482                                BC3046070E1F497F003232CF /* Error.h in Headers */,
     1483                                BC257DE80E1F51C50016B6C9 /* Arguments.h in Headers */,
     1484                                BC257DEC0E1F52BA0016B6C9 /* IndexToNameMap.h in Headers */,
     1485                                BC257DF00E1F52ED0016B6C9 /* GlobalEvalFunction.h in Headers */,
     1486                                BC257DF40E1F53740016B6C9 /* PrototypeFunction.h in Headers */,
     1487                                BC756FC90E2031B200DE7D12 /* JSGlobalObjectFunctions.h in Headers */,
    14581488                        );
    14591489                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/JavaScriptCore/JavaScriptCoreSources.bkl

    r35007 r35016  
    4444    <set append="1" var="JSCORE_SOURCES_KJS">
    4545        DerivedSources/JavaScriptCore/grammar.cpp
    46         kjs/JSArray.cpp
     46        kjs/Arguments.cpp
    4747        kjs/ArrayConstructor.cpp
    4848        kjs/ArrayPrototype.cpp
     
    5252        kjs/collector.cpp
    5353        kjs/CommonIdentifiers.cpp
     54        kjs/DateConstructor.cpp
    5455        kjs/DateInstance.cpp
    55         kjs/DateConstructor.cpp
    5656        kjs/DateMath.cpp
    5757        kjs/DatePrototype.cpp
     
    6464        kjs/ErrorPrototype.cpp
    6565        kjs/ExecState.cpp
    66         kjs/GetterSetter.cpp
    67         kjs/JSFunction.cpp
    6866        kjs/FunctionConstructor.cpp
    6967        kjs/FunctionPrototype.cpp
     68        kjs/GetterSetter.cpp
     69        kjs/GlobalEvalFunction.cpp
    7070        kjs/identifier.cpp
     71        kjs/IndexToNameMap.cpp
    7172        kjs/InitializeThreading.cpp
    7273        kjs/InternalFunction.cpp
    7374        kjs/interpreter.cpp
    7475        kjs/JSActivation.cpp
     76        kjs/JSArray.cpp
    7577        kjs/JSCell.cpp
     78        kjs/JSFunction.cpp
    7679        kjs/JSGlobalData.cpp
    7780        kjs/JSGlobalObject.cpp
    78         kjs/JSVariableObject.cpp
     81        kjs/JSGlobalObjectFunctions.cpp
    7982        kjs/JSImmediate.cpp
    8083        kjs/JSLock.cpp
    8184        kjs/JSNotAnObject.cpp
    8285        kjs/JSNumberCell.cpp
     86        kjs/JSObject.cpp
    8387        kjs/JSString.cpp
     88        kjs/JSValue.cpp
     89        kjs/JSVariableObject.cpp
    8490        kjs/JSWrapperObject.cpp
    8591        kjs/LabelStack.cpp
     
    95101        kjs/NumberObject.cpp
    96102        kjs/NumberPrototype.cpp
    97         kjs/JSObject.cpp
    98103        kjs/ObjectConstructor.cpp
    99104        kjs/ObjectPrototype.cpp
     
    101106        kjs/Parser.cpp
    102107        kjs/PropertyMap.cpp
     108        kjs/PropertyNameArray.cpp
    103109        kjs/PropertySlot.cpp
    104         kjs/PropertyNameArray.cpp
     110        kjs/PrototypeFunction.cpp
    105111        kjs/regexp.cpp
    106112        kjs/RegExpConstructor.cpp
     
    112118        kjs/StringPrototype.cpp
    113119        kjs/ustring.cpp
    114         kjs/JSValue.cpp
    115120
    116121    </set>
  • trunk/JavaScriptCore/VM/Machine.cpp

    r34981 r35016  
    3535#include "ExceptionHelpers.h"
    3636#include "ExecState.h"
     37#include "GlobalEvalFunction.h"
    3738#include "JSActivation.h"
    3839#include "JSArray.h"
  • trunk/JavaScriptCore/kjs/AllInOneFile.cpp

    r35007 r35016  
    11/*
    2  *  Copyright (C) 2006 Apple Inc. All rights reserved.
     2 *  Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
    33 *
    44 *  This library is free software; you can redistribute it and/or
     
    2828
    2929#include "JSFunction.cpp"
     30#include "IndexToNameMap.cpp"
     31#include "Arguments.cpp"
     32#include "JSGlobalObjectFunctions.cpp"
     33#include "PrototypeFunction.cpp"
     34#include "GlobalEvalFunction.cpp"
    3035#include "debugger.cpp"
    3136#include "JSArray.cpp"
  • trunk/JavaScriptCore/kjs/Arguments.cpp

    r35006 r35016  
    1 // -*- c-basic-offset: 2 -*-
    21/*
    32 *  Copyright (C) 1999-2002 Harri Porten ([email protected])
     
    2524
    2625#include "config.h"
     26#include "Arguments.h"
     27
    2728#include "JSFunction.h"
    28 
    29 #include "ExecState.h"
    30 #include "FunctionPrototype.h"
     29#include "JSGlobalObject.h"
    3130#include "JSActivation.h"
    32 #include "JSGlobalObject.h"
    33 #include "JSString.h"
    34 #include "Machine.h"
    35 #include "ObjectPrototype.h"
    36 #include "Parser.h"
    37 #include "PropertyNameArray.h"
    38 #include "ScopeChainMark.h"
    39 #include "debugger.h"
    40 #include "dtoa.h"
    41 #include "lexer.h"
    42 #include "nodes.h"
    43 #include "operations.h"
    44 #include <errno.h>
    45 #include <profiler/Profiler.h>
    46 #include <stdio.h>
    47 #include <stdlib.h>
    48 #include <string.h>
    49 #include <wtf/ASCIICType.h>
    50 #include <wtf/Assertions.h>
    51 #include <wtf/MathExtras.h>
    52 #include <wtf/unicode/UTF8.h>
    53 
    54 using namespace WTF;
    55 using namespace Unicode;
    5631
    5732namespace KJS {
    58 
    59 // ----------------------------- JSFunction ----------------------------------
    60 
    61 const ClassInfo JSFunction::info = { "Function", &InternalFunction::info, 0, 0 };
    62 
    63 JSFunction::JSFunction(ExecState* exec, const Identifier& name, FunctionBodyNode* b, ScopeChainNode* scopeChain)
    64   : InternalFunction(exec->lexicalGlobalObject()->functionPrototype(), name)
    65   , body(b)
    66   , _scope(scopeChain)
    67 {
    68 }
    69 
    70 void JSFunction::mark()
    71 {
    72     InternalFunction::mark();
    73     body->mark();
    74     _scope.mark();
    75 }
    76 
    77 CallType JSFunction::getCallData(CallData& callData)
    78 {
    79     callData.js.functionBody = body.get();
    80     callData.js.scopeChain = _scope.node();
    81     return CallTypeJS;
    82 }
    83 
    84 JSValue* JSFunction::call(ExecState* exec, JSValue* thisValue, const ArgList& args)
    85 {
    86     return exec->machine()->execute(body.get(), exec, this, thisValue->toThisObject(exec), args, _scope.node(), exec->exceptionSlot());
    87 }
    88 
    89 JSValue* JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    90 {
    91     JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
    92     return exec->machine()->retrieveArguments(exec, thisObj);
    93 }
    94 
    95 JSValue* JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    96 {
    97     JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
    98     return exec->machine()->retrieveCaller(exec, thisObj);
    99 }
    100 
    101 JSValue* JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    102 {
    103     JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
    104     return jsNumber(exec, thisObj->body->parameters().size());
    105 }
    106 
    107 bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
    108 {
    109     if (propertyName == exec->propertyNames().arguments) {
    110         slot.setCustom(this, argumentsGetter);
    111         return true;
    112     }
    113 
    114     if (propertyName == exec->propertyNames().length) {
    115         slot.setCustom(this, lengthGetter);
    116         return true;
    117     }
    118 
    119     if (propertyName == exec->propertyNames().caller) {
    120         slot.setCustom(this, callerGetter);
    121         return true;
    122     }
    123 
    124     return InternalFunction::getOwnPropertySlot(exec, propertyName, slot);
    125 }
    126 
    127 void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
    128 {
    129     if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
    130         return;
    131     InternalFunction::put(exec, propertyName, value);
    132 }
    133 
    134 bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
    135 {
    136     if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
    137         return false;
    138     return InternalFunction::deleteProperty(exec, propertyName);
    139 }
    140 
    141 /* Returns the parameter name corresponding to the given index. eg:
    142  * function f1(x, y, z): getParameterName(0) --> x
    143  *
    144  * If a name appears more than once, only the last index at which
    145  * it appears associates with it. eg:
    146  * function f2(x, x): getParameterName(0) --> null
    147  */
    148 const Identifier& JSFunction::getParameterName(int index)
    149 {
    150     Vector<Identifier>& parameters = body->parameters();
    151 
    152     if (static_cast<size_t>(index) >= body->parameters().size())
    153         return _scope.globalObject()->globalData()->propertyNames->nullIdentifier;
    154  
    155     const Identifier& name = parameters[index];
    156 
    157     // Are there any subsequent parameters with the same name?
    158     size_t size = parameters.size();
    159     for (size_t i = index + 1; i < size; ++i)
    160         if (parameters[i] == name)
    161             return _scope.globalObject()->globalData()->propertyNames->nullIdentifier;
    162 
    163     return name;
    164 }
    165 
    166 // ECMA 13.2.2 [[Construct]]
    167 ConstructType JSFunction::getConstructData(ConstructData& constructData)
    168 {
    169     constructData.js.functionBody = body.get();
    170     constructData.js.scopeChain = _scope.node();
    171     return ConstructTypeJS;
    172 }
    173 
    174 JSObject* JSFunction::construct(ExecState* exec, const ArgList& args)
    175 {
    176     JSObject* proto;
    177     JSValue* p = get(exec, exec->propertyNames().prototype);
    178     if (p->isObject())
    179         proto = static_cast<JSObject*>(p);
    180     else
    181         proto = exec->lexicalGlobalObject()->objectPrototype();
    182 
    183     JSObject* thisObj = new (exec) JSObject(proto);
    184 
    185     JSValue* result = exec->machine()->execute(body.get(), exec, this, thisObj, args, _scope.node(), exec->exceptionSlot());
    186     if (exec->hadException() || !result->isObject())
    187         return thisObj;
    188     return static_cast<JSObject*>(result);
    189 }
    190 
    191 // ------------------------------ IndexToNameMap ---------------------------------
    192 
    193 // We map indexes in the arguments array to their corresponding argument names.
    194 // Example: function f(x, y, z): arguments[0] = x, so we map 0 to Identifier("x").
    195 
    196 // Once we have an argument name, we can get and set the argument's value in the
    197 // activation object.
    198 
    199 // We use Identifier::null to indicate that a given argument's value
    200 // isn't stored in the activation object.
    201 
    202 IndexToNameMap::IndexToNameMap(JSFunction* func, const ArgList& args)
    203 {
    204   _map = new Identifier[args.size()];
    205   this->size = args.size();
    206  
    207   unsigned i = 0;
    208   ArgList::const_iterator end = args.end();
    209   for (ArgList::const_iterator it = args.begin(); it != end; ++i, ++it)
    210     _map[i] = func->getParameterName(i); // null if there is no corresponding parameter
    211 }
    212 
    213 IndexToNameMap::~IndexToNameMap()
    214 {
    215   delete [] _map;
    216 }
    217 
    218 bool IndexToNameMap::isMapped(const Identifier& index) const
    219 {
    220   bool indexIsNumber;
    221   unsigned indexAsNumber = index.toStrictUInt32(&indexIsNumber);
    222  
    223   if (!indexIsNumber)
    224     return false;
    225  
    226   if (indexAsNumber >= size)
    227     return false;
    228 
    229   if (_map[indexAsNumber].isNull())
    230     return false;
    231  
    232   return true;
    233 }
    234 
    235 void IndexToNameMap::unMap(ExecState* exec, const Identifier& index)
    236 {
    237   bool indexIsNumber;
    238   unsigned indexAsNumber = index.toStrictUInt32(&indexIsNumber);
    239 
    240   ASSERT(indexIsNumber && indexAsNumber < size);
    241  
    242   _map[indexAsNumber] = exec->propertyNames().nullIdentifier;
    243 }
    244 
    245 Identifier& IndexToNameMap::operator[](const Identifier& index)
    246 {
    247   bool indexIsNumber;
    248   unsigned indexAsNumber = index.toStrictUInt32(&indexIsNumber);
    249 
    250   ASSERT(indexIsNumber && indexAsNumber < size);
    251  
    252   return _map[indexAsNumber];
    253 }
    254 
    255 // ------------------------------ Arguments ---------------------------------
    25633
    25734const ClassInfo Arguments::info = { "Arguments", 0, 0, 0 };
     
    31693}
    31794
    318 // ------------------------------ Global Functions -----------------------------------
    319 
    320 static JSValue* encode(ExecState* exec, const ArgList& args, const char* do_not_escape)
    321 {
    322   UString r = "", s, str = args[0]->toString(exec);
    323   CString cstr = str.UTF8String(true);
    324   if (!cstr.c_str())
    325     return throwError(exec, URIError, "String contained an illegal UTF-16 sequence.");
    326   const char* p = cstr.c_str();
    327   for (size_t k = 0; k < cstr.size(); k++, p++) {
    328     char c = *p;
    329     if (c && strchr(do_not_escape, c)) {
    330       r.append(c);
    331     } else {
    332       char tmp[4];
    333       sprintf(tmp, "%%%02X", (unsigned char)c);
    334       r += tmp;
    335     }
    336   }
    337   return jsString(exec, r);
    338 }
    339 
    340 static JSValue* decode(ExecState* exec, const ArgList& args, const char* do_not_unescape, bool strict)
    341 {
    342   UString s = "", str = args[0]->toString(exec);
    343   int k = 0, len = str.size();
    344   const UChar* d = str.data();
    345   UChar u = 0;
    346   while (k < len) {
    347     const UChar* p = d + k;
    348     UChar c = *p;
    349     if (c == '%') {
    350       int charLen = 0;
    351       if (k <= len - 3 && isASCIIHexDigit(p[1]) && isASCIIHexDigit(p[2])) {
    352         const char b0 = Lexer::convertHex(p[1], p[2]);
    353         const int sequenceLen = UTF8SequenceLength(b0);
    354         if (sequenceLen != 0 && k <= len - sequenceLen * 3) {
    355           charLen = sequenceLen * 3;
    356           char sequence[5];
    357           sequence[0] = b0;
    358           for (int i = 1; i < sequenceLen; ++i) {
    359             const UChar* q = p + i * 3;
    360             if (q[0] == '%' && isASCIIHexDigit(q[1]) && isASCIIHexDigit(q[2]))
    361               sequence[i] = Lexer::convertHex(q[1], q[2]);
    362             else {
    363               charLen = 0;
    364               break;
    365             }
    366           }
    367           if (charLen != 0) {
    368             sequence[sequenceLen] = 0;
    369             const int character = decodeUTF8Sequence(sequence);
    370             if (character < 0 || character >= 0x110000) {
    371               charLen = 0;
    372             } else if (character >= 0x10000) {
    373               // Convert to surrogate pair.
    374               s.append(static_cast<UChar>(0xD800 | ((character - 0x10000) >> 10)));
    375               u = static_cast<UChar>(0xDC00 | ((character - 0x10000) & 0x3FF));
    376             } else {
    377               u = static_cast<UChar>(character);
    378             }
    379           }
    380         }
    381       }
    382       if (charLen == 0) {
    383         if (strict)
    384           return throwError(exec, URIError);
    385         // The only case where we don't use "strict" mode is the "unescape" function.
    386         // For that, it's good to support the wonky "%u" syntax for compatibility with WinIE.
    387         if (k <= len - 6 && p[1] == 'u'
    388             && isASCIIHexDigit(p[2]) && isASCIIHexDigit(p[3])
    389             && isASCIIHexDigit(p[4]) && isASCIIHexDigit(p[5])) {
    390           charLen = 6;
    391           u = Lexer::convertUnicode(p[2], p[3], p[4], p[5]);
    392         }
    393       }
    394       if (charLen && (u == 0 || u >= 128 || !strchr(do_not_unescape, u))) {
    395         c = u;
    396         k += charLen - 1;
    397       }
    398     }
    399     k++;
    400     s.append(c);
    401   }
    402   return jsString(exec, s);
    403 }
    404 
    405 static bool isStrWhiteSpace(unsigned short c)
    406 {
    407     switch (c) {
    408         case 0x0009:
    409         case 0x000A:
    410         case 0x000B:
    411         case 0x000C:
    412         case 0x000D:
    413         case 0x0020:
    414         case 0x00A0:
    415         case 0x2028:
    416         case 0x2029:
    417             return true;
    418         default:
    419             return c > 0xff && isSeparatorSpace(c);
    420     }
    421 }
    422 
    423 static int parseDigit(unsigned short c, int radix)
    424 {
    425     int digit = -1;
    426 
    427     if (c >= '0' && c <= '9') {
    428         digit = c - '0';
    429     } else if (c >= 'A' && c <= 'Z') {
    430         digit = c - 'A' + 10;
    431     } else if (c >= 'a' && c <= 'z') {
    432         digit = c - 'a' + 10;
    433     }
    434 
    435     if (digit >= radix)
    436         return -1;
    437     return digit;
    438 }
    439 
    440 double parseIntOverflow(const char* s, int length, int radix)
    441 {
    442     double number = 0.0;
    443     double radixMultiplier = 1.0;
    444 
    445     for (const char* p = s + length - 1; p >= s; p--) {
    446         if (radixMultiplier == Inf) {
    447             if (*p != '0') {
    448                 number = Inf;
    449                 break;
    450             }
    451         } else {
    452             int digit = parseDigit(*p, radix);
    453             number += digit * radixMultiplier;
    454         }
    455 
    456         radixMultiplier *= radix;
    457     }
    458 
    459     return number;
    460 }
    461 
    462 static double parseInt(const UString& s, int radix)
    463 {
    464     int length = s.size();
    465     int p = 0;
    466 
    467     while (p < length && isStrWhiteSpace(s[p])) {
    468         ++p;
    469     }
    470 
    471     double sign = 1;
    472     if (p < length) {
    473         if (s[p] == '+') {
    474             ++p;
    475         } else if (s[p] == '-') {
    476             sign = -1;
    477             ++p;
    478         }
    479     }
    480 
    481     if ((radix == 0 || radix == 16) && length - p >= 2 && s[p] == '0' && (s[p + 1] == 'x' || s[p + 1] == 'X')) {
    482         radix = 16;
    483         p += 2;
    484     } else if (radix == 0) {
    485         if (p < length && s[p] == '0')
    486             radix = 8;
    487         else
    488             radix = 10;
    489     }
    490 
    491     if (radix < 2 || radix > 36)
    492         return NaN;
    493 
    494     int firstDigitPosition = p;
    495     bool sawDigit = false;
    496     double number = 0;
    497     while (p < length) {
    498         int digit = parseDigit(s[p], radix);
    499         if (digit == -1)
    500             break;
    501         sawDigit = true;
    502         number *= radix;
    503         number += digit;
    504         ++p;
    505     }
    506 
    507     if (number >= mantissaOverflowLowerBound) {
    508         if (radix == 10)
    509             number = strtod(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), 0);
    510         else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32)
    511             number = parseIntOverflow(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), p - firstDigitPosition, radix);
    512     }
    513 
    514     if (!sawDigit)
    515         return NaN;
    516 
    517     return sign * number;
    518 }
    519 
    520 static double parseFloat(const UString& s)
    521 {
    522     // Check for 0x prefix here, because toDouble allows it, but we must treat it as 0.
    523     // Need to skip any whitespace and then one + or - sign.
    524     int length = s.size();
    525     int p = 0;
    526     while (p < length && isStrWhiteSpace(s[p])) {
    527         ++p;
    528     }
    529     if (p < length && (s[p] == '+' || s[p] == '-')) {
    530         ++p;
    531     }
    532     if (length - p >= 2 && s[p] == '0' && (s[p + 1] == 'x' || s[p + 1] == 'X')) {
    533         return 0;
    534     }
    535 
    536     return s.toDouble( true /*tolerant*/, false /* NaN for empty string */ );
    537 }
    538 
    539 JSValue* globalFuncEval(ExecState* exec, JSObject* function, JSValue* thisValue, const ArgList& args)
    540 {
    541     JSObject* thisObject = thisValue->toThisObject(exec);
    542     JSGlobalObject* globalObject = thisObject->toGlobalObject(exec);
    543     if (!globalObject || globalObject->evalFunction() != function)
    544         return throwError(exec, EvalError, "The \"this\" value passed to eval must be the global object from which eval originated");
    545 
    546     JSValue* x = args[0];
    547     if (!x->isString())
    548         return x;
    549    
    550     UString s = x->toString(exec);
    551    
    552     int sourceId;
    553     int errLine;
    554     UString errMsg;
    555 
    556     RefPtr<EvalNode> evalNode = exec->parser()->parse<EvalNode>(exec, UString(), 1, UStringSourceProvider::create(s), &sourceId, &errLine, &errMsg);
    557    
    558     if (!evalNode)
    559         return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL);
    560 
    561     return exec->machine()->execute(evalNode.get(), exec, thisObject, globalObject->globalScopeChain().node(), exec->exceptionSlot());
    562 }
    563 
    564 JSValue* globalFuncParseInt(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    565 {
    566     return jsNumber(exec, parseInt(args[0]->toString(exec), args[1]->toInt32(exec)));
    567 }
    568 
    569 JSValue* globalFuncParseFloat(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    570 {
    571     return jsNumber(exec, parseFloat(args[0]->toString(exec)));
    572 }
    573 
    574 JSValue* globalFuncIsNaN(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    575 {
    576     return jsBoolean(isnan(args[0]->toNumber(exec)));
    577 }
    578 
    579 JSValue* globalFuncIsFinite(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    580 {
    581     double n = args[0]->toNumber(exec);
    582     return jsBoolean(!isnan(n) && !isinf(n));
    583 }
    584 
    585 JSValue* globalFuncDecodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    586 {
    587     static const char do_not_unescape_when_decoding_URI[] =
    588         "#$&+,/:;=?@";
    589 
    590     return decode(exec, args, do_not_unescape_when_decoding_URI, true);
    591 }
    592 
    593 JSValue* globalFuncDecodeURIComponent(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    594 {
    595     return decode(exec, args, "", true);
    596 }
    597 
    598 JSValue* globalFuncEncodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    599 {
    600     static const char do_not_escape_when_encoding_URI[] =
    601         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    602         "abcdefghijklmnopqrstuvwxyz"
    603         "0123456789"
    604         "!#$&'()*+,-./:;=?@_~";
    605 
    606     return encode(exec, args, do_not_escape_when_encoding_URI);
    607 }
    608 
    609 JSValue* globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    610 {
    611     static const char do_not_escape_when_encoding_URI_component[] =
    612         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    613         "abcdefghijklmnopqrstuvwxyz"
    614         "0123456789"
    615         "!'()*-._~";
    616 
    617     return encode(exec, args, do_not_escape_when_encoding_URI_component);
    618 }
    619 
    620 JSValue* globalFuncEscape(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    621 {
    622     static const char do_not_escape[] =
    623         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    624         "abcdefghijklmnopqrstuvwxyz"
    625         "0123456789"
    626         "*+-./@_";
    627 
    628     UString r = "", s, str = args[0]->toString(exec);
    629     const UChar* c = str.data();
    630     for (int k = 0; k < str.size(); k++, c++) {
    631         int u = c[0];
    632         if (u > 255) {
    633             char tmp[7];
    634             sprintf(tmp, "%%u%04X", u);
    635             s = UString(tmp);
    636         } else if (u != 0 && strchr(do_not_escape, (char)u))
    637             s = UString(c, 1);
    638         else {
    639             char tmp[4];
    640             sprintf(tmp, "%%%02X", u);
    641             s = UString(tmp);
    642         }
    643         r += s;
    644     }
    645 
    646     return jsString(exec, r);
    647 }
    648 
    649 JSValue* globalFuncUnescape(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    650 {
    651     UString s = "", str = args[0]->toString(exec);
    652     int k = 0, len = str.size();
    653     while (k < len) {
    654         const UChar* c = str.data() + k;
    655         UChar u;
    656         if (c[0] == '%' && k <= len - 6 && c[1] == 'u') {
    657             if (Lexer::isHexDigit(c[2]) && Lexer::isHexDigit(c[3]) && Lexer::isHexDigit(c[4]) && Lexer::isHexDigit(c[5])) {
    658                 u = Lexer::convertUnicode(c[2], c[3], c[4], c[5]);
    659                 c = &u;
    660                 k += 5;
    661             }
    662         } else if (c[0] == '%' && k <= len - 3 && Lexer::isHexDigit(c[1]) && Lexer::isHexDigit(c[2])) {
    663             u = UChar(Lexer::convertHex(c[1], c[2]));
    664             c = &u;
    665             k += 2;
    666         }
    667         k++;
    668         s.append(*c);
    669     }
    670 
    671     return jsString(exec, s);
    672 }
    673 
    674 #ifndef NDEBUG
    675 JSValue* globalFuncKJSPrint(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    676 {
    677     CStringBuffer string;
    678     args[0]->toString(exec).getCString(string);
    679     puts(string.data());
    680     return jsUndefined();
    681 }
    682 #endif
    683 
    684 // ------------------------------ PrototypeFunction -------------------------------
    685 
    686 PrototypeFunction::PrototypeFunction(ExecState* exec, int len, const Identifier& name, NativeFunction function)
    687     : InternalFunction(exec->lexicalGlobalObject()->functionPrototype(), name)
    688     , m_function(function)
    689 {
    690     ASSERT_ARG(function, function);
    691     putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
    692 }
    693 
    694 PrototypeFunction::PrototypeFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, NativeFunction function)
    695     : InternalFunction(functionPrototype, name)
    696     , m_function(function)
    697 {
    698     ASSERT_ARG(function, function);
    699     putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
    700 }
    701 
    702 CallType PrototypeFunction::getCallData(CallData& callData)
    703 {
    704     callData.native.function = m_function;
    705     return CallTypeNative;
    706 }
    707 
    708 // ------------------------------ PrototypeReflexiveFunction -------------------------------
    709 
    710 GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, NativeFunction function, JSGlobalObject* cachedGlobalObject)
    711     : PrototypeFunction(exec, functionPrototype, len, name, function)
    712     , m_cachedGlobalObject(cachedGlobalObject)
    713 {
    714     ASSERT_ARG(cachedGlobalObject, cachedGlobalObject);
    715 }
    716 
    717 void GlobalEvalFunction::mark()
    718 {
    719     PrototypeFunction::mark();
    720     if (!m_cachedGlobalObject->marked())
    721         m_cachedGlobalObject->mark();
    722 }
    723 
    72495} // namespace KJS
  • trunk/JavaScriptCore/kjs/Arguments.h

    r35006 r35016  
    2222 */
    2323
    24 #ifndef JSFunction_h
    25 #define JSFunction_h
     24#ifndef Arguments_h
     25#define Arguments_h
    2626
    27 #include "InternalFunction.h"
    28 #include "JSVariableObject.h"
    29 #include "SymbolTable.h"
    30 #include "nodes.h"
     27#include "IndexToNameMap.h"
    3128#include "JSObject.h"
    3229
    3330namespace KJS {
    3431
    35   class FunctionBodyNode;
    36   class FunctionPrototype;
    3732  class JSActivation;
    38   class JSGlobalObject;
    3933
    40   class JSFunction : public InternalFunction {
    41   public:
    42     JSFunction(ExecState*, const Identifier&, FunctionBodyNode*, ScopeChainNode*);
    43 
    44     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    45     virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
    46     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    47 
    48     JSObject* construct(ExecState*, const ArgList&);
    49     JSValue* call(ExecState*, JSValue* thisValue, const ArgList&);
    50 
    51     // Note: Returns a null identifier for any parameters that will never get set
    52     // due to a later parameter with the same name.
    53     const Identifier& getParameterName(int index);
    54 
    55     static const ClassInfo info;
    56 
    57     RefPtr<FunctionBodyNode> body;
    58 
    59     void setScope(const ScopeChain& s) { _scope = s; }
    60     ScopeChain& scope() { return _scope; }
    61 
    62     virtual void mark();
    63 
    64   private:
    65     virtual const ClassInfo* classInfo() const { return &info; }
    66     virtual ConstructType getConstructData(ConstructData&);
    67     virtual CallType getCallData(CallData&);
    68 
    69     ScopeChain _scope;
    70 
    71     static JSValue* argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
    72     static JSValue* callerGetter(ExecState*, const Identifier&, const PropertySlot&);
    73     static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
    74   };
    75 
    76   class IndexToNameMap {
    77   public:
    78     IndexToNameMap(JSFunction*, const ArgList&);
    79     ~IndexToNameMap();
    80    
    81     Identifier& operator[](const Identifier& index);
    82     bool isMapped(const Identifier& index) const;
    83     void unMap(ExecState* exec, const Identifier& index);
    84    
    85   private:
    86     unsigned size;
    87     Identifier* _map;
    88   };
    89  
    9034  class Arguments : public JSObject {
    9135  public:
     
    10448  };
    10549
    106   class PrototypeFunction : public InternalFunction {
    107   public:
    108     PrototypeFunction(ExecState*, int len, const Identifier&, NativeFunction);
    109     PrototypeFunction(ExecState*, FunctionPrototype*, int len, const Identifier&, NativeFunction);
     50} // namespace KJS
    11051
    111   private:
    112     virtual CallType getCallData(CallData&);
    113 
    114     const NativeFunction m_function;
    115   };
    116 
    117     class GlobalEvalFunction : public PrototypeFunction {
    118     public:
    119         GlobalEvalFunction(ExecState*, FunctionPrototype*, int len, const Identifier&, NativeFunction, JSGlobalObject* expectedThisObject);
    120         JSGlobalObject* cachedGlobalObject() const { return m_cachedGlobalObject; }
    121 
    122     private:
    123         virtual void mark();
    124 
    125         JSGlobalObject* m_cachedGlobalObject;
    126     };
    127 
    128     // Global Functions
    129     JSValue* globalFuncEval(ExecState*, JSObject*, JSValue*, const ArgList&);
    130     JSValue* globalFuncParseInt(ExecState*, JSObject*, JSValue*, const ArgList&);
    131     JSValue* globalFuncParseFloat(ExecState*, JSObject*, JSValue*, const ArgList&);
    132     JSValue* globalFuncIsNaN(ExecState*, JSObject*, JSValue*, const ArgList&);
    133     JSValue* globalFuncIsFinite(ExecState*, JSObject*, JSValue*, const ArgList&);
    134     JSValue* globalFuncDecodeURI(ExecState*, JSObject*, JSValue*, const ArgList&);
    135     JSValue* globalFuncDecodeURIComponent(ExecState*, JSObject*, JSValue*, const ArgList&);
    136     JSValue* globalFuncEncodeURI(ExecState*, JSObject*, JSValue*, const ArgList&);
    137     JSValue* globalFuncEncodeURIComponent(ExecState*, JSObject*, JSValue*, const ArgList&);
    138     JSValue* globalFuncEscape(ExecState*, JSObject*, JSValue*, const ArgList&);
    139     JSValue* globalFuncUnescape(ExecState*, JSObject*, JSValue*, const ArgList&);
    140 #ifndef NDEBUG
    141     JSValue* globalFuncKJSPrint(ExecState*, JSObject*, JSValue*, const ArgList&);
    142 #endif
    143 
    144     static const double mantissaOverflowLowerBound = 9007199254740992.0;
    145     double parseIntOverflow(const char*, int length, int radix);
    146 
    147 } // namespace
    148 
    149 #endif
     52#endif // Arguments_h
  • trunk/JavaScriptCore/kjs/GlobalEvalFunction.cpp

    r35006 r35016  
    1 // -*- c-basic-offset: 2 -*-
    21/*
    32 *  Copyright (C) 1999-2002 Harri Porten ([email protected])
     
    2524
    2625#include "config.h"
    27 #include "JSFunction.h"
     26#include "GlobalEvalFunction.h"
    2827
    29 #include "ExecState.h"
    3028#include "FunctionPrototype.h"
    31 #include "JSActivation.h"
    3229#include "JSGlobalObject.h"
    33 #include "JSString.h"
    34 #include "Machine.h"
    35 #include "ObjectPrototype.h"
    36 #include "Parser.h"
    37 #include "PropertyNameArray.h"
    38 #include "ScopeChainMark.h"
    39 #include "debugger.h"
    40 #include "dtoa.h"
    41 #include "lexer.h"
    42 #include "nodes.h"
    43 #include "operations.h"
    44 #include <errno.h>
    45 #include <profiler/Profiler.h>
    46 #include <stdio.h>
    47 #include <stdlib.h>
    48 #include <string.h>
    49 #include <wtf/ASCIICType.h>
    5030#include <wtf/Assertions.h>
    51 #include <wtf/MathExtras.h>
    52 #include <wtf/unicode/UTF8.h>
    53 
    54 using namespace WTF;
    55 using namespace Unicode;
    5631
    5732namespace KJS {
    58 
    59 // ----------------------------- JSFunction ----------------------------------
    60 
    61 const ClassInfo JSFunction::info = { "Function", &InternalFunction::info, 0, 0 };
    62 
    63 JSFunction::JSFunction(ExecState* exec, const Identifier& name, FunctionBodyNode* b, ScopeChainNode* scopeChain)
    64   : InternalFunction(exec->lexicalGlobalObject()->functionPrototype(), name)
    65   , body(b)
    66   , _scope(scopeChain)
    67 {
    68 }
    69 
    70 void JSFunction::mark()
    71 {
    72     InternalFunction::mark();
    73     body->mark();
    74     _scope.mark();
    75 }
    76 
    77 CallType JSFunction::getCallData(CallData& callData)
    78 {
    79     callData.js.functionBody = body.get();
    80     callData.js.scopeChain = _scope.node();
    81     return CallTypeJS;
    82 }
    83 
    84 JSValue* JSFunction::call(ExecState* exec, JSValue* thisValue, const ArgList& args)
    85 {
    86     return exec->machine()->execute(body.get(), exec, this, thisValue->toThisObject(exec), args, _scope.node(), exec->exceptionSlot());
    87 }
    88 
    89 JSValue* JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    90 {
    91     JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
    92     return exec->machine()->retrieveArguments(exec, thisObj);
    93 }
    94 
    95 JSValue* JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    96 {
    97     JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
    98     return exec->machine()->retrieveCaller(exec, thisObj);
    99 }
    100 
    101 JSValue* JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    102 {
    103     JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
    104     return jsNumber(exec, thisObj->body->parameters().size());
    105 }
    106 
    107 bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
    108 {
    109     if (propertyName == exec->propertyNames().arguments) {
    110         slot.setCustom(this, argumentsGetter);
    111         return true;
    112     }
    113 
    114     if (propertyName == exec->propertyNames().length) {
    115         slot.setCustom(this, lengthGetter);
    116         return true;
    117     }
    118 
    119     if (propertyName == exec->propertyNames().caller) {
    120         slot.setCustom(this, callerGetter);
    121         return true;
    122     }
    123 
    124     return InternalFunction::getOwnPropertySlot(exec, propertyName, slot);
    125 }
    126 
    127 void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
    128 {
    129     if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
    130         return;
    131     InternalFunction::put(exec, propertyName, value);
    132 }
    133 
    134 bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
    135 {
    136     if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
    137         return false;
    138     return InternalFunction::deleteProperty(exec, propertyName);
    139 }
    140 
    141 /* Returns the parameter name corresponding to the given index. eg:
    142  * function f1(x, y, z): getParameterName(0) --> x
    143  *
    144  * If a name appears more than once, only the last index at which
    145  * it appears associates with it. eg:
    146  * function f2(x, x): getParameterName(0) --> null
    147  */
    148 const Identifier& JSFunction::getParameterName(int index)
    149 {
    150     Vector<Identifier>& parameters = body->parameters();
    151 
    152     if (static_cast<size_t>(index) >= body->parameters().size())
    153         return _scope.globalObject()->globalData()->propertyNames->nullIdentifier;
    154  
    155     const Identifier& name = parameters[index];
    156 
    157     // Are there any subsequent parameters with the same name?
    158     size_t size = parameters.size();
    159     for (size_t i = index + 1; i < size; ++i)
    160         if (parameters[i] == name)
    161             return _scope.globalObject()->globalData()->propertyNames->nullIdentifier;
    162 
    163     return name;
    164 }
    165 
    166 // ECMA 13.2.2 [[Construct]]
    167 ConstructType JSFunction::getConstructData(ConstructData& constructData)
    168 {
    169     constructData.js.functionBody = body.get();
    170     constructData.js.scopeChain = _scope.node();
    171     return ConstructTypeJS;
    172 }
    173 
    174 JSObject* JSFunction::construct(ExecState* exec, const ArgList& args)
    175 {
    176     JSObject* proto;
    177     JSValue* p = get(exec, exec->propertyNames().prototype);
    178     if (p->isObject())
    179         proto = static_cast<JSObject*>(p);
    180     else
    181         proto = exec->lexicalGlobalObject()->objectPrototype();
    182 
    183     JSObject* thisObj = new (exec) JSObject(proto);
    184 
    185     JSValue* result = exec->machine()->execute(body.get(), exec, this, thisObj, args, _scope.node(), exec->exceptionSlot());
    186     if (exec->hadException() || !result->isObject())
    187         return thisObj;
    188     return static_cast<JSObject*>(result);
    189 }
    190 
    191 // ------------------------------ IndexToNameMap ---------------------------------
    192 
    193 // We map indexes in the arguments array to their corresponding argument names.
    194 // Example: function f(x, y, z): arguments[0] = x, so we map 0 to Identifier("x").
    195 
    196 // Once we have an argument name, we can get and set the argument's value in the
    197 // activation object.
    198 
    199 // We use Identifier::null to indicate that a given argument's value
    200 // isn't stored in the activation object.
    201 
    202 IndexToNameMap::IndexToNameMap(JSFunction* func, const ArgList& args)
    203 {
    204   _map = new Identifier[args.size()];
    205   this->size = args.size();
    206  
    207   unsigned i = 0;
    208   ArgList::const_iterator end = args.end();
    209   for (ArgList::const_iterator it = args.begin(); it != end; ++i, ++it)
    210     _map[i] = func->getParameterName(i); // null if there is no corresponding parameter
    211 }
    212 
    213 IndexToNameMap::~IndexToNameMap()
    214 {
    215   delete [] _map;
    216 }
    217 
    218 bool IndexToNameMap::isMapped(const Identifier& index) const
    219 {
    220   bool indexIsNumber;
    221   unsigned indexAsNumber = index.toStrictUInt32(&indexIsNumber);
    222  
    223   if (!indexIsNumber)
    224     return false;
    225  
    226   if (indexAsNumber >= size)
    227     return false;
    228 
    229   if (_map[indexAsNumber].isNull())
    230     return false;
    231  
    232   return true;
    233 }
    234 
    235 void IndexToNameMap::unMap(ExecState* exec, const Identifier& index)
    236 {
    237   bool indexIsNumber;
    238   unsigned indexAsNumber = index.toStrictUInt32(&indexIsNumber);
    239 
    240   ASSERT(indexIsNumber && indexAsNumber < size);
    241  
    242   _map[indexAsNumber] = exec->propertyNames().nullIdentifier;
    243 }
    244 
    245 Identifier& IndexToNameMap::operator[](const Identifier& index)
    246 {
    247   bool indexIsNumber;
    248   unsigned indexAsNumber = index.toStrictUInt32(&indexIsNumber);
    249 
    250   ASSERT(indexIsNumber && indexAsNumber < size);
    251  
    252   return _map[indexAsNumber];
    253 }
    254 
    255 // ------------------------------ Arguments ---------------------------------
    256 
    257 const ClassInfo Arguments::info = { "Arguments", 0, 0, 0 };
    258 
    259 // ECMA 10.1.8
    260 Arguments::Arguments(ExecState* exec, JSFunction* func, const ArgList& args, JSActivation* act)
    261     : JSObject(exec->lexicalGlobalObject()->objectPrototype())
    262     , _activationObject(act)
    263     , indexToNameMap(func, args)
    264 {
    265     putDirect(exec->propertyNames().callee, func, DontEnum);
    266     putDirect(exec, exec->propertyNames().length, args.size(), DontEnum);
    267  
    268     int i = 0;
    269     ArgList::const_iterator end = args.end();
    270     for (ArgList::const_iterator it = args.begin(); it != end; ++it, ++i) {
    271         Identifier name = Identifier::from(exec, i);
    272         if (!indexToNameMap.isMapped(name))
    273             putDirect(name, *it, DontEnum);
    274     }
    275 }
    276 
    277 void Arguments::mark()
    278 {
    279   JSObject::mark();
    280   if (_activationObject && !_activationObject->marked())
    281     _activationObject->mark();
    282 }
    283 
    284 JSValue* Arguments::mappedIndexGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
    285 {
    286   Arguments* thisObj = static_cast<Arguments*>(slot.slotBase());
    287   return thisObj->_activationObject->get(exec, thisObj->indexToNameMap[propertyName]);
    288 }
    289 
    290 bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
    291 {
    292   if (indexToNameMap.isMapped(propertyName)) {
    293     slot.setCustom(this, mappedIndexGetter);
    294     return true;
    295   }
    296 
    297   return JSObject::getOwnPropertySlot(exec, propertyName, slot);
    298 }
    299 
    300 void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
    301 {
    302     if (indexToNameMap.isMapped(propertyName))
    303         _activationObject->put(exec, indexToNameMap[propertyName], value);
    304     else
    305         JSObject::put(exec, propertyName, value);
    306 }
    307 
    308 bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName)
    309 {
    310   if (indexToNameMap.isMapped(propertyName)) {
    311     indexToNameMap.unMap(exec, propertyName);
    312     return true;
    313   } else {
    314     return JSObject::deleteProperty(exec, propertyName);
    315   }
    316 }
    317 
    318 // ------------------------------ Global Functions -----------------------------------
    319 
    320 static JSValue* encode(ExecState* exec, const ArgList& args, const char* do_not_escape)
    321 {
    322   UString r = "", s, str = args[0]->toString(exec);
    323   CString cstr = str.UTF8String(true);
    324   if (!cstr.c_str())
    325     return throwError(exec, URIError, "String contained an illegal UTF-16 sequence.");
    326   const char* p = cstr.c_str();
    327   for (size_t k = 0; k < cstr.size(); k++, p++) {
    328     char c = *p;
    329     if (c && strchr(do_not_escape, c)) {
    330       r.append(c);
    331     } else {
    332       char tmp[4];
    333       sprintf(tmp, "%%%02X", (unsigned char)c);
    334       r += tmp;
    335     }
    336   }
    337   return jsString(exec, r);
    338 }
    339 
    340 static JSValue* decode(ExecState* exec, const ArgList& args, const char* do_not_unescape, bool strict)
    341 {
    342   UString s = "", str = args[0]->toString(exec);
    343   int k = 0, len = str.size();
    344   const UChar* d = str.data();
    345   UChar u = 0;
    346   while (k < len) {
    347     const UChar* p = d + k;
    348     UChar c = *p;
    349     if (c == '%') {
    350       int charLen = 0;
    351       if (k <= len - 3 && isASCIIHexDigit(p[1]) && isASCIIHexDigit(p[2])) {
    352         const char b0 = Lexer::convertHex(p[1], p[2]);
    353         const int sequenceLen = UTF8SequenceLength(b0);
    354         if (sequenceLen != 0 && k <= len - sequenceLen * 3) {
    355           charLen = sequenceLen * 3;
    356           char sequence[5];
    357           sequence[0] = b0;
    358           for (int i = 1; i < sequenceLen; ++i) {
    359             const UChar* q = p + i * 3;
    360             if (q[0] == '%' && isASCIIHexDigit(q[1]) && isASCIIHexDigit(q[2]))
    361               sequence[i] = Lexer::convertHex(q[1], q[2]);
    362             else {
    363               charLen = 0;
    364               break;
    365             }
    366           }
    367           if (charLen != 0) {
    368             sequence[sequenceLen] = 0;
    369             const int character = decodeUTF8Sequence(sequence);
    370             if (character < 0 || character >= 0x110000) {
    371               charLen = 0;
    372             } else if (character >= 0x10000) {
    373               // Convert to surrogate pair.
    374               s.append(static_cast<UChar>(0xD800 | ((character - 0x10000) >> 10)));
    375               u = static_cast<UChar>(0xDC00 | ((character - 0x10000) & 0x3FF));
    376             } else {
    377               u = static_cast<UChar>(character);
    378             }
    379           }
    380         }
    381       }
    382       if (charLen == 0) {
    383         if (strict)
    384           return throwError(exec, URIError);
    385         // The only case where we don't use "strict" mode is the "unescape" function.
    386         // For that, it's good to support the wonky "%u" syntax for compatibility with WinIE.
    387         if (k <= len - 6 && p[1] == 'u'
    388             && isASCIIHexDigit(p[2]) && isASCIIHexDigit(p[3])
    389             && isASCIIHexDigit(p[4]) && isASCIIHexDigit(p[5])) {
    390           charLen = 6;
    391           u = Lexer::convertUnicode(p[2], p[3], p[4], p[5]);
    392         }
    393       }
    394       if (charLen && (u == 0 || u >= 128 || !strchr(do_not_unescape, u))) {
    395         c = u;
    396         k += charLen - 1;
    397       }
    398     }
    399     k++;
    400     s.append(c);
    401   }
    402   return jsString(exec, s);
    403 }
    404 
    405 static bool isStrWhiteSpace(unsigned short c)
    406 {
    407     switch (c) {
    408         case 0x0009:
    409         case 0x000A:
    410         case 0x000B:
    411         case 0x000C:
    412         case 0x000D:
    413         case 0x0020:
    414         case 0x00A0:
    415         case 0x2028:
    416         case 0x2029:
    417             return true;
    418         default:
    419             return c > 0xff && isSeparatorSpace(c);
    420     }
    421 }
    422 
    423 static int parseDigit(unsigned short c, int radix)
    424 {
    425     int digit = -1;
    426 
    427     if (c >= '0' && c <= '9') {
    428         digit = c - '0';
    429     } else if (c >= 'A' && c <= 'Z') {
    430         digit = c - 'A' + 10;
    431     } else if (c >= 'a' && c <= 'z') {
    432         digit = c - 'a' + 10;
    433     }
    434 
    435     if (digit >= radix)
    436         return -1;
    437     return digit;
    438 }
    439 
    440 double parseIntOverflow(const char* s, int length, int radix)
    441 {
    442     double number = 0.0;
    443     double radixMultiplier = 1.0;
    444 
    445     for (const char* p = s + length - 1; p >= s; p--) {
    446         if (radixMultiplier == Inf) {
    447             if (*p != '0') {
    448                 number = Inf;
    449                 break;
    450             }
    451         } else {
    452             int digit = parseDigit(*p, radix);
    453             number += digit * radixMultiplier;
    454         }
    455 
    456         radixMultiplier *= radix;
    457     }
    458 
    459     return number;
    460 }
    461 
    462 static double parseInt(const UString& s, int radix)
    463 {
    464     int length = s.size();
    465     int p = 0;
    466 
    467     while (p < length && isStrWhiteSpace(s[p])) {
    468         ++p;
    469     }
    470 
    471     double sign = 1;
    472     if (p < length) {
    473         if (s[p] == '+') {
    474             ++p;
    475         } else if (s[p] == '-') {
    476             sign = -1;
    477             ++p;
    478         }
    479     }
    480 
    481     if ((radix == 0 || radix == 16) && length - p >= 2 && s[p] == '0' && (s[p + 1] == 'x' || s[p + 1] == 'X')) {
    482         radix = 16;
    483         p += 2;
    484     } else if (radix == 0) {
    485         if (p < length && s[p] == '0')
    486             radix = 8;
    487         else
    488             radix = 10;
    489     }
    490 
    491     if (radix < 2 || radix > 36)
    492         return NaN;
    493 
    494     int firstDigitPosition = p;
    495     bool sawDigit = false;
    496     double number = 0;
    497     while (p < length) {
    498         int digit = parseDigit(s[p], radix);
    499         if (digit == -1)
    500             break;
    501         sawDigit = true;
    502         number *= radix;
    503         number += digit;
    504         ++p;
    505     }
    506 
    507     if (number >= mantissaOverflowLowerBound) {
    508         if (radix == 10)
    509             number = strtod(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), 0);
    510         else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32)
    511             number = parseIntOverflow(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), p - firstDigitPosition, radix);
    512     }
    513 
    514     if (!sawDigit)
    515         return NaN;
    516 
    517     return sign * number;
    518 }
    519 
    520 static double parseFloat(const UString& s)
    521 {
    522     // Check for 0x prefix here, because toDouble allows it, but we must treat it as 0.
    523     // Need to skip any whitespace and then one + or - sign.
    524     int length = s.size();
    525     int p = 0;
    526     while (p < length && isStrWhiteSpace(s[p])) {
    527         ++p;
    528     }
    529     if (p < length && (s[p] == '+' || s[p] == '-')) {
    530         ++p;
    531     }
    532     if (length - p >= 2 && s[p] == '0' && (s[p + 1] == 'x' || s[p + 1] == 'X')) {
    533         return 0;
    534     }
    535 
    536     return s.toDouble( true /*tolerant*/, false /* NaN for empty string */ );
    537 }
    538 
    539 JSValue* globalFuncEval(ExecState* exec, JSObject* function, JSValue* thisValue, const ArgList& args)
    540 {
    541     JSObject* thisObject = thisValue->toThisObject(exec);
    542     JSGlobalObject* globalObject = thisObject->toGlobalObject(exec);
    543     if (!globalObject || globalObject->evalFunction() != function)
    544         return throwError(exec, EvalError, "The \"this\" value passed to eval must be the global object from which eval originated");
    545 
    546     JSValue* x = args[0];
    547     if (!x->isString())
    548         return x;
    549    
    550     UString s = x->toString(exec);
    551    
    552     int sourceId;
    553     int errLine;
    554     UString errMsg;
    555 
    556     RefPtr<EvalNode> evalNode = exec->parser()->parse<EvalNode>(exec, UString(), 1, UStringSourceProvider::create(s), &sourceId, &errLine, &errMsg);
    557    
    558     if (!evalNode)
    559         return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL);
    560 
    561     return exec->machine()->execute(evalNode.get(), exec, thisObject, globalObject->globalScopeChain().node(), exec->exceptionSlot());
    562 }
    563 
    564 JSValue* globalFuncParseInt(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    565 {
    566     return jsNumber(exec, parseInt(args[0]->toString(exec), args[1]->toInt32(exec)));
    567 }
    568 
    569 JSValue* globalFuncParseFloat(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    570 {
    571     return jsNumber(exec, parseFloat(args[0]->toString(exec)));
    572 }
    573 
    574 JSValue* globalFuncIsNaN(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    575 {
    576     return jsBoolean(isnan(args[0]->toNumber(exec)));
    577 }
    578 
    579 JSValue* globalFuncIsFinite(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    580 {
    581     double n = args[0]->toNumber(exec);
    582     return jsBoolean(!isnan(n) && !isinf(n));
    583 }
    584 
    585 JSValue* globalFuncDecodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    586 {
    587     static const char do_not_unescape_when_decoding_URI[] =
    588         "#$&+,/:;=?@";
    589 
    590     return decode(exec, args, do_not_unescape_when_decoding_URI, true);
    591 }
    592 
    593 JSValue* globalFuncDecodeURIComponent(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    594 {
    595     return decode(exec, args, "", true);
    596 }
    597 
    598 JSValue* globalFuncEncodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    599 {
    600     static const char do_not_escape_when_encoding_URI[] =
    601         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    602         "abcdefghijklmnopqrstuvwxyz"
    603         "0123456789"
    604         "!#$&'()*+,-./:;=?@_~";
    605 
    606     return encode(exec, args, do_not_escape_when_encoding_URI);
    607 }
    608 
    609 JSValue* globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    610 {
    611     static const char do_not_escape_when_encoding_URI_component[] =
    612         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    613         "abcdefghijklmnopqrstuvwxyz"
    614         "0123456789"
    615         "!'()*-._~";
    616 
    617     return encode(exec, args, do_not_escape_when_encoding_URI_component);
    618 }
    619 
    620 JSValue* globalFuncEscape(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    621 {
    622     static const char do_not_escape[] =
    623         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    624         "abcdefghijklmnopqrstuvwxyz"
    625         "0123456789"
    626         "*+-./@_";
    627 
    628     UString r = "", s, str = args[0]->toString(exec);
    629     const UChar* c = str.data();
    630     for (int k = 0; k < str.size(); k++, c++) {
    631         int u = c[0];
    632         if (u > 255) {
    633             char tmp[7];
    634             sprintf(tmp, "%%u%04X", u);
    635             s = UString(tmp);
    636         } else if (u != 0 && strchr(do_not_escape, (char)u))
    637             s = UString(c, 1);
    638         else {
    639             char tmp[4];
    640             sprintf(tmp, "%%%02X", u);
    641             s = UString(tmp);
    642         }
    643         r += s;
    644     }
    645 
    646     return jsString(exec, r);
    647 }
    648 
    649 JSValue* globalFuncUnescape(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    650 {
    651     UString s = "", str = args[0]->toString(exec);
    652     int k = 0, len = str.size();
    653     while (k < len) {
    654         const UChar* c = str.data() + k;
    655         UChar u;
    656         if (c[0] == '%' && k <= len - 6 && c[1] == 'u') {
    657             if (Lexer::isHexDigit(c[2]) && Lexer::isHexDigit(c[3]) && Lexer::isHexDigit(c[4]) && Lexer::isHexDigit(c[5])) {
    658                 u = Lexer::convertUnicode(c[2], c[3], c[4], c[5]);
    659                 c = &u;
    660                 k += 5;
    661             }
    662         } else if (c[0] == '%' && k <= len - 3 && Lexer::isHexDigit(c[1]) && Lexer::isHexDigit(c[2])) {
    663             u = UChar(Lexer::convertHex(c[1], c[2]));
    664             c = &u;
    665             k += 2;
    666         }
    667         k++;
    668         s.append(*c);
    669     }
    670 
    671     return jsString(exec, s);
    672 }
    673 
    674 #ifndef NDEBUG
    675 JSValue* globalFuncKJSPrint(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    676 {
    677     CStringBuffer string;
    678     args[0]->toString(exec).getCString(string);
    679     puts(string.data());
    680     return jsUndefined();
    681 }
    682 #endif
    683 
    684 // ------------------------------ PrototypeFunction -------------------------------
    685 
    686 PrototypeFunction::PrototypeFunction(ExecState* exec, int len, const Identifier& name, NativeFunction function)
    687     : InternalFunction(exec->lexicalGlobalObject()->functionPrototype(), name)
    688     , m_function(function)
    689 {
    690     ASSERT_ARG(function, function);
    691     putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
    692 }
    693 
    694 PrototypeFunction::PrototypeFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, NativeFunction function)
    695     : InternalFunction(functionPrototype, name)
    696     , m_function(function)
    697 {
    698     ASSERT_ARG(function, function);
    699     putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
    700 }
    701 
    702 CallType PrototypeFunction::getCallData(CallData& callData)
    703 {
    704     callData.native.function = m_function;
    705     return CallTypeNative;
    706 }
    707 
    708 // ------------------------------ PrototypeReflexiveFunction -------------------------------
    70933
    71034GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, NativeFunction function, JSGlobalObject* cachedGlobalObject)
  • trunk/JavaScriptCore/kjs/GlobalEvalFunction.h

    r35006 r35016  
    2222 */
    2323
    24 #ifndef JSFunction_h
    25 #define JSFunction_h
     24#ifndef GlobalEvalFunction_h
     25#define GlobalEvalFunction_h
    2626
    27 #include "InternalFunction.h"
    28 #include "JSVariableObject.h"
    29 #include "SymbolTable.h"
    30 #include "nodes.h"
    31 #include "JSObject.h"
     27#include "PrototypeFunction.h"
    3228
    3329namespace KJS {
    3430
    35   class FunctionBodyNode;
     31  class ExecState;
    3632  class FunctionPrototype;
    37   class JSActivation;
    3833  class JSGlobalObject;
    39 
    40   class JSFunction : public InternalFunction {
    41   public:
    42     JSFunction(ExecState*, const Identifier&, FunctionBodyNode*, ScopeChainNode*);
    43 
    44     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    45     virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
    46     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    47 
    48     JSObject* construct(ExecState*, const ArgList&);
    49     JSValue* call(ExecState*, JSValue* thisValue, const ArgList&);
    50 
    51     // Note: Returns a null identifier for any parameters that will never get set
    52     // due to a later parameter with the same name.
    53     const Identifier& getParameterName(int index);
    54 
    55     static const ClassInfo info;
    56 
    57     RefPtr<FunctionBodyNode> body;
    58 
    59     void setScope(const ScopeChain& s) { _scope = s; }
    60     ScopeChain& scope() { return _scope; }
    61 
    62     virtual void mark();
    63 
    64   private:
    65     virtual const ClassInfo* classInfo() const { return &info; }
    66     virtual ConstructType getConstructData(ConstructData&);
    67     virtual CallType getCallData(CallData&);
    68 
    69     ScopeChain _scope;
    70 
    71     static JSValue* argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
    72     static JSValue* callerGetter(ExecState*, const Identifier&, const PropertySlot&);
    73     static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
    74   };
    75 
    76   class IndexToNameMap {
    77   public:
    78     IndexToNameMap(JSFunction*, const ArgList&);
    79     ~IndexToNameMap();
    80    
    81     Identifier& operator[](const Identifier& index);
    82     bool isMapped(const Identifier& index) const;
    83     void unMap(ExecState* exec, const Identifier& index);
    84    
    85   private:
    86     unsigned size;
    87     Identifier* _map;
    88   };
    89  
    90   class Arguments : public JSObject {
    91   public:
    92     Arguments(ExecState*, JSFunction* func, const ArgList& args, JSActivation* act);
    93     virtual void mark();
    94     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    95     virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
    96     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    97     virtual const ClassInfo* classInfo() const { return &info; }
    98     static const ClassInfo info;
    99   private:
    100     static JSValue* mappedIndexGetter(ExecState*, const Identifier&, const PropertySlot& slot);
    101 
    102     JSActivation* _activationObject;
    103     mutable IndexToNameMap indexToNameMap;
    104   };
    105 
    106   class PrototypeFunction : public InternalFunction {
    107   public:
    108     PrototypeFunction(ExecState*, int len, const Identifier&, NativeFunction);
    109     PrototypeFunction(ExecState*, FunctionPrototype*, int len, const Identifier&, NativeFunction);
    110 
    111   private:
    112     virtual CallType getCallData(CallData&);
    113 
    114     const NativeFunction m_function;
    115   };
    11634
    11735    class GlobalEvalFunction : public PrototypeFunction {
     
    12644    };
    12745
    128     // Global Functions
    129     JSValue* globalFuncEval(ExecState*, JSObject*, JSValue*, const ArgList&);
    130     JSValue* globalFuncParseInt(ExecState*, JSObject*, JSValue*, const ArgList&);
    131     JSValue* globalFuncParseFloat(ExecState*, JSObject*, JSValue*, const ArgList&);
    132     JSValue* globalFuncIsNaN(ExecState*, JSObject*, JSValue*, const ArgList&);
    133     JSValue* globalFuncIsFinite(ExecState*, JSObject*, JSValue*, const ArgList&);
    134     JSValue* globalFuncDecodeURI(ExecState*, JSObject*, JSValue*, const ArgList&);
    135     JSValue* globalFuncDecodeURIComponent(ExecState*, JSObject*, JSValue*, const ArgList&);
    136     JSValue* globalFuncEncodeURI(ExecState*, JSObject*, JSValue*, const ArgList&);
    137     JSValue* globalFuncEncodeURIComponent(ExecState*, JSObject*, JSValue*, const ArgList&);
    138     JSValue* globalFuncEscape(ExecState*, JSObject*, JSValue*, const ArgList&);
    139     JSValue* globalFuncUnescape(ExecState*, JSObject*, JSValue*, const ArgList&);
    140 #ifndef NDEBUG
    141     JSValue* globalFuncKJSPrint(ExecState*, JSObject*, JSValue*, const ArgList&);
    142 #endif
     46} // namespace KJS
    14347
    144     static const double mantissaOverflowLowerBound = 9007199254740992.0;
    145     double parseIntOverflow(const char*, int length, int radix);
    146 
    147 } // namespace
    148 
    149 #endif
     48#endif // GlobalEvalFunction_h
  • trunk/JavaScriptCore/kjs/IndexToNameMap.cpp

    r35006 r35016  
    1 // -*- c-basic-offset: 2 -*-
    21/*
    32 *  Copyright (C) 1999-2002 Harri Porten ([email protected])
     
    2524
    2625#include "config.h"
     26#include "IndexToNameMap.h"
     27
     28#include "Identifier.h"
     29#include "list.h"
    2730#include "JSFunction.h"
    2831
    29 #include "ExecState.h"
    30 #include "FunctionPrototype.h"
    31 #include "JSActivation.h"
    32 #include "JSGlobalObject.h"
    33 #include "JSString.h"
    34 #include "Machine.h"
    35 #include "ObjectPrototype.h"
    36 #include "Parser.h"
    37 #include "PropertyNameArray.h"
    38 #include "ScopeChainMark.h"
    39 #include "debugger.h"
    40 #include "dtoa.h"
    41 #include "lexer.h"
    42 #include "nodes.h"
    43 #include "operations.h"
    44 #include <errno.h>
    45 #include <profiler/Profiler.h>
    46 #include <stdio.h>
    47 #include <stdlib.h>
    48 #include <string.h>
    49 #include <wtf/ASCIICType.h>
    50 #include <wtf/Assertions.h>
    51 #include <wtf/MathExtras.h>
    52 #include <wtf/unicode/UTF8.h>
    53 
    54 using namespace WTF;
    55 using namespace Unicode;
    56 
    5732namespace KJS {
    58 
    59 // ----------------------------- JSFunction ----------------------------------
    60 
    61 const ClassInfo JSFunction::info = { "Function", &InternalFunction::info, 0, 0 };
    62 
    63 JSFunction::JSFunction(ExecState* exec, const Identifier& name, FunctionBodyNode* b, ScopeChainNode* scopeChain)
    64   : InternalFunction(exec->lexicalGlobalObject()->functionPrototype(), name)
    65   , body(b)
    66   , _scope(scopeChain)
    67 {
    68 }
    69 
    70 void JSFunction::mark()
    71 {
    72     InternalFunction::mark();
    73     body->mark();
    74     _scope.mark();
    75 }
    76 
    77 CallType JSFunction::getCallData(CallData& callData)
    78 {
    79     callData.js.functionBody = body.get();
    80     callData.js.scopeChain = _scope.node();
    81     return CallTypeJS;
    82 }
    83 
    84 JSValue* JSFunction::call(ExecState* exec, JSValue* thisValue, const ArgList& args)
    85 {
    86     return exec->machine()->execute(body.get(), exec, this, thisValue->toThisObject(exec), args, _scope.node(), exec->exceptionSlot());
    87 }
    88 
    89 JSValue* JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    90 {
    91     JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
    92     return exec->machine()->retrieveArguments(exec, thisObj);
    93 }
    94 
    95 JSValue* JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    96 {
    97     JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
    98     return exec->machine()->retrieveCaller(exec, thisObj);
    99 }
    100 
    101 JSValue* JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    102 {
    103     JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
    104     return jsNumber(exec, thisObj->body->parameters().size());
    105 }
    106 
    107 bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
    108 {
    109     if (propertyName == exec->propertyNames().arguments) {
    110         slot.setCustom(this, argumentsGetter);
    111         return true;
    112     }
    113 
    114     if (propertyName == exec->propertyNames().length) {
    115         slot.setCustom(this, lengthGetter);
    116         return true;
    117     }
    118 
    119     if (propertyName == exec->propertyNames().caller) {
    120         slot.setCustom(this, callerGetter);
    121         return true;
    122     }
    123 
    124     return InternalFunction::getOwnPropertySlot(exec, propertyName, slot);
    125 }
    126 
    127 void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
    128 {
    129     if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
    130         return;
    131     InternalFunction::put(exec, propertyName, value);
    132 }
    133 
    134 bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
    135 {
    136     if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
    137         return false;
    138     return InternalFunction::deleteProperty(exec, propertyName);
    139 }
    140 
    141 /* Returns the parameter name corresponding to the given index. eg:
    142  * function f1(x, y, z): getParameterName(0) --> x
    143  *
    144  * If a name appears more than once, only the last index at which
    145  * it appears associates with it. eg:
    146  * function f2(x, x): getParameterName(0) --> null
    147  */
    148 const Identifier& JSFunction::getParameterName(int index)
    149 {
    150     Vector<Identifier>& parameters = body->parameters();
    151 
    152     if (static_cast<size_t>(index) >= body->parameters().size())
    153         return _scope.globalObject()->globalData()->propertyNames->nullIdentifier;
    154  
    155     const Identifier& name = parameters[index];
    156 
    157     // Are there any subsequent parameters with the same name?
    158     size_t size = parameters.size();
    159     for (size_t i = index + 1; i < size; ++i)
    160         if (parameters[i] == name)
    161             return _scope.globalObject()->globalData()->propertyNames->nullIdentifier;
    162 
    163     return name;
    164 }
    165 
    166 // ECMA 13.2.2 [[Construct]]
    167 ConstructType JSFunction::getConstructData(ConstructData& constructData)
    168 {
    169     constructData.js.functionBody = body.get();
    170     constructData.js.scopeChain = _scope.node();
    171     return ConstructTypeJS;
    172 }
    173 
    174 JSObject* JSFunction::construct(ExecState* exec, const ArgList& args)
    175 {
    176     JSObject* proto;
    177     JSValue* p = get(exec, exec->propertyNames().prototype);
    178     if (p->isObject())
    179         proto = static_cast<JSObject*>(p);
    180     else
    181         proto = exec->lexicalGlobalObject()->objectPrototype();
    182 
    183     JSObject* thisObj = new (exec) JSObject(proto);
    184 
    185     JSValue* result = exec->machine()->execute(body.get(), exec, this, thisObj, args, _scope.node(), exec->exceptionSlot());
    186     if (exec->hadException() || !result->isObject())
    187         return thisObj;
    188     return static_cast<JSObject*>(result);
    189 }
    190 
    191 // ------------------------------ IndexToNameMap ---------------------------------
    19233
    19334// We map indexes in the arguments array to their corresponding argument names.
     
    25394}
    25495
    255 // ------------------------------ Arguments ---------------------------------
    256 
    257 const ClassInfo Arguments::info = { "Arguments", 0, 0, 0 };
    258 
    259 // ECMA 10.1.8
    260 Arguments::Arguments(ExecState* exec, JSFunction* func, const ArgList& args, JSActivation* act)
    261     : JSObject(exec->lexicalGlobalObject()->objectPrototype())
    262     , _activationObject(act)
    263     , indexToNameMap(func, args)
    264 {
    265     putDirect(exec->propertyNames().callee, func, DontEnum);
    266     putDirect(exec, exec->propertyNames().length, args.size(), DontEnum);
    267  
    268     int i = 0;
    269     ArgList::const_iterator end = args.end();
    270     for (ArgList::const_iterator it = args.begin(); it != end; ++it, ++i) {
    271         Identifier name = Identifier::from(exec, i);
    272         if (!indexToNameMap.isMapped(name))
    273             putDirect(name, *it, DontEnum);
    274     }
    275 }
    276 
    277 void Arguments::mark()
    278 {
    279   JSObject::mark();
    280   if (_activationObject && !_activationObject->marked())
    281     _activationObject->mark();
    282 }
    283 
    284 JSValue* Arguments::mappedIndexGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
    285 {
    286   Arguments* thisObj = static_cast<Arguments*>(slot.slotBase());
    287   return thisObj->_activationObject->get(exec, thisObj->indexToNameMap[propertyName]);
    288 }
    289 
    290 bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
    291 {
    292   if (indexToNameMap.isMapped(propertyName)) {
    293     slot.setCustom(this, mappedIndexGetter);
    294     return true;
    295   }
    296 
    297   return JSObject::getOwnPropertySlot(exec, propertyName, slot);
    298 }
    299 
    300 void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
    301 {
    302     if (indexToNameMap.isMapped(propertyName))
    303         _activationObject->put(exec, indexToNameMap[propertyName], value);
    304     else
    305         JSObject::put(exec, propertyName, value);
    306 }
    307 
    308 bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName)
    309 {
    310   if (indexToNameMap.isMapped(propertyName)) {
    311     indexToNameMap.unMap(exec, propertyName);
    312     return true;
    313   } else {
    314     return JSObject::deleteProperty(exec, propertyName);
    315   }
    316 }
    317 
    318 // ------------------------------ Global Functions -----------------------------------
    319 
    320 static JSValue* encode(ExecState* exec, const ArgList& args, const char* do_not_escape)
    321 {
    322   UString r = "", s, str = args[0]->toString(exec);
    323   CString cstr = str.UTF8String(true);
    324   if (!cstr.c_str())
    325     return throwError(exec, URIError, "String contained an illegal UTF-16 sequence.");
    326   const char* p = cstr.c_str();
    327   for (size_t k = 0; k < cstr.size(); k++, p++) {
    328     char c = *p;
    329     if (c && strchr(do_not_escape, c)) {
    330       r.append(c);
    331     } else {
    332       char tmp[4];
    333       sprintf(tmp, "%%%02X", (unsigned char)c);
    334       r += tmp;
    335     }
    336   }
    337   return jsString(exec, r);
    338 }
    339 
    340 static JSValue* decode(ExecState* exec, const ArgList& args, const char* do_not_unescape, bool strict)
    341 {
    342   UString s = "", str = args[0]->toString(exec);
    343   int k = 0, len = str.size();
    344   const UChar* d = str.data();
    345   UChar u = 0;
    346   while (k < len) {
    347     const UChar* p = d + k;
    348     UChar c = *p;
    349     if (c == '%') {
    350       int charLen = 0;
    351       if (k <= len - 3 && isASCIIHexDigit(p[1]) && isASCIIHexDigit(p[2])) {
    352         const char b0 = Lexer::convertHex(p[1], p[2]);
    353         const int sequenceLen = UTF8SequenceLength(b0);
    354         if (sequenceLen != 0 && k <= len - sequenceLen * 3) {
    355           charLen = sequenceLen * 3;
    356           char sequence[5];
    357           sequence[0] = b0;
    358           for (int i = 1; i < sequenceLen; ++i) {
    359             const UChar* q = p + i * 3;
    360             if (q[0] == '%' && isASCIIHexDigit(q[1]) && isASCIIHexDigit(q[2]))
    361               sequence[i] = Lexer::convertHex(q[1], q[2]);
    362             else {
    363               charLen = 0;
    364               break;
    365             }
    366           }
    367           if (charLen != 0) {
    368             sequence[sequenceLen] = 0;
    369             const int character = decodeUTF8Sequence(sequence);
    370             if (character < 0 || character >= 0x110000) {
    371               charLen = 0;
    372             } else if (character >= 0x10000) {
    373               // Convert to surrogate pair.
    374               s.append(static_cast<UChar>(0xD800 | ((character - 0x10000) >> 10)));
    375               u = static_cast<UChar>(0xDC00 | ((character - 0x10000) & 0x3FF));
    376             } else {
    377               u = static_cast<UChar>(character);
    378             }
    379           }
    380         }
    381       }
    382       if (charLen == 0) {
    383         if (strict)
    384           return throwError(exec, URIError);
    385         // The only case where we don't use "strict" mode is the "unescape" function.
    386         // For that, it's good to support the wonky "%u" syntax for compatibility with WinIE.
    387         if (k <= len - 6 && p[1] == 'u'
    388             && isASCIIHexDigit(p[2]) && isASCIIHexDigit(p[3])
    389             && isASCIIHexDigit(p[4]) && isASCIIHexDigit(p[5])) {
    390           charLen = 6;
    391           u = Lexer::convertUnicode(p[2], p[3], p[4], p[5]);
    392         }
    393       }
    394       if (charLen && (u == 0 || u >= 128 || !strchr(do_not_unescape, u))) {
    395         c = u;
    396         k += charLen - 1;
    397       }
    398     }
    399     k++;
    400     s.append(c);
    401   }
    402   return jsString(exec, s);
    403 }
    404 
    405 static bool isStrWhiteSpace(unsigned short c)
    406 {
    407     switch (c) {
    408         case 0x0009:
    409         case 0x000A:
    410         case 0x000B:
    411         case 0x000C:
    412         case 0x000D:
    413         case 0x0020:
    414         case 0x00A0:
    415         case 0x2028:
    416         case 0x2029:
    417             return true;
    418         default:
    419             return c > 0xff && isSeparatorSpace(c);
    420     }
    421 }
    422 
    423 static int parseDigit(unsigned short c, int radix)
    424 {
    425     int digit = -1;
    426 
    427     if (c >= '0' && c <= '9') {
    428         digit = c - '0';
    429     } else if (c >= 'A' && c <= 'Z') {
    430         digit = c - 'A' + 10;
    431     } else if (c >= 'a' && c <= 'z') {
    432         digit = c - 'a' + 10;
    433     }
    434 
    435     if (digit >= radix)
    436         return -1;
    437     return digit;
    438 }
    439 
    440 double parseIntOverflow(const char* s, int length, int radix)
    441 {
    442     double number = 0.0;
    443     double radixMultiplier = 1.0;
    444 
    445     for (const char* p = s + length - 1; p >= s; p--) {
    446         if (radixMultiplier == Inf) {
    447             if (*p != '0') {
    448                 number = Inf;
    449                 break;
    450             }
    451         } else {
    452             int digit = parseDigit(*p, radix);
    453             number += digit * radixMultiplier;
    454         }
    455 
    456         radixMultiplier *= radix;
    457     }
    458 
    459     return number;
    460 }
    461 
    462 static double parseInt(const UString& s, int radix)
    463 {
    464     int length = s.size();
    465     int p = 0;
    466 
    467     while (p < length && isStrWhiteSpace(s[p])) {
    468         ++p;
    469     }
    470 
    471     double sign = 1;
    472     if (p < length) {
    473         if (s[p] == '+') {
    474             ++p;
    475         } else if (s[p] == '-') {
    476             sign = -1;
    477             ++p;
    478         }
    479     }
    480 
    481     if ((radix == 0 || radix == 16) && length - p >= 2 && s[p] == '0' && (s[p + 1] == 'x' || s[p + 1] == 'X')) {
    482         radix = 16;
    483         p += 2;
    484     } else if (radix == 0) {
    485         if (p < length && s[p] == '0')
    486             radix = 8;
    487         else
    488             radix = 10;
    489     }
    490 
    491     if (radix < 2 || radix > 36)
    492         return NaN;
    493 
    494     int firstDigitPosition = p;
    495     bool sawDigit = false;
    496     double number = 0;
    497     while (p < length) {
    498         int digit = parseDigit(s[p], radix);
    499         if (digit == -1)
    500             break;
    501         sawDigit = true;
    502         number *= radix;
    503         number += digit;
    504         ++p;
    505     }
    506 
    507     if (number >= mantissaOverflowLowerBound) {
    508         if (radix == 10)
    509             number = strtod(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), 0);
    510         else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32)
    511             number = parseIntOverflow(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), p - firstDigitPosition, radix);
    512     }
    513 
    514     if (!sawDigit)
    515         return NaN;
    516 
    517     return sign * number;
    518 }
    519 
    520 static double parseFloat(const UString& s)
    521 {
    522     // Check for 0x prefix here, because toDouble allows it, but we must treat it as 0.
    523     // Need to skip any whitespace and then one + or - sign.
    524     int length = s.size();
    525     int p = 0;
    526     while (p < length && isStrWhiteSpace(s[p])) {
    527         ++p;
    528     }
    529     if (p < length && (s[p] == '+' || s[p] == '-')) {
    530         ++p;
    531     }
    532     if (length - p >= 2 && s[p] == '0' && (s[p + 1] == 'x' || s[p + 1] == 'X')) {
    533         return 0;
    534     }
    535 
    536     return s.toDouble( true /*tolerant*/, false /* NaN for empty string */ );
    537 }
    538 
    539 JSValue* globalFuncEval(ExecState* exec, JSObject* function, JSValue* thisValue, const ArgList& args)
    540 {
    541     JSObject* thisObject = thisValue->toThisObject(exec);
    542     JSGlobalObject* globalObject = thisObject->toGlobalObject(exec);
    543     if (!globalObject || globalObject->evalFunction() != function)
    544         return throwError(exec, EvalError, "The \"this\" value passed to eval must be the global object from which eval originated");
    545 
    546     JSValue* x = args[0];
    547     if (!x->isString())
    548         return x;
    549    
    550     UString s = x->toString(exec);
    551    
    552     int sourceId;
    553     int errLine;
    554     UString errMsg;
    555 
    556     RefPtr<EvalNode> evalNode = exec->parser()->parse<EvalNode>(exec, UString(), 1, UStringSourceProvider::create(s), &sourceId, &errLine, &errMsg);
    557    
    558     if (!evalNode)
    559         return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL);
    560 
    561     return exec->machine()->execute(evalNode.get(), exec, thisObject, globalObject->globalScopeChain().node(), exec->exceptionSlot());
    562 }
    563 
    564 JSValue* globalFuncParseInt(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    565 {
    566     return jsNumber(exec, parseInt(args[0]->toString(exec), args[1]->toInt32(exec)));
    567 }
    568 
    569 JSValue* globalFuncParseFloat(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    570 {
    571     return jsNumber(exec, parseFloat(args[0]->toString(exec)));
    572 }
    573 
    574 JSValue* globalFuncIsNaN(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    575 {
    576     return jsBoolean(isnan(args[0]->toNumber(exec)));
    577 }
    578 
    579 JSValue* globalFuncIsFinite(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    580 {
    581     double n = args[0]->toNumber(exec);
    582     return jsBoolean(!isnan(n) && !isinf(n));
    583 }
    584 
    585 JSValue* globalFuncDecodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    586 {
    587     static const char do_not_unescape_when_decoding_URI[] =
    588         "#$&+,/:;=?@";
    589 
    590     return decode(exec, args, do_not_unescape_when_decoding_URI, true);
    591 }
    592 
    593 JSValue* globalFuncDecodeURIComponent(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    594 {
    595     return decode(exec, args, "", true);
    596 }
    597 
    598 JSValue* globalFuncEncodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    599 {
    600     static const char do_not_escape_when_encoding_URI[] =
    601         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    602         "abcdefghijklmnopqrstuvwxyz"
    603         "0123456789"
    604         "!#$&'()*+,-./:;=?@_~";
    605 
    606     return encode(exec, args, do_not_escape_when_encoding_URI);
    607 }
    608 
    609 JSValue* globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    610 {
    611     static const char do_not_escape_when_encoding_URI_component[] =
    612         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    613         "abcdefghijklmnopqrstuvwxyz"
    614         "0123456789"
    615         "!'()*-._~";
    616 
    617     return encode(exec, args, do_not_escape_when_encoding_URI_component);
    618 }
    619 
    620 JSValue* globalFuncEscape(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    621 {
    622     static const char do_not_escape[] =
    623         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    624         "abcdefghijklmnopqrstuvwxyz"
    625         "0123456789"
    626         "*+-./@_";
    627 
    628     UString r = "", s, str = args[0]->toString(exec);
    629     const UChar* c = str.data();
    630     for (int k = 0; k < str.size(); k++, c++) {
    631         int u = c[0];
    632         if (u > 255) {
    633             char tmp[7];
    634             sprintf(tmp, "%%u%04X", u);
    635             s = UString(tmp);
    636         } else if (u != 0 && strchr(do_not_escape, (char)u))
    637             s = UString(c, 1);
    638         else {
    639             char tmp[4];
    640             sprintf(tmp, "%%%02X", u);
    641             s = UString(tmp);
    642         }
    643         r += s;
    644     }
    645 
    646     return jsString(exec, r);
    647 }
    648 
    649 JSValue* globalFuncUnescape(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    650 {
    651     UString s = "", str = args[0]->toString(exec);
    652     int k = 0, len = str.size();
    653     while (k < len) {
    654         const UChar* c = str.data() + k;
    655         UChar u;
    656         if (c[0] == '%' && k <= len - 6 && c[1] == 'u') {
    657             if (Lexer::isHexDigit(c[2]) && Lexer::isHexDigit(c[3]) && Lexer::isHexDigit(c[4]) && Lexer::isHexDigit(c[5])) {
    658                 u = Lexer::convertUnicode(c[2], c[3], c[4], c[5]);
    659                 c = &u;
    660                 k += 5;
    661             }
    662         } else if (c[0] == '%' && k <= len - 3 && Lexer::isHexDigit(c[1]) && Lexer::isHexDigit(c[2])) {
    663             u = UChar(Lexer::convertHex(c[1], c[2]));
    664             c = &u;
    665             k += 2;
    666         }
    667         k++;
    668         s.append(*c);
    669     }
    670 
    671     return jsString(exec, s);
    672 }
    673 
    674 #ifndef NDEBUG
    675 JSValue* globalFuncKJSPrint(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    676 {
    677     CStringBuffer string;
    678     args[0]->toString(exec).getCString(string);
    679     puts(string.data());
    680     return jsUndefined();
    681 }
    682 #endif
    683 
    684 // ------------------------------ PrototypeFunction -------------------------------
    685 
    686 PrototypeFunction::PrototypeFunction(ExecState* exec, int len, const Identifier& name, NativeFunction function)
    687     : InternalFunction(exec->lexicalGlobalObject()->functionPrototype(), name)
    688     , m_function(function)
    689 {
    690     ASSERT_ARG(function, function);
    691     putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
    692 }
    693 
    694 PrototypeFunction::PrototypeFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, NativeFunction function)
    695     : InternalFunction(functionPrototype, name)
    696     , m_function(function)
    697 {
    698     ASSERT_ARG(function, function);
    699     putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
    700 }
    701 
    702 CallType PrototypeFunction::getCallData(CallData& callData)
    703 {
    704     callData.native.function = m_function;
    705     return CallTypeNative;
    706 }
    707 
    708 // ------------------------------ PrototypeReflexiveFunction -------------------------------
    709 
    710 GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, NativeFunction function, JSGlobalObject* cachedGlobalObject)
    711     : PrototypeFunction(exec, functionPrototype, len, name, function)
    712     , m_cachedGlobalObject(cachedGlobalObject)
    713 {
    714     ASSERT_ARG(cachedGlobalObject, cachedGlobalObject);
    715 }
    716 
    717 void GlobalEvalFunction::mark()
    718 {
    719     PrototypeFunction::mark();
    720     if (!m_cachedGlobalObject->marked())
    721         m_cachedGlobalObject->mark();
    722 }
    723 
    72496} // namespace KJS
  • trunk/JavaScriptCore/kjs/IndexToNameMap.h

    r35006 r35016  
    2222 */
    2323
    24 #ifndef JSFunction_h
    25 #define JSFunction_h
    26 
    27 #include "InternalFunction.h"
    28 #include "JSVariableObject.h"
    29 #include "SymbolTable.h"
    30 #include "nodes.h"
    31 #include "JSObject.h"
     24#ifndef IndexToNameMap_h
     25#define IndexToNameMap_h
    3226
    3327namespace KJS {
    3428
    35   class FunctionBodyNode;
    36   class FunctionPrototype;
    37   class JSActivation;
    38   class JSGlobalObject;
    39 
    40   class JSFunction : public InternalFunction {
    41   public:
    42     JSFunction(ExecState*, const Identifier&, FunctionBodyNode*, ScopeChainNode*);
    43 
    44     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    45     virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
    46     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    47 
    48     JSObject* construct(ExecState*, const ArgList&);
    49     JSValue* call(ExecState*, JSValue* thisValue, const ArgList&);
    50 
    51     // Note: Returns a null identifier for any parameters that will never get set
    52     // due to a later parameter with the same name.
    53     const Identifier& getParameterName(int index);
    54 
    55     static const ClassInfo info;
    56 
    57     RefPtr<FunctionBodyNode> body;
    58 
    59     void setScope(const ScopeChain& s) { _scope = s; }
    60     ScopeChain& scope() { return _scope; }
    61 
    62     virtual void mark();
    63 
    64   private:
    65     virtual const ClassInfo* classInfo() const { return &info; }
    66     virtual ConstructType getConstructData(ConstructData&);
    67     virtual CallType getCallData(CallData&);
    68 
    69     ScopeChain _scope;
    70 
    71     static JSValue* argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
    72     static JSValue* callerGetter(ExecState*, const Identifier&, const PropertySlot&);
    73     static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
    74   };
     29  class ArgList;
     30  class ExecState;
     31  class Identifier;
     32  class JSFunction;
    7533
    7634  class IndexToNameMap {
     
    8745    Identifier* _map;
    8846  };
    89  
    90   class Arguments : public JSObject {
    91   public:
    92     Arguments(ExecState*, JSFunction* func, const ArgList& args, JSActivation* act);
    93     virtual void mark();
    94     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    95     virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
    96     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    97     virtual const ClassInfo* classInfo() const { return &info; }
    98     static const ClassInfo info;
    99   private:
    100     static JSValue* mappedIndexGetter(ExecState*, const Identifier&, const PropertySlot& slot);
    10147
    102     JSActivation* _activationObject;
    103     mutable IndexToNameMap indexToNameMap;
    104   };
     48} // namespace KJS
    10549
    106   class PrototypeFunction : public InternalFunction {
    107   public:
    108     PrototypeFunction(ExecState*, int len, const Identifier&, NativeFunction);
    109     PrototypeFunction(ExecState*, FunctionPrototype*, int len, const Identifier&, NativeFunction);
    110 
    111   private:
    112     virtual CallType getCallData(CallData&);
    113 
    114     const NativeFunction m_function;
    115   };
    116 
    117     class GlobalEvalFunction : public PrototypeFunction {
    118     public:
    119         GlobalEvalFunction(ExecState*, FunctionPrototype*, int len, const Identifier&, NativeFunction, JSGlobalObject* expectedThisObject);
    120         JSGlobalObject* cachedGlobalObject() const { return m_cachedGlobalObject; }
    121 
    122     private:
    123         virtual void mark();
    124 
    125         JSGlobalObject* m_cachedGlobalObject;
    126     };
    127 
    128     // Global Functions
    129     JSValue* globalFuncEval(ExecState*, JSObject*, JSValue*, const ArgList&);
    130     JSValue* globalFuncParseInt(ExecState*, JSObject*, JSValue*, const ArgList&);
    131     JSValue* globalFuncParseFloat(ExecState*, JSObject*, JSValue*, const ArgList&);
    132     JSValue* globalFuncIsNaN(ExecState*, JSObject*, JSValue*, const ArgList&);
    133     JSValue* globalFuncIsFinite(ExecState*, JSObject*, JSValue*, const ArgList&);
    134     JSValue* globalFuncDecodeURI(ExecState*, JSObject*, JSValue*, const ArgList&);
    135     JSValue* globalFuncDecodeURIComponent(ExecState*, JSObject*, JSValue*, const ArgList&);
    136     JSValue* globalFuncEncodeURI(ExecState*, JSObject*, JSValue*, const ArgList&);
    137     JSValue* globalFuncEncodeURIComponent(ExecState*, JSObject*, JSValue*, const ArgList&);
    138     JSValue* globalFuncEscape(ExecState*, JSObject*, JSValue*, const ArgList&);
    139     JSValue* globalFuncUnescape(ExecState*, JSObject*, JSValue*, const ArgList&);
    140 #ifndef NDEBUG
    141     JSValue* globalFuncKJSPrint(ExecState*, JSObject*, JSValue*, const ArgList&);
    142 #endif
    143 
    144     static const double mantissaOverflowLowerBound = 9007199254740992.0;
    145     double parseIntOverflow(const char*, int length, int radix);
    146 
    147 } // namespace
    148 
    149 #endif
     50#endif // IndexToNameMap_h
  • trunk/JavaScriptCore/kjs/JSActivation.cpp

    r34906 r35016  
    3030#include "JSActivation.h"
    3131
     32#include "Arguments.h"
    3233#include "CodeBlock.h"
    3334#include "Machine.h"
  • trunk/JavaScriptCore/kjs/JSFunction.cpp

    r34854 r35016  
    1 // -*- c-basic-offset: 2 -*-
    21/*
    32 *  Copyright (C) 1999-2002 Harri Porten ([email protected])
     
    2928#include "ExecState.h"
    3029#include "FunctionPrototype.h"
    31 #include "JSActivation.h"
    3230#include "JSGlobalObject.h"
    33 #include "JSString.h"
    3431#include "Machine.h"
    3532#include "ObjectPrototype.h"
     
    3734#include "PropertyNameArray.h"
    3835#include "ScopeChainMark.h"
    39 #include "debugger.h"
    40 #include "dtoa.h"
    41 #include "lexer.h"
    42 #include "nodes.h"
    43 #include "operations.h"
    44 #include <errno.h>
    45 #include <profiler/Profiler.h>
    46 #include <stdio.h>
    47 #include <stdlib.h>
    48 #include <string.h>
    49 #include <wtf/ASCIICType.h>
    50 #include <wtf/Assertions.h>
    51 #include <wtf/MathExtras.h>
    52 #include <wtf/unicode/UTF8.h>
    5336
    5437using namespace WTF;
     
    5639
    5740namespace KJS {
    58 
    59 // ----------------------------- JSFunction ----------------------------------
    6041
    6142const ClassInfo JSFunction::info = { "Function", &InternalFunction::info, 0, 0 };
     
    189170}
    190171
    191 // ------------------------------ IndexToNameMap ---------------------------------
    192 
    193 // We map indexes in the arguments array to their corresponding argument names.
    194 // Example: function f(x, y, z): arguments[0] = x, so we map 0 to Identifier("x").
    195 
    196 // Once we have an argument name, we can get and set the argument's value in the
    197 // activation object.
    198 
    199 // We use Identifier::null to indicate that a given argument's value
    200 // isn't stored in the activation object.
    201 
    202 IndexToNameMap::IndexToNameMap(JSFunction* func, const ArgList& args)
    203 {
    204   _map = new Identifier[args.size()];
    205   this->size = args.size();
    206  
    207   unsigned i = 0;
    208   ArgList::const_iterator end = args.end();
    209   for (ArgList::const_iterator it = args.begin(); it != end; ++i, ++it)
    210     _map[i] = func->getParameterName(i); // null if there is no corresponding parameter
    211 }
    212 
    213 IndexToNameMap::~IndexToNameMap()
    214 {
    215   delete [] _map;
    216 }
    217 
    218 bool IndexToNameMap::isMapped(const Identifier& index) const
    219 {
    220   bool indexIsNumber;
    221   unsigned indexAsNumber = index.toStrictUInt32(&indexIsNumber);
    222  
    223   if (!indexIsNumber)
    224     return false;
    225  
    226   if (indexAsNumber >= size)
    227     return false;
    228 
    229   if (_map[indexAsNumber].isNull())
    230     return false;
    231  
    232   return true;
    233 }
    234 
    235 void IndexToNameMap::unMap(ExecState* exec, const Identifier& index)
    236 {
    237   bool indexIsNumber;
    238   unsigned indexAsNumber = index.toStrictUInt32(&indexIsNumber);
    239 
    240   ASSERT(indexIsNumber && indexAsNumber < size);
    241  
    242   _map[indexAsNumber] = exec->propertyNames().nullIdentifier;
    243 }
    244 
    245 Identifier& IndexToNameMap::operator[](const Identifier& index)
    246 {
    247   bool indexIsNumber;
    248   unsigned indexAsNumber = index.toStrictUInt32(&indexIsNumber);
    249 
    250   ASSERT(indexIsNumber && indexAsNumber < size);
    251  
    252   return _map[indexAsNumber];
    253 }
    254 
    255 // ------------------------------ Arguments ---------------------------------
    256 
    257 const ClassInfo Arguments::info = { "Arguments", 0, 0, 0 };
    258 
    259 // ECMA 10.1.8
    260 Arguments::Arguments(ExecState* exec, JSFunction* func, const ArgList& args, JSActivation* act)
    261     : JSObject(exec->lexicalGlobalObject()->objectPrototype())
    262     , _activationObject(act)
    263     , indexToNameMap(func, args)
    264 {
    265     putDirect(exec->propertyNames().callee, func, DontEnum);
    266     putDirect(exec, exec->propertyNames().length, args.size(), DontEnum);
    267  
    268     int i = 0;
    269     ArgList::const_iterator end = args.end();
    270     for (ArgList::const_iterator it = args.begin(); it != end; ++it, ++i) {
    271         Identifier name = Identifier::from(exec, i);
    272         if (!indexToNameMap.isMapped(name))
    273             putDirect(name, *it, DontEnum);
    274     }
    275 }
    276 
    277 void Arguments::mark()
    278 {
    279   JSObject::mark();
    280   if (_activationObject && !_activationObject->marked())
    281     _activationObject->mark();
    282 }
    283 
    284 JSValue* Arguments::mappedIndexGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
    285 {
    286   Arguments* thisObj = static_cast<Arguments*>(slot.slotBase());
    287   return thisObj->_activationObject->get(exec, thisObj->indexToNameMap[propertyName]);
    288 }
    289 
    290 bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
    291 {
    292   if (indexToNameMap.isMapped(propertyName)) {
    293     slot.setCustom(this, mappedIndexGetter);
    294     return true;
    295   }
    296 
    297   return JSObject::getOwnPropertySlot(exec, propertyName, slot);
    298 }
    299 
    300 void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
    301 {
    302     if (indexToNameMap.isMapped(propertyName))
    303         _activationObject->put(exec, indexToNameMap[propertyName], value);
    304     else
    305         JSObject::put(exec, propertyName, value);
    306 }
    307 
    308 bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName)
    309 {
    310   if (indexToNameMap.isMapped(propertyName)) {
    311     indexToNameMap.unMap(exec, propertyName);
    312     return true;
    313   } else {
    314     return JSObject::deleteProperty(exec, propertyName);
    315   }
    316 }
    317 
    318 // ------------------------------ Global Functions -----------------------------------
    319 
    320 static JSValue* encode(ExecState* exec, const ArgList& args, const char* do_not_escape)
    321 {
    322   UString r = "", s, str = args[0]->toString(exec);
    323   CString cstr = str.UTF8String(true);
    324   if (!cstr.c_str())
    325     return throwError(exec, URIError, "String contained an illegal UTF-16 sequence.");
    326   const char* p = cstr.c_str();
    327   for (size_t k = 0; k < cstr.size(); k++, p++) {
    328     char c = *p;
    329     if (c && strchr(do_not_escape, c)) {
    330       r.append(c);
    331     } else {
    332       char tmp[4];
    333       sprintf(tmp, "%%%02X", (unsigned char)c);
    334       r += tmp;
    335     }
    336   }
    337   return jsString(exec, r);
    338 }
    339 
    340 static JSValue* decode(ExecState* exec, const ArgList& args, const char* do_not_unescape, bool strict)
    341 {
    342   UString s = "", str = args[0]->toString(exec);
    343   int k = 0, len = str.size();
    344   const UChar* d = str.data();
    345   UChar u = 0;
    346   while (k < len) {
    347     const UChar* p = d + k;
    348     UChar c = *p;
    349     if (c == '%') {
    350       int charLen = 0;
    351       if (k <= len - 3 && isASCIIHexDigit(p[1]) && isASCIIHexDigit(p[2])) {
    352         const char b0 = Lexer::convertHex(p[1], p[2]);
    353         const int sequenceLen = UTF8SequenceLength(b0);
    354         if (sequenceLen != 0 && k <= len - sequenceLen * 3) {
    355           charLen = sequenceLen * 3;
    356           char sequence[5];
    357           sequence[0] = b0;
    358           for (int i = 1; i < sequenceLen; ++i) {
    359             const UChar* q = p + i * 3;
    360             if (q[0] == '%' && isASCIIHexDigit(q[1]) && isASCIIHexDigit(q[2]))
    361               sequence[i] = Lexer::convertHex(q[1], q[2]);
    362             else {
    363               charLen = 0;
    364               break;
    365             }
    366           }
    367           if (charLen != 0) {
    368             sequence[sequenceLen] = 0;
    369             const int character = decodeUTF8Sequence(sequence);
    370             if (character < 0 || character >= 0x110000) {
    371               charLen = 0;
    372             } else if (character >= 0x10000) {
    373               // Convert to surrogate pair.
    374               s.append(static_cast<UChar>(0xD800 | ((character - 0x10000) >> 10)));
    375               u = static_cast<UChar>(0xDC00 | ((character - 0x10000) & 0x3FF));
    376             } else {
    377               u = static_cast<UChar>(character);
    378             }
    379           }
    380         }
    381       }
    382       if (charLen == 0) {
    383         if (strict)
    384           return throwError(exec, URIError);
    385         // The only case where we don't use "strict" mode is the "unescape" function.
    386         // For that, it's good to support the wonky "%u" syntax for compatibility with WinIE.
    387         if (k <= len - 6 && p[1] == 'u'
    388             && isASCIIHexDigit(p[2]) && isASCIIHexDigit(p[3])
    389             && isASCIIHexDigit(p[4]) && isASCIIHexDigit(p[5])) {
    390           charLen = 6;
    391           u = Lexer::convertUnicode(p[2], p[3], p[4], p[5]);
    392         }
    393       }
    394       if (charLen && (u == 0 || u >= 128 || !strchr(do_not_unescape, u))) {
    395         c = u;
    396         k += charLen - 1;
    397       }
    398     }
    399     k++;
    400     s.append(c);
    401   }
    402   return jsString(exec, s);
    403 }
    404 
    405 static bool isStrWhiteSpace(unsigned short c)
    406 {
    407     switch (c) {
    408         case 0x0009:
    409         case 0x000A:
    410         case 0x000B:
    411         case 0x000C:
    412         case 0x000D:
    413         case 0x0020:
    414         case 0x00A0:
    415         case 0x2028:
    416         case 0x2029:
    417             return true;
    418         default:
    419             return c > 0xff && isSeparatorSpace(c);
    420     }
    421 }
    422 
    423 static int parseDigit(unsigned short c, int radix)
    424 {
    425     int digit = -1;
    426 
    427     if (c >= '0' && c <= '9') {
    428         digit = c - '0';
    429     } else if (c >= 'A' && c <= 'Z') {
    430         digit = c - 'A' + 10;
    431     } else if (c >= 'a' && c <= 'z') {
    432         digit = c - 'a' + 10;
    433     }
    434 
    435     if (digit >= radix)
    436         return -1;
    437     return digit;
    438 }
    439 
    440 double parseIntOverflow(const char* s, int length, int radix)
    441 {
    442     double number = 0.0;
    443     double radixMultiplier = 1.0;
    444 
    445     for (const char* p = s + length - 1; p >= s; p--) {
    446         if (radixMultiplier == Inf) {
    447             if (*p != '0') {
    448                 number = Inf;
    449                 break;
    450             }
    451         } else {
    452             int digit = parseDigit(*p, radix);
    453             number += digit * radixMultiplier;
    454         }
    455 
    456         radixMultiplier *= radix;
    457     }
    458 
    459     return number;
    460 }
    461 
    462 static double parseInt(const UString& s, int radix)
    463 {
    464     int length = s.size();
    465     int p = 0;
    466 
    467     while (p < length && isStrWhiteSpace(s[p])) {
    468         ++p;
    469     }
    470 
    471     double sign = 1;
    472     if (p < length) {
    473         if (s[p] == '+') {
    474             ++p;
    475         } else if (s[p] == '-') {
    476             sign = -1;
    477             ++p;
    478         }
    479     }
    480 
    481     if ((radix == 0 || radix == 16) && length - p >= 2 && s[p] == '0' && (s[p + 1] == 'x' || s[p + 1] == 'X')) {
    482         radix = 16;
    483         p += 2;
    484     } else if (radix == 0) {
    485         if (p < length && s[p] == '0')
    486             radix = 8;
    487         else
    488             radix = 10;
    489     }
    490 
    491     if (radix < 2 || radix > 36)
    492         return NaN;
    493 
    494     int firstDigitPosition = p;
    495     bool sawDigit = false;
    496     double number = 0;
    497     while (p < length) {
    498         int digit = parseDigit(s[p], radix);
    499         if (digit == -1)
    500             break;
    501         sawDigit = true;
    502         number *= radix;
    503         number += digit;
    504         ++p;
    505     }
    506 
    507     if (number >= mantissaOverflowLowerBound) {
    508         if (radix == 10)
    509             number = strtod(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), 0);
    510         else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32)
    511             number = parseIntOverflow(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), p - firstDigitPosition, radix);
    512     }
    513 
    514     if (!sawDigit)
    515         return NaN;
    516 
    517     return sign * number;
    518 }
    519 
    520 static double parseFloat(const UString& s)
    521 {
    522     // Check for 0x prefix here, because toDouble allows it, but we must treat it as 0.
    523     // Need to skip any whitespace and then one + or - sign.
    524     int length = s.size();
    525     int p = 0;
    526     while (p < length && isStrWhiteSpace(s[p])) {
    527         ++p;
    528     }
    529     if (p < length && (s[p] == '+' || s[p] == '-')) {
    530         ++p;
    531     }
    532     if (length - p >= 2 && s[p] == '0' && (s[p + 1] == 'x' || s[p + 1] == 'X')) {
    533         return 0;
    534     }
    535 
    536     return s.toDouble( true /*tolerant*/, false /* NaN for empty string */ );
    537 }
    538 
    539 JSValue* globalFuncEval(ExecState* exec, JSObject* function, JSValue* thisValue, const ArgList& args)
    540 {
    541     JSObject* thisObject = thisValue->toThisObject(exec);
    542     JSGlobalObject* globalObject = thisObject->toGlobalObject(exec);
    543     if (!globalObject || globalObject->evalFunction() != function)
    544         return throwError(exec, EvalError, "The \"this\" value passed to eval must be the global object from which eval originated");
    545 
    546     JSValue* x = args[0];
    547     if (!x->isString())
    548         return x;
    549    
    550     UString s = x->toString(exec);
    551    
    552     int sourceId;
    553     int errLine;
    554     UString errMsg;
    555 
    556     RefPtr<EvalNode> evalNode = exec->parser()->parse<EvalNode>(exec, UString(), 1, UStringSourceProvider::create(s), &sourceId, &errLine, &errMsg);
    557    
    558     if (!evalNode)
    559         return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL);
    560 
    561     return exec->machine()->execute(evalNode.get(), exec, thisObject, globalObject->globalScopeChain().node(), exec->exceptionSlot());
    562 }
    563 
    564 JSValue* globalFuncParseInt(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    565 {
    566     return jsNumber(exec, parseInt(args[0]->toString(exec), args[1]->toInt32(exec)));
    567 }
    568 
    569 JSValue* globalFuncParseFloat(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    570 {
    571     return jsNumber(exec, parseFloat(args[0]->toString(exec)));
    572 }
    573 
    574 JSValue* globalFuncIsNaN(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    575 {
    576     return jsBoolean(isnan(args[0]->toNumber(exec)));
    577 }
    578 
    579 JSValue* globalFuncIsFinite(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    580 {
    581     double n = args[0]->toNumber(exec);
    582     return jsBoolean(!isnan(n) && !isinf(n));
    583 }
    584 
    585 JSValue* globalFuncDecodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    586 {
    587     static const char do_not_unescape_when_decoding_URI[] =
    588         "#$&+,/:;=?@";
    589 
    590     return decode(exec, args, do_not_unescape_when_decoding_URI, true);
    591 }
    592 
    593 JSValue* globalFuncDecodeURIComponent(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    594 {
    595     return decode(exec, args, "", true);
    596 }
    597 
    598 JSValue* globalFuncEncodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    599 {
    600     static const char do_not_escape_when_encoding_URI[] =
    601         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    602         "abcdefghijklmnopqrstuvwxyz"
    603         "0123456789"
    604         "!#$&'()*+,-./:;=?@_~";
    605 
    606     return encode(exec, args, do_not_escape_when_encoding_URI);
    607 }
    608 
    609 JSValue* globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    610 {
    611     static const char do_not_escape_when_encoding_URI_component[] =
    612         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    613         "abcdefghijklmnopqrstuvwxyz"
    614         "0123456789"
    615         "!'()*-._~";
    616 
    617     return encode(exec, args, do_not_escape_when_encoding_URI_component);
    618 }
    619 
    620 JSValue* globalFuncEscape(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    621 {
    622     static const char do_not_escape[] =
    623         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    624         "abcdefghijklmnopqrstuvwxyz"
    625         "0123456789"
    626         "*+-./@_";
    627 
    628     UString r = "", s, str = args[0]->toString(exec);
    629     const UChar* c = str.data();
    630     for (int k = 0; k < str.size(); k++, c++) {
    631         int u = c[0];
    632         if (u > 255) {
    633             char tmp[7];
    634             sprintf(tmp, "%%u%04X", u);
    635             s = UString(tmp);
    636         } else if (u != 0 && strchr(do_not_escape, (char)u))
    637             s = UString(c, 1);
    638         else {
    639             char tmp[4];
    640             sprintf(tmp, "%%%02X", u);
    641             s = UString(tmp);
    642         }
    643         r += s;
    644     }
    645 
    646     return jsString(exec, r);
    647 }
    648 
    649 JSValue* globalFuncUnescape(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    650 {
    651     UString s = "", str = args[0]->toString(exec);
    652     int k = 0, len = str.size();
    653     while (k < len) {
    654         const UChar* c = str.data() + k;
    655         UChar u;
    656         if (c[0] == '%' && k <= len - 6 && c[1] == 'u') {
    657             if (Lexer::isHexDigit(c[2]) && Lexer::isHexDigit(c[3]) && Lexer::isHexDigit(c[4]) && Lexer::isHexDigit(c[5])) {
    658                 u = Lexer::convertUnicode(c[2], c[3], c[4], c[5]);
    659                 c = &u;
    660                 k += 5;
    661             }
    662         } else if (c[0] == '%' && k <= len - 3 && Lexer::isHexDigit(c[1]) && Lexer::isHexDigit(c[2])) {
    663             u = UChar(Lexer::convertHex(c[1], c[2]));
    664             c = &u;
    665             k += 2;
    666         }
    667         k++;
    668         s.append(*c);
    669     }
    670 
    671     return jsString(exec, s);
    672 }
    673 
    674 #ifndef NDEBUG
    675 JSValue* globalFuncKJSPrint(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    676 {
    677     CStringBuffer string;
    678     args[0]->toString(exec).getCString(string);
    679     puts(string.data());
    680     return jsUndefined();
    681 }
    682 #endif
    683 
    684 // ------------------------------ PrototypeFunction -------------------------------
    685 
    686 PrototypeFunction::PrototypeFunction(ExecState* exec, int len, const Identifier& name, NativeFunction function)
    687     : InternalFunction(exec->lexicalGlobalObject()->functionPrototype(), name)
    688     , m_function(function)
    689 {
    690     ASSERT_ARG(function, function);
    691     putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
    692 }
    693 
    694 PrototypeFunction::PrototypeFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, NativeFunction function)
    695     : InternalFunction(functionPrototype, name)
    696     , m_function(function)
    697 {
    698     ASSERT_ARG(function, function);
    699     putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
    700 }
    701 
    702 CallType PrototypeFunction::getCallData(CallData& callData)
    703 {
    704     callData.native.function = m_function;
    705     return CallTypeNative;
    706 }
    707 
    708 // ------------------------------ PrototypeReflexiveFunction -------------------------------
    709 
    710 GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, NativeFunction function, JSGlobalObject* cachedGlobalObject)
    711     : PrototypeFunction(exec, functionPrototype, len, name, function)
    712     , m_cachedGlobalObject(cachedGlobalObject)
    713 {
    714     ASSERT_ARG(cachedGlobalObject, cachedGlobalObject);
    715 }
    716 
    717 void GlobalEvalFunction::mark()
    718 {
    719     PrototypeFunction::mark();
    720     if (!m_cachedGlobalObject->marked())
    721         m_cachedGlobalObject->mark();
    722 }
    723 
    724172} // namespace KJS
  • trunk/JavaScriptCore/kjs/JSFunction.h

    r34901 r35016  
    7474  };
    7575
    76   class IndexToNameMap {
    77   public:
    78     IndexToNameMap(JSFunction*, const ArgList&);
    79     ~IndexToNameMap();
    80    
    81     Identifier& operator[](const Identifier& index);
    82     bool isMapped(const Identifier& index) const;
    83     void unMap(ExecState* exec, const Identifier& index);
    84    
    85   private:
    86     unsigned size;
    87     Identifier* _map;
    88   };
    89  
    90   class Arguments : public JSObject {
    91   public:
    92     Arguments(ExecState*, JSFunction* func, const ArgList& args, JSActivation* act);
    93     virtual void mark();
    94     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    95     virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
    96     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    97     virtual const ClassInfo* classInfo() const { return &info; }
    98     static const ClassInfo info;
    99   private:
    100     static JSValue* mappedIndexGetter(ExecState*, const Identifier&, const PropertySlot& slot);
     76} // namespace kJS
    10177
    102     JSActivation* _activationObject;
    103     mutable IndexToNameMap indexToNameMap;
    104   };
    105 
    106   class PrototypeFunction : public InternalFunction {
    107   public:
    108     PrototypeFunction(ExecState*, int len, const Identifier&, NativeFunction);
    109     PrototypeFunction(ExecState*, FunctionPrototype*, int len, const Identifier&, NativeFunction);
    110 
    111   private:
    112     virtual CallType getCallData(CallData&);
    113 
    114     const NativeFunction m_function;
    115   };
    116 
    117     class GlobalEvalFunction : public PrototypeFunction {
    118     public:
    119         GlobalEvalFunction(ExecState*, FunctionPrototype*, int len, const Identifier&, NativeFunction, JSGlobalObject* expectedThisObject);
    120         JSGlobalObject* cachedGlobalObject() const { return m_cachedGlobalObject; }
    121 
    122     private:
    123         virtual void mark();
    124 
    125         JSGlobalObject* m_cachedGlobalObject;
    126     };
    127 
    128     // Global Functions
    129     JSValue* globalFuncEval(ExecState*, JSObject*, JSValue*, const ArgList&);
    130     JSValue* globalFuncParseInt(ExecState*, JSObject*, JSValue*, const ArgList&);
    131     JSValue* globalFuncParseFloat(ExecState*, JSObject*, JSValue*, const ArgList&);
    132     JSValue* globalFuncIsNaN(ExecState*, JSObject*, JSValue*, const ArgList&);
    133     JSValue* globalFuncIsFinite(ExecState*, JSObject*, JSValue*, const ArgList&);
    134     JSValue* globalFuncDecodeURI(ExecState*, JSObject*, JSValue*, const ArgList&);
    135     JSValue* globalFuncDecodeURIComponent(ExecState*, JSObject*, JSValue*, const ArgList&);
    136     JSValue* globalFuncEncodeURI(ExecState*, JSObject*, JSValue*, const ArgList&);
    137     JSValue* globalFuncEncodeURIComponent(ExecState*, JSObject*, JSValue*, const ArgList&);
    138     JSValue* globalFuncEscape(ExecState*, JSObject*, JSValue*, const ArgList&);
    139     JSValue* globalFuncUnescape(ExecState*, JSObject*, JSValue*, const ArgList&);
    140 #ifndef NDEBUG
    141     JSValue* globalFuncKJSPrint(ExecState*, JSObject*, JSValue*, const ArgList&);
    142 #endif
    143 
    144     static const double mantissaOverflowLowerBound = 9007199254740992.0;
    145     double parseIntOverflow(const char*, int length, int radix);
    146 
    147 } // namespace
    148 
    149 #endif
     78#endif // JSFunction_h
  • trunk/JavaScriptCore/kjs/JSGlobalObject.cpp

    r34974 r35016  
    4242#include "FunctionConstructor.h"
    4343#include "FunctionPrototype.h"
     44#include "JSGlobalObjectFunctions.h"
    4445#include "JSLock.h"
    4546#include "Machine.h"
  • trunk/JavaScriptCore/kjs/JSGlobalObjectFunctions.cpp

    r35006 r35016  
    1 // -*- c-basic-offset: 2 -*-
    21/*
    32 *  Copyright (C) 1999-2002 Harri Porten ([email protected])
     
    2524
    2625#include "config.h"
    27 #include "JSFunction.h"
     26#include "JSGlobalObjectFunctions.h"
    2827
    2928#include "ExecState.h"
    30 #include "FunctionPrototype.h"
    31 #include "JSActivation.h"
     29#include "GlobalEvalFunction.h"
    3230#include "JSGlobalObject.h"
    3331#include "JSString.h"
    3432#include "Machine.h"
    35 #include "ObjectPrototype.h"
    3633#include "Parser.h"
    37 #include "PropertyNameArray.h"
    38 #include "ScopeChainMark.h"
    39 #include "debugger.h"
    4034#include "dtoa.h"
    4135#include "lexer.h"
    4236#include "nodes.h"
    43 #include "operations.h"
    4437#include <errno.h>
    45 #include <profiler/Profiler.h>
    4638#include <stdio.h>
    4739#include <stdlib.h>
     
    5648
    5749namespace KJS {
    58 
    59 // ----------------------------- JSFunction ----------------------------------
    60 
    61 const ClassInfo JSFunction::info = { "Function", &InternalFunction::info, 0, 0 };
    62 
    63 JSFunction::JSFunction(ExecState* exec, const Identifier& name, FunctionBodyNode* b, ScopeChainNode* scopeChain)
    64   : InternalFunction(exec->lexicalGlobalObject()->functionPrototype(), name)
    65   , body(b)
    66   , _scope(scopeChain)
    67 {
    68 }
    69 
    70 void JSFunction::mark()
    71 {
    72     InternalFunction::mark();
    73     body->mark();
    74     _scope.mark();
    75 }
    76 
    77 CallType JSFunction::getCallData(CallData& callData)
    78 {
    79     callData.js.functionBody = body.get();
    80     callData.js.scopeChain = _scope.node();
    81     return CallTypeJS;
    82 }
    83 
    84 JSValue* JSFunction::call(ExecState* exec, JSValue* thisValue, const ArgList& args)
    85 {
    86     return exec->machine()->execute(body.get(), exec, this, thisValue->toThisObject(exec), args, _scope.node(), exec->exceptionSlot());
    87 }
    88 
    89 JSValue* JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    90 {
    91     JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
    92     return exec->machine()->retrieveArguments(exec, thisObj);
    93 }
    94 
    95 JSValue* JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    96 {
    97     JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
    98     return exec->machine()->retrieveCaller(exec, thisObj);
    99 }
    100 
    101 JSValue* JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    102 {
    103     JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
    104     return jsNumber(exec, thisObj->body->parameters().size());
    105 }
    106 
    107 bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
    108 {
    109     if (propertyName == exec->propertyNames().arguments) {
    110         slot.setCustom(this, argumentsGetter);
    111         return true;
    112     }
    113 
    114     if (propertyName == exec->propertyNames().length) {
    115         slot.setCustom(this, lengthGetter);
    116         return true;
    117     }
    118 
    119     if (propertyName == exec->propertyNames().caller) {
    120         slot.setCustom(this, callerGetter);
    121         return true;
    122     }
    123 
    124     return InternalFunction::getOwnPropertySlot(exec, propertyName, slot);
    125 }
    126 
    127 void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
    128 {
    129     if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
    130         return;
    131     InternalFunction::put(exec, propertyName, value);
    132 }
    133 
    134 bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
    135 {
    136     if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
    137         return false;
    138     return InternalFunction::deleteProperty(exec, propertyName);
    139 }
    140 
    141 /* Returns the parameter name corresponding to the given index. eg:
    142  * function f1(x, y, z): getParameterName(0) --> x
    143  *
    144  * If a name appears more than once, only the last index at which
    145  * it appears associates with it. eg:
    146  * function f2(x, x): getParameterName(0) --> null
    147  */
    148 const Identifier& JSFunction::getParameterName(int index)
    149 {
    150     Vector<Identifier>& parameters = body->parameters();
    151 
    152     if (static_cast<size_t>(index) >= body->parameters().size())
    153         return _scope.globalObject()->globalData()->propertyNames->nullIdentifier;
    154  
    155     const Identifier& name = parameters[index];
    156 
    157     // Are there any subsequent parameters with the same name?
    158     size_t size = parameters.size();
    159     for (size_t i = index + 1; i < size; ++i)
    160         if (parameters[i] == name)
    161             return _scope.globalObject()->globalData()->propertyNames->nullIdentifier;
    162 
    163     return name;
    164 }
    165 
    166 // ECMA 13.2.2 [[Construct]]
    167 ConstructType JSFunction::getConstructData(ConstructData& constructData)
    168 {
    169     constructData.js.functionBody = body.get();
    170     constructData.js.scopeChain = _scope.node();
    171     return ConstructTypeJS;
    172 }
    173 
    174 JSObject* JSFunction::construct(ExecState* exec, const ArgList& args)
    175 {
    176     JSObject* proto;
    177     JSValue* p = get(exec, exec->propertyNames().prototype);
    178     if (p->isObject())
    179         proto = static_cast<JSObject*>(p);
    180     else
    181         proto = exec->lexicalGlobalObject()->objectPrototype();
    182 
    183     JSObject* thisObj = new (exec) JSObject(proto);
    184 
    185     JSValue* result = exec->machine()->execute(body.get(), exec, this, thisObj, args, _scope.node(), exec->exceptionSlot());
    186     if (exec->hadException() || !result->isObject())
    187         return thisObj;
    188     return static_cast<JSObject*>(result);
    189 }
    190 
    191 // ------------------------------ IndexToNameMap ---------------------------------
    192 
    193 // We map indexes in the arguments array to their corresponding argument names.
    194 // Example: function f(x, y, z): arguments[0] = x, so we map 0 to Identifier("x").
    195 
    196 // Once we have an argument name, we can get and set the argument's value in the
    197 // activation object.
    198 
    199 // We use Identifier::null to indicate that a given argument's value
    200 // isn't stored in the activation object.
    201 
    202 IndexToNameMap::IndexToNameMap(JSFunction* func, const ArgList& args)
    203 {
    204   _map = new Identifier[args.size()];
    205   this->size = args.size();
    206  
    207   unsigned i = 0;
    208   ArgList::const_iterator end = args.end();
    209   for (ArgList::const_iterator it = args.begin(); it != end; ++i, ++it)
    210     _map[i] = func->getParameterName(i); // null if there is no corresponding parameter
    211 }
    212 
    213 IndexToNameMap::~IndexToNameMap()
    214 {
    215   delete [] _map;
    216 }
    217 
    218 bool IndexToNameMap::isMapped(const Identifier& index) const
    219 {
    220   bool indexIsNumber;
    221   unsigned indexAsNumber = index.toStrictUInt32(&indexIsNumber);
    222  
    223   if (!indexIsNumber)
    224     return false;
    225  
    226   if (indexAsNumber >= size)
    227     return false;
    228 
    229   if (_map[indexAsNumber].isNull())
    230     return false;
    231  
    232   return true;
    233 }
    234 
    235 void IndexToNameMap::unMap(ExecState* exec, const Identifier& index)
    236 {
    237   bool indexIsNumber;
    238   unsigned indexAsNumber = index.toStrictUInt32(&indexIsNumber);
    239 
    240   ASSERT(indexIsNumber && indexAsNumber < size);
    241  
    242   _map[indexAsNumber] = exec->propertyNames().nullIdentifier;
    243 }
    244 
    245 Identifier& IndexToNameMap::operator[](const Identifier& index)
    246 {
    247   bool indexIsNumber;
    248   unsigned indexAsNumber = index.toStrictUInt32(&indexIsNumber);
    249 
    250   ASSERT(indexIsNumber && indexAsNumber < size);
    251  
    252   return _map[indexAsNumber];
    253 }
    254 
    255 // ------------------------------ Arguments ---------------------------------
    256 
    257 const ClassInfo Arguments::info = { "Arguments", 0, 0, 0 };
    258 
    259 // ECMA 10.1.8
    260 Arguments::Arguments(ExecState* exec, JSFunction* func, const ArgList& args, JSActivation* act)
    261     : JSObject(exec->lexicalGlobalObject()->objectPrototype())
    262     , _activationObject(act)
    263     , indexToNameMap(func, args)
    264 {
    265     putDirect(exec->propertyNames().callee, func, DontEnum);
    266     putDirect(exec, exec->propertyNames().length, args.size(), DontEnum);
    267  
    268     int i = 0;
    269     ArgList::const_iterator end = args.end();
    270     for (ArgList::const_iterator it = args.begin(); it != end; ++it, ++i) {
    271         Identifier name = Identifier::from(exec, i);
    272         if (!indexToNameMap.isMapped(name))
    273             putDirect(name, *it, DontEnum);
    274     }
    275 }
    276 
    277 void Arguments::mark()
    278 {
    279   JSObject::mark();
    280   if (_activationObject && !_activationObject->marked())
    281     _activationObject->mark();
    282 }
    283 
    284 JSValue* Arguments::mappedIndexGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
    285 {
    286   Arguments* thisObj = static_cast<Arguments*>(slot.slotBase());
    287   return thisObj->_activationObject->get(exec, thisObj->indexToNameMap[propertyName]);
    288 }
    289 
    290 bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
    291 {
    292   if (indexToNameMap.isMapped(propertyName)) {
    293     slot.setCustom(this, mappedIndexGetter);
    294     return true;
    295   }
    296 
    297   return JSObject::getOwnPropertySlot(exec, propertyName, slot);
    298 }
    299 
    300 void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
    301 {
    302     if (indexToNameMap.isMapped(propertyName))
    303         _activationObject->put(exec, indexToNameMap[propertyName], value);
    304     else
    305         JSObject::put(exec, propertyName, value);
    306 }
    307 
    308 bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName)
    309 {
    310   if (indexToNameMap.isMapped(propertyName)) {
    311     indexToNameMap.unMap(exec, propertyName);
    312     return true;
    313   } else {
    314     return JSObject::deleteProperty(exec, propertyName);
    315   }
    316 }
    317 
    318 // ------------------------------ Global Functions -----------------------------------
    31950
    32051static JSValue* encode(ExecState* exec, const ArgList& args, const char* do_not_escape)
     
    682413#endif
    683414
    684 // ------------------------------ PrototypeFunction -------------------------------
    685 
    686 PrototypeFunction::PrototypeFunction(ExecState* exec, int len, const Identifier& name, NativeFunction function)
    687     : InternalFunction(exec->lexicalGlobalObject()->functionPrototype(), name)
    688     , m_function(function)
    689 {
    690     ASSERT_ARG(function, function);
    691     putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
    692 }
    693 
    694 PrototypeFunction::PrototypeFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, NativeFunction function)
    695     : InternalFunction(functionPrototype, name)
    696     , m_function(function)
    697 {
    698     ASSERT_ARG(function, function);
    699     putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
    700 }
    701 
    702 CallType PrototypeFunction::getCallData(CallData& callData)
    703 {
    704     callData.native.function = m_function;
    705     return CallTypeNative;
    706 }
    707 
    708 // ------------------------------ PrototypeReflexiveFunction -------------------------------
    709 
    710 GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, NativeFunction function, JSGlobalObject* cachedGlobalObject)
    711     : PrototypeFunction(exec, functionPrototype, len, name, function)
    712     , m_cachedGlobalObject(cachedGlobalObject)
    713 {
    714     ASSERT_ARG(cachedGlobalObject, cachedGlobalObject);
    715 }
    716 
    717 void GlobalEvalFunction::mark()
    718 {
    719     PrototypeFunction::mark();
    720     if (!m_cachedGlobalObject->marked())
    721         m_cachedGlobalObject->mark();
    722 }
    723 
    724415} // namespace KJS
  • trunk/JavaScriptCore/kjs/JSGlobalObjectFunctions.h

    r35006 r35016  
    2222 */
    2323
    24 #ifndef JSFunction_h
    25 #define JSFunction_h
    26 
    27 #include "InternalFunction.h"
    28 #include "JSVariableObject.h"
    29 #include "SymbolTable.h"
    30 #include "nodes.h"
    31 #include "JSObject.h"
     24#ifndef JSGlobalObjectFunctions_h
     25#define JSGlobalObjectFunctions_h
    3226
    3327namespace KJS {
    3428
    35   class FunctionBodyNode;
    36   class FunctionPrototype;
    37   class JSActivation;
    38   class JSGlobalObject;
     29    class ArgList;
     30    class ExecState;
     31    class JSObject;
     32    class JSValue;
    3933
    40   class JSFunction : public InternalFunction {
    41   public:
    42     JSFunction(ExecState*, const Identifier&, FunctionBodyNode*, ScopeChainNode*);
     34    // FIXME: These functions should really be in JSGlobalObject.cpp, but putting them there
     35    // is a 0.5% reduction.
    4336
    44     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    45     virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
    46     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    47 
    48     JSObject* construct(ExecState*, const ArgList&);
    49     JSValue* call(ExecState*, JSValue* thisValue, const ArgList&);
    50 
    51     // Note: Returns a null identifier for any parameters that will never get set
    52     // due to a later parameter with the same name.
    53     const Identifier& getParameterName(int index);
    54 
    55     static const ClassInfo info;
    56 
    57     RefPtr<FunctionBodyNode> body;
    58 
    59     void setScope(const ScopeChain& s) { _scope = s; }
    60     ScopeChain& scope() { return _scope; }
    61 
    62     virtual void mark();
    63 
    64   private:
    65     virtual const ClassInfo* classInfo() const { return &info; }
    66     virtual ConstructType getConstructData(ConstructData&);
    67     virtual CallType getCallData(CallData&);
    68 
    69     ScopeChain _scope;
    70 
    71     static JSValue* argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
    72     static JSValue* callerGetter(ExecState*, const Identifier&, const PropertySlot&);
    73     static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
    74   };
    75 
    76   class IndexToNameMap {
    77   public:
    78     IndexToNameMap(JSFunction*, const ArgList&);
    79     ~IndexToNameMap();
    80    
    81     Identifier& operator[](const Identifier& index);
    82     bool isMapped(const Identifier& index) const;
    83     void unMap(ExecState* exec, const Identifier& index);
    84    
    85   private:
    86     unsigned size;
    87     Identifier* _map;
    88   };
    89  
    90   class Arguments : public JSObject {
    91   public:
    92     Arguments(ExecState*, JSFunction* func, const ArgList& args, JSActivation* act);
    93     virtual void mark();
    94     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    95     virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
    96     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    97     virtual const ClassInfo* classInfo() const { return &info; }
    98     static const ClassInfo info;
    99   private:
    100     static JSValue* mappedIndexGetter(ExecState*, const Identifier&, const PropertySlot& slot);
    101 
    102     JSActivation* _activationObject;
    103     mutable IndexToNameMap indexToNameMap;
    104   };
    105 
    106   class PrototypeFunction : public InternalFunction {
    107   public:
    108     PrototypeFunction(ExecState*, int len, const Identifier&, NativeFunction);
    109     PrototypeFunction(ExecState*, FunctionPrototype*, int len, const Identifier&, NativeFunction);
    110 
    111   private:
    112     virtual CallType getCallData(CallData&);
    113 
    114     const NativeFunction m_function;
    115   };
    116 
    117     class GlobalEvalFunction : public PrototypeFunction {
    118     public:
    119         GlobalEvalFunction(ExecState*, FunctionPrototype*, int len, const Identifier&, NativeFunction, JSGlobalObject* expectedThisObject);
    120         JSGlobalObject* cachedGlobalObject() const { return m_cachedGlobalObject; }
    121 
    122     private:
    123         virtual void mark();
    124 
    125         JSGlobalObject* m_cachedGlobalObject;
    126     };
    127 
    128     // Global Functions
    12937    JSValue* globalFuncEval(ExecState*, JSObject*, JSValue*, const ArgList&);
    13038    JSValue* globalFuncParseInt(ExecState*, JSObject*, JSValue*, const ArgList&);
     
    14553    double parseIntOverflow(const char*, int length, int radix);
    14654
    147 } // namespace
     55} // namespace KJS
    14856
    149 #endif
     57#endif // JSGlobalObjectFunctions_h
  • trunk/JavaScriptCore/kjs/PrototypeFunction.cpp

    r35006 r35016  
    1 // -*- c-basic-offset: 2 -*-
    21/*
    32 *  Copyright (C) 1999-2002 Harri Porten ([email protected])
     
    2524
    2625#include "config.h"
    27 #include "JSFunction.h"
     26#include "PrototypeFunction.h"
    2827
    29 #include "ExecState.h"
    3028#include "FunctionPrototype.h"
    31 #include "JSActivation.h"
    3229#include "JSGlobalObject.h"
    33 #include "JSString.h"
    34 #include "Machine.h"
    35 #include "ObjectPrototype.h"
    36 #include "Parser.h"
    37 #include "PropertyNameArray.h"
    38 #include "ScopeChainMark.h"
    39 #include "debugger.h"
    40 #include "dtoa.h"
    41 #include "lexer.h"
    42 #include "nodes.h"
    43 #include "operations.h"
    44 #include <errno.h>
    45 #include <profiler/Profiler.h>
    46 #include <stdio.h>
    47 #include <stdlib.h>
    48 #include <string.h>
    49 #include <wtf/ASCIICType.h>
    5030#include <wtf/Assertions.h>
    51 #include <wtf/MathExtras.h>
    52 #include <wtf/unicode/UTF8.h>
    53 
    54 using namespace WTF;
    55 using namespace Unicode;
    5631
    5732namespace KJS {
    58 
    59 // ----------------------------- JSFunction ----------------------------------
    60 
    61 const ClassInfo JSFunction::info = { "Function", &InternalFunction::info, 0, 0 };
    62 
    63 JSFunction::JSFunction(ExecState* exec, const Identifier& name, FunctionBodyNode* b, ScopeChainNode* scopeChain)
    64   : InternalFunction(exec->lexicalGlobalObject()->functionPrototype(), name)
    65   , body(b)
    66   , _scope(scopeChain)
    67 {
    68 }
    69 
    70 void JSFunction::mark()
    71 {
    72     InternalFunction::mark();
    73     body->mark();
    74     _scope.mark();
    75 }
    76 
    77 CallType JSFunction::getCallData(CallData& callData)
    78 {
    79     callData.js.functionBody = body.get();
    80     callData.js.scopeChain = _scope.node();
    81     return CallTypeJS;
    82 }
    83 
    84 JSValue* JSFunction::call(ExecState* exec, JSValue* thisValue, const ArgList& args)
    85 {
    86     return exec->machine()->execute(body.get(), exec, this, thisValue->toThisObject(exec), args, _scope.node(), exec->exceptionSlot());
    87 }
    88 
    89 JSValue* JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    90 {
    91     JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
    92     return exec->machine()->retrieveArguments(exec, thisObj);
    93 }
    94 
    95 JSValue* JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    96 {
    97     JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
    98     return exec->machine()->retrieveCaller(exec, thisObj);
    99 }
    100 
    101 JSValue* JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    102 {
    103     JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
    104     return jsNumber(exec, thisObj->body->parameters().size());
    105 }
    106 
    107 bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
    108 {
    109     if (propertyName == exec->propertyNames().arguments) {
    110         slot.setCustom(this, argumentsGetter);
    111         return true;
    112     }
    113 
    114     if (propertyName == exec->propertyNames().length) {
    115         slot.setCustom(this, lengthGetter);
    116         return true;
    117     }
    118 
    119     if (propertyName == exec->propertyNames().caller) {
    120         slot.setCustom(this, callerGetter);
    121         return true;
    122     }
    123 
    124     return InternalFunction::getOwnPropertySlot(exec, propertyName, slot);
    125 }
    126 
    127 void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
    128 {
    129     if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
    130         return;
    131     InternalFunction::put(exec, propertyName, value);
    132 }
    133 
    134 bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
    135 {
    136     if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
    137         return false;
    138     return InternalFunction::deleteProperty(exec, propertyName);
    139 }
    140 
    141 /* Returns the parameter name corresponding to the given index. eg:
    142  * function f1(x, y, z): getParameterName(0) --> x
    143  *
    144  * If a name appears more than once, only the last index at which
    145  * it appears associates with it. eg:
    146  * function f2(x, x): getParameterName(0) --> null
    147  */
    148 const Identifier& JSFunction::getParameterName(int index)
    149 {
    150     Vector<Identifier>& parameters = body->parameters();
    151 
    152     if (static_cast<size_t>(index) >= body->parameters().size())
    153         return _scope.globalObject()->globalData()->propertyNames->nullIdentifier;
    154  
    155     const Identifier& name = parameters[index];
    156 
    157     // Are there any subsequent parameters with the same name?
    158     size_t size = parameters.size();
    159     for (size_t i = index + 1; i < size; ++i)
    160         if (parameters[i] == name)
    161             return _scope.globalObject()->globalData()->propertyNames->nullIdentifier;
    162 
    163     return name;
    164 }
    165 
    166 // ECMA 13.2.2 [[Construct]]
    167 ConstructType JSFunction::getConstructData(ConstructData& constructData)
    168 {
    169     constructData.js.functionBody = body.get();
    170     constructData.js.scopeChain = _scope.node();
    171     return ConstructTypeJS;
    172 }
    173 
    174 JSObject* JSFunction::construct(ExecState* exec, const ArgList& args)
    175 {
    176     JSObject* proto;
    177     JSValue* p = get(exec, exec->propertyNames().prototype);
    178     if (p->isObject())
    179         proto = static_cast<JSObject*>(p);
    180     else
    181         proto = exec->lexicalGlobalObject()->objectPrototype();
    182 
    183     JSObject* thisObj = new (exec) JSObject(proto);
    184 
    185     JSValue* result = exec->machine()->execute(body.get(), exec, this, thisObj, args, _scope.node(), exec->exceptionSlot());
    186     if (exec->hadException() || !result->isObject())
    187         return thisObj;
    188     return static_cast<JSObject*>(result);
    189 }
    190 
    191 // ------------------------------ IndexToNameMap ---------------------------------
    192 
    193 // We map indexes in the arguments array to their corresponding argument names.
    194 // Example: function f(x, y, z): arguments[0] = x, so we map 0 to Identifier("x").
    195 
    196 // Once we have an argument name, we can get and set the argument's value in the
    197 // activation object.
    198 
    199 // We use Identifier::null to indicate that a given argument's value
    200 // isn't stored in the activation object.
    201 
    202 IndexToNameMap::IndexToNameMap(JSFunction* func, const ArgList& args)
    203 {
    204   _map = new Identifier[args.size()];
    205   this->size = args.size();
    206  
    207   unsigned i = 0;
    208   ArgList::const_iterator end = args.end();
    209   for (ArgList::const_iterator it = args.begin(); it != end; ++i, ++it)
    210     _map[i] = func->getParameterName(i); // null if there is no corresponding parameter
    211 }
    212 
    213 IndexToNameMap::~IndexToNameMap()
    214 {
    215   delete [] _map;
    216 }
    217 
    218 bool IndexToNameMap::isMapped(const Identifier& index) const
    219 {
    220   bool indexIsNumber;
    221   unsigned indexAsNumber = index.toStrictUInt32(&indexIsNumber);
    222  
    223   if (!indexIsNumber)
    224     return false;
    225  
    226   if (indexAsNumber >= size)
    227     return false;
    228 
    229   if (_map[indexAsNumber].isNull())
    230     return false;
    231  
    232   return true;
    233 }
    234 
    235 void IndexToNameMap::unMap(ExecState* exec, const Identifier& index)
    236 {
    237   bool indexIsNumber;
    238   unsigned indexAsNumber = index.toStrictUInt32(&indexIsNumber);
    239 
    240   ASSERT(indexIsNumber && indexAsNumber < size);
    241  
    242   _map[indexAsNumber] = exec->propertyNames().nullIdentifier;
    243 }
    244 
    245 Identifier& IndexToNameMap::operator[](const Identifier& index)
    246 {
    247   bool indexIsNumber;
    248   unsigned indexAsNumber = index.toStrictUInt32(&indexIsNumber);
    249 
    250   ASSERT(indexIsNumber && indexAsNumber < size);
    251  
    252   return _map[indexAsNumber];
    253 }
    254 
    255 // ------------------------------ Arguments ---------------------------------
    256 
    257 const ClassInfo Arguments::info = { "Arguments", 0, 0, 0 };
    258 
    259 // ECMA 10.1.8
    260 Arguments::Arguments(ExecState* exec, JSFunction* func, const ArgList& args, JSActivation* act)
    261     : JSObject(exec->lexicalGlobalObject()->objectPrototype())
    262     , _activationObject(act)
    263     , indexToNameMap(func, args)
    264 {
    265     putDirect(exec->propertyNames().callee, func, DontEnum);
    266     putDirect(exec, exec->propertyNames().length, args.size(), DontEnum);
    267  
    268     int i = 0;
    269     ArgList::const_iterator end = args.end();
    270     for (ArgList::const_iterator it = args.begin(); it != end; ++it, ++i) {
    271         Identifier name = Identifier::from(exec, i);
    272         if (!indexToNameMap.isMapped(name))
    273             putDirect(name, *it, DontEnum);
    274     }
    275 }
    276 
    277 void Arguments::mark()
    278 {
    279   JSObject::mark();
    280   if (_activationObject && !_activationObject->marked())
    281     _activationObject->mark();
    282 }
    283 
    284 JSValue* Arguments::mappedIndexGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
    285 {
    286   Arguments* thisObj = static_cast<Arguments*>(slot.slotBase());
    287   return thisObj->_activationObject->get(exec, thisObj->indexToNameMap[propertyName]);
    288 }
    289 
    290 bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
    291 {
    292   if (indexToNameMap.isMapped(propertyName)) {
    293     slot.setCustom(this, mappedIndexGetter);
    294     return true;
    295   }
    296 
    297   return JSObject::getOwnPropertySlot(exec, propertyName, slot);
    298 }
    299 
    300 void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
    301 {
    302     if (indexToNameMap.isMapped(propertyName))
    303         _activationObject->put(exec, indexToNameMap[propertyName], value);
    304     else
    305         JSObject::put(exec, propertyName, value);
    306 }
    307 
    308 bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName)
    309 {
    310   if (indexToNameMap.isMapped(propertyName)) {
    311     indexToNameMap.unMap(exec, propertyName);
    312     return true;
    313   } else {
    314     return JSObject::deleteProperty(exec, propertyName);
    315   }
    316 }
    317 
    318 // ------------------------------ Global Functions -----------------------------------
    319 
    320 static JSValue* encode(ExecState* exec, const ArgList& args, const char* do_not_escape)
    321 {
    322   UString r = "", s, str = args[0]->toString(exec);
    323   CString cstr = str.UTF8String(true);
    324   if (!cstr.c_str())
    325     return throwError(exec, URIError, "String contained an illegal UTF-16 sequence.");
    326   const char* p = cstr.c_str();
    327   for (size_t k = 0; k < cstr.size(); k++, p++) {
    328     char c = *p;
    329     if (c && strchr(do_not_escape, c)) {
    330       r.append(c);
    331     } else {
    332       char tmp[4];
    333       sprintf(tmp, "%%%02X", (unsigned char)c);
    334       r += tmp;
    335     }
    336   }
    337   return jsString(exec, r);
    338 }
    339 
    340 static JSValue* decode(ExecState* exec, const ArgList& args, const char* do_not_unescape, bool strict)
    341 {
    342   UString s = "", str = args[0]->toString(exec);
    343   int k = 0, len = str.size();
    344   const UChar* d = str.data();
    345   UChar u = 0;
    346   while (k < len) {
    347     const UChar* p = d + k;
    348     UChar c = *p;
    349     if (c == '%') {
    350       int charLen = 0;
    351       if (k <= len - 3 && isASCIIHexDigit(p[1]) && isASCIIHexDigit(p[2])) {
    352         const char b0 = Lexer::convertHex(p[1], p[2]);
    353         const int sequenceLen = UTF8SequenceLength(b0);
    354         if (sequenceLen != 0 && k <= len - sequenceLen * 3) {
    355           charLen = sequenceLen * 3;
    356           char sequence[5];
    357           sequence[0] = b0;
    358           for (int i = 1; i < sequenceLen; ++i) {
    359             const UChar* q = p + i * 3;
    360             if (q[0] == '%' && isASCIIHexDigit(q[1]) && isASCIIHexDigit(q[2]))
    361               sequence[i] = Lexer::convertHex(q[1], q[2]);
    362             else {
    363               charLen = 0;
    364               break;
    365             }
    366           }
    367           if (charLen != 0) {
    368             sequence[sequenceLen] = 0;
    369             const int character = decodeUTF8Sequence(sequence);
    370             if (character < 0 || character >= 0x110000) {
    371               charLen = 0;
    372             } else if (character >= 0x10000) {
    373               // Convert to surrogate pair.
    374               s.append(static_cast<UChar>(0xD800 | ((character - 0x10000) >> 10)));
    375               u = static_cast<UChar>(0xDC00 | ((character - 0x10000) & 0x3FF));
    376             } else {
    377               u = static_cast<UChar>(character);
    378             }
    379           }
    380         }
    381       }
    382       if (charLen == 0) {
    383         if (strict)
    384           return throwError(exec, URIError);
    385         // The only case where we don't use "strict" mode is the "unescape" function.
    386         // For that, it's good to support the wonky "%u" syntax for compatibility with WinIE.
    387         if (k <= len - 6 && p[1] == 'u'
    388             && isASCIIHexDigit(p[2]) && isASCIIHexDigit(p[3])
    389             && isASCIIHexDigit(p[4]) && isASCIIHexDigit(p[5])) {
    390           charLen = 6;
    391           u = Lexer::convertUnicode(p[2], p[3], p[4], p[5]);
    392         }
    393       }
    394       if (charLen && (u == 0 || u >= 128 || !strchr(do_not_unescape, u))) {
    395         c = u;
    396         k += charLen - 1;
    397       }
    398     }
    399     k++;
    400     s.append(c);
    401   }
    402   return jsString(exec, s);
    403 }
    404 
    405 static bool isStrWhiteSpace(unsigned short c)
    406 {
    407     switch (c) {
    408         case 0x0009:
    409         case 0x000A:
    410         case 0x000B:
    411         case 0x000C:
    412         case 0x000D:
    413         case 0x0020:
    414         case 0x00A0:
    415         case 0x2028:
    416         case 0x2029:
    417             return true;
    418         default:
    419             return c > 0xff && isSeparatorSpace(c);
    420     }
    421 }
    422 
    423 static int parseDigit(unsigned short c, int radix)
    424 {
    425     int digit = -1;
    426 
    427     if (c >= '0' && c <= '9') {
    428         digit = c - '0';
    429     } else if (c >= 'A' && c <= 'Z') {
    430         digit = c - 'A' + 10;
    431     } else if (c >= 'a' && c <= 'z') {
    432         digit = c - 'a' + 10;
    433     }
    434 
    435     if (digit >= radix)
    436         return -1;
    437     return digit;
    438 }
    439 
    440 double parseIntOverflow(const char* s, int length, int radix)
    441 {
    442     double number = 0.0;
    443     double radixMultiplier = 1.0;
    444 
    445     for (const char* p = s + length - 1; p >= s; p--) {
    446         if (radixMultiplier == Inf) {
    447             if (*p != '0') {
    448                 number = Inf;
    449                 break;
    450             }
    451         } else {
    452             int digit = parseDigit(*p, radix);
    453             number += digit * radixMultiplier;
    454         }
    455 
    456         radixMultiplier *= radix;
    457     }
    458 
    459     return number;
    460 }
    461 
    462 static double parseInt(const UString& s, int radix)
    463 {
    464     int length = s.size();
    465     int p = 0;
    466 
    467     while (p < length && isStrWhiteSpace(s[p])) {
    468         ++p;
    469     }
    470 
    471     double sign = 1;
    472     if (p < length) {
    473         if (s[p] == '+') {
    474             ++p;
    475         } else if (s[p] == '-') {
    476             sign = -1;
    477             ++p;
    478         }
    479     }
    480 
    481     if ((radix == 0 || radix == 16) && length - p >= 2 && s[p] == '0' && (s[p + 1] == 'x' || s[p + 1] == 'X')) {
    482         radix = 16;
    483         p += 2;
    484     } else if (radix == 0) {
    485         if (p < length && s[p] == '0')
    486             radix = 8;
    487         else
    488             radix = 10;
    489     }
    490 
    491     if (radix < 2 || radix > 36)
    492         return NaN;
    493 
    494     int firstDigitPosition = p;
    495     bool sawDigit = false;
    496     double number = 0;
    497     while (p < length) {
    498         int digit = parseDigit(s[p], radix);
    499         if (digit == -1)
    500             break;
    501         sawDigit = true;
    502         number *= radix;
    503         number += digit;
    504         ++p;
    505     }
    506 
    507     if (number >= mantissaOverflowLowerBound) {
    508         if (radix == 10)
    509             number = strtod(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), 0);
    510         else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32)
    511             number = parseIntOverflow(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), p - firstDigitPosition, radix);
    512     }
    513 
    514     if (!sawDigit)
    515         return NaN;
    516 
    517     return sign * number;
    518 }
    519 
    520 static double parseFloat(const UString& s)
    521 {
    522     // Check for 0x prefix here, because toDouble allows it, but we must treat it as 0.
    523     // Need to skip any whitespace and then one + or - sign.
    524     int length = s.size();
    525     int p = 0;
    526     while (p < length && isStrWhiteSpace(s[p])) {
    527         ++p;
    528     }
    529     if (p < length && (s[p] == '+' || s[p] == '-')) {
    530         ++p;
    531     }
    532     if (length - p >= 2 && s[p] == '0' && (s[p + 1] == 'x' || s[p + 1] == 'X')) {
    533         return 0;
    534     }
    535 
    536     return s.toDouble( true /*tolerant*/, false /* NaN for empty string */ );
    537 }
    538 
    539 JSValue* globalFuncEval(ExecState* exec, JSObject* function, JSValue* thisValue, const ArgList& args)
    540 {
    541     JSObject* thisObject = thisValue->toThisObject(exec);
    542     JSGlobalObject* globalObject = thisObject->toGlobalObject(exec);
    543     if (!globalObject || globalObject->evalFunction() != function)
    544         return throwError(exec, EvalError, "The \"this\" value passed to eval must be the global object from which eval originated");
    545 
    546     JSValue* x = args[0];
    547     if (!x->isString())
    548         return x;
    549    
    550     UString s = x->toString(exec);
    551    
    552     int sourceId;
    553     int errLine;
    554     UString errMsg;
    555 
    556     RefPtr<EvalNode> evalNode = exec->parser()->parse<EvalNode>(exec, UString(), 1, UStringSourceProvider::create(s), &sourceId, &errLine, &errMsg);
    557    
    558     if (!evalNode)
    559         return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL);
    560 
    561     return exec->machine()->execute(evalNode.get(), exec, thisObject, globalObject->globalScopeChain().node(), exec->exceptionSlot());
    562 }
    563 
    564 JSValue* globalFuncParseInt(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    565 {
    566     return jsNumber(exec, parseInt(args[0]->toString(exec), args[1]->toInt32(exec)));
    567 }
    568 
    569 JSValue* globalFuncParseFloat(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    570 {
    571     return jsNumber(exec, parseFloat(args[0]->toString(exec)));
    572 }
    573 
    574 JSValue* globalFuncIsNaN(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    575 {
    576     return jsBoolean(isnan(args[0]->toNumber(exec)));
    577 }
    578 
    579 JSValue* globalFuncIsFinite(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    580 {
    581     double n = args[0]->toNumber(exec);
    582     return jsBoolean(!isnan(n) && !isinf(n));
    583 }
    584 
    585 JSValue* globalFuncDecodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    586 {
    587     static const char do_not_unescape_when_decoding_URI[] =
    588         "#$&+,/:;=?@";
    589 
    590     return decode(exec, args, do_not_unescape_when_decoding_URI, true);
    591 }
    592 
    593 JSValue* globalFuncDecodeURIComponent(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    594 {
    595     return decode(exec, args, "", true);
    596 }
    597 
    598 JSValue* globalFuncEncodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    599 {
    600     static const char do_not_escape_when_encoding_URI[] =
    601         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    602         "abcdefghijklmnopqrstuvwxyz"
    603         "0123456789"
    604         "!#$&'()*+,-./:;=?@_~";
    605 
    606     return encode(exec, args, do_not_escape_when_encoding_URI);
    607 }
    608 
    609 JSValue* globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    610 {
    611     static const char do_not_escape_when_encoding_URI_component[] =
    612         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    613         "abcdefghijklmnopqrstuvwxyz"
    614         "0123456789"
    615         "!'()*-._~";
    616 
    617     return encode(exec, args, do_not_escape_when_encoding_URI_component);
    618 }
    619 
    620 JSValue* globalFuncEscape(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    621 {
    622     static const char do_not_escape[] =
    623         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    624         "abcdefghijklmnopqrstuvwxyz"
    625         "0123456789"
    626         "*+-./@_";
    627 
    628     UString r = "", s, str = args[0]->toString(exec);
    629     const UChar* c = str.data();
    630     for (int k = 0; k < str.size(); k++, c++) {
    631         int u = c[0];
    632         if (u > 255) {
    633             char tmp[7];
    634             sprintf(tmp, "%%u%04X", u);
    635             s = UString(tmp);
    636         } else if (u != 0 && strchr(do_not_escape, (char)u))
    637             s = UString(c, 1);
    638         else {
    639             char tmp[4];
    640             sprintf(tmp, "%%%02X", u);
    641             s = UString(tmp);
    642         }
    643         r += s;
    644     }
    645 
    646     return jsString(exec, r);
    647 }
    648 
    649 JSValue* globalFuncUnescape(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    650 {
    651     UString s = "", str = args[0]->toString(exec);
    652     int k = 0, len = str.size();
    653     while (k < len) {
    654         const UChar* c = str.data() + k;
    655         UChar u;
    656         if (c[0] == '%' && k <= len - 6 && c[1] == 'u') {
    657             if (Lexer::isHexDigit(c[2]) && Lexer::isHexDigit(c[3]) && Lexer::isHexDigit(c[4]) && Lexer::isHexDigit(c[5])) {
    658                 u = Lexer::convertUnicode(c[2], c[3], c[4], c[5]);
    659                 c = &u;
    660                 k += 5;
    661             }
    662         } else if (c[0] == '%' && k <= len - 3 && Lexer::isHexDigit(c[1]) && Lexer::isHexDigit(c[2])) {
    663             u = UChar(Lexer::convertHex(c[1], c[2]));
    664             c = &u;
    665             k += 2;
    666         }
    667         k++;
    668         s.append(*c);
    669     }
    670 
    671     return jsString(exec, s);
    672 }
    673 
    674 #ifndef NDEBUG
    675 JSValue* globalFuncKJSPrint(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
    676 {
    677     CStringBuffer string;
    678     args[0]->toString(exec).getCString(string);
    679     puts(string.data());
    680     return jsUndefined();
    681 }
    682 #endif
    683 
    684 // ------------------------------ PrototypeFunction -------------------------------
    68533
    68634PrototypeFunction::PrototypeFunction(ExecState* exec, int len, const Identifier& name, NativeFunction function)
     
    70654}
    70755
    708 // ------------------------------ PrototypeReflexiveFunction -------------------------------
    709 
    710 GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, NativeFunction function, JSGlobalObject* cachedGlobalObject)
    711     : PrototypeFunction(exec, functionPrototype, len, name, function)
    712     , m_cachedGlobalObject(cachedGlobalObject)
    713 {
    714     ASSERT_ARG(cachedGlobalObject, cachedGlobalObject);
    715 }
    716 
    717 void GlobalEvalFunction::mark()
    718 {
    719     PrototypeFunction::mark();
    720     if (!m_cachedGlobalObject->marked())
    721         m_cachedGlobalObject->mark();
    722 }
    723 
    72456} // namespace KJS
  • trunk/JavaScriptCore/kjs/PrototypeFunction.h

    r35006 r35016  
    2222 */
    2323
    24 #ifndef JSFunction_h
    25 #define JSFunction_h
     24#ifndef PrototypeFunction_h
     25#define PrototypeFunction_h
    2626
    2727#include "InternalFunction.h"
    28 #include "JSVariableObject.h"
    29 #include "SymbolTable.h"
    30 #include "nodes.h"
    31 #include "JSObject.h"
     28#include "CallData.h"
    3229
    3330namespace KJS {
    34 
    35   class FunctionBodyNode;
    36   class FunctionPrototype;
    37   class JSActivation;
    38   class JSGlobalObject;
    39 
    40   class JSFunction : public InternalFunction {
    41   public:
    42     JSFunction(ExecState*, const Identifier&, FunctionBodyNode*, ScopeChainNode*);
    43 
    44     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    45     virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
    46     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    47 
    48     JSObject* construct(ExecState*, const ArgList&);
    49     JSValue* call(ExecState*, JSValue* thisValue, const ArgList&);
    50 
    51     // Note: Returns a null identifier for any parameters that will never get set
    52     // due to a later parameter with the same name.
    53     const Identifier& getParameterName(int index);
    54 
    55     static const ClassInfo info;
    56 
    57     RefPtr<FunctionBodyNode> body;
    58 
    59     void setScope(const ScopeChain& s) { _scope = s; }
    60     ScopeChain& scope() { return _scope; }
    61 
    62     virtual void mark();
    63 
    64   private:
    65     virtual const ClassInfo* classInfo() const { return &info; }
    66     virtual ConstructType getConstructData(ConstructData&);
    67     virtual CallType getCallData(CallData&);
    68 
    69     ScopeChain _scope;
    70 
    71     static JSValue* argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
    72     static JSValue* callerGetter(ExecState*, const Identifier&, const PropertySlot&);
    73     static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
    74   };
    75 
    76   class IndexToNameMap {
    77   public:
    78     IndexToNameMap(JSFunction*, const ArgList&);
    79     ~IndexToNameMap();
    80    
    81     Identifier& operator[](const Identifier& index);
    82     bool isMapped(const Identifier& index) const;
    83     void unMap(ExecState* exec, const Identifier& index);
    84    
    85   private:
    86     unsigned size;
    87     Identifier* _map;
    88   };
    89  
    90   class Arguments : public JSObject {
    91   public:
    92     Arguments(ExecState*, JSFunction* func, const ArgList& args, JSActivation* act);
    93     virtual void mark();
    94     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    95     virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
    96     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    97     virtual const ClassInfo* classInfo() const { return &info; }
    98     static const ClassInfo info;
    99   private:
    100     static JSValue* mappedIndexGetter(ExecState*, const Identifier&, const PropertySlot& slot);
    101 
    102     JSActivation* _activationObject;
    103     mutable IndexToNameMap indexToNameMap;
    104   };
    10531
    10632  class PrototypeFunction : public InternalFunction {
     
    11541  };
    11642
    117     class GlobalEvalFunction : public PrototypeFunction {
    118     public:
    119         GlobalEvalFunction(ExecState*, FunctionPrototype*, int len, const Identifier&, NativeFunction, JSGlobalObject* expectedThisObject);
    120         JSGlobalObject* cachedGlobalObject() const { return m_cachedGlobalObject; }
     43} // namespace KJS
    12144
    122     private:
    123         virtual void mark();
    124 
    125         JSGlobalObject* m_cachedGlobalObject;
    126     };
    127 
    128     // Global Functions
    129     JSValue* globalFuncEval(ExecState*, JSObject*, JSValue*, const ArgList&);
    130     JSValue* globalFuncParseInt(ExecState*, JSObject*, JSValue*, const ArgList&);
    131     JSValue* globalFuncParseFloat(ExecState*, JSObject*, JSValue*, const ArgList&);
    132     JSValue* globalFuncIsNaN(ExecState*, JSObject*, JSValue*, const ArgList&);
    133     JSValue* globalFuncIsFinite(ExecState*, JSObject*, JSValue*, const ArgList&);
    134     JSValue* globalFuncDecodeURI(ExecState*, JSObject*, JSValue*, const ArgList&);
    135     JSValue* globalFuncDecodeURIComponent(ExecState*, JSObject*, JSValue*, const ArgList&);
    136     JSValue* globalFuncEncodeURI(ExecState*, JSObject*, JSValue*, const ArgList&);
    137     JSValue* globalFuncEncodeURIComponent(ExecState*, JSObject*, JSValue*, const ArgList&);
    138     JSValue* globalFuncEscape(ExecState*, JSObject*, JSValue*, const ArgList&);
    139     JSValue* globalFuncUnescape(ExecState*, JSObject*, JSValue*, const ArgList&);
    140 #ifndef NDEBUG
    141     JSValue* globalFuncKJSPrint(ExecState*, JSObject*, JSValue*, const ArgList&);
    142 #endif
    143 
    144     static const double mantissaOverflowLowerBound = 9007199254740992.0;
    145     double parseIntOverflow(const char*, int length, int radix);
    146 
    147 } // namespace
    148 
    149 #endif
     45#endif // PrototypeFunction_h
  • trunk/JavaScriptCore/kjs/Shell.cpp

    r34947 r35016  
    3434#include "JSObject.h"
    3535#include "Parser.h"
     36#include "PrototypeFunction.h"
    3637#include "collector.h"
    3738#include "completion.h"
  • trunk/JavaScriptCore/kjs/lexer.cpp

    r34607 r35016  
    2828#include "nodes.h"
    2929#include "NodeInfo.h"
     30#include "JSGlobalObjectFunctions.h"
    3031#include <ctype.h>
    3132#include <limits.h>
  • trunk/JavaScriptCore/kjs/ustring.cpp

    r34947 r35016  
    2525#include "ustring.h"
    2626
     27#include "JSGlobalObjectFunctions.h"
    2728#include "collector.h"
    2829#include "dtoa.h"
    29 #include "JSFunction.h"
    3030#include "identifier.h"
    3131#include "operations.h"
     
    3636#include <stdio.h>
    3737#include <stdlib.h>
     38#include <wtf/ASCIICType.h>
    3839#include <wtf/Assertions.h>
    39 #include <wtf/ASCIICType.h>
    4040#include <wtf/MathExtras.h>
    4141#include <wtf/Vector.h>
Note: See TracChangeset for help on using the changeset viewer.