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:
File:
1 copied

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.