webengine/osswebengine/JavaScriptCore/kjs/internal.cpp
changeset 0 dd21522fd290
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2  *  This file is part of the KDE libraries
       
     3  *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
       
     4  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
       
     5  *  Copyright (C) 2004 Apple Computer, Inc.
       
     6  *
       
     7  *  This library is free software; you can redistribute it and/or
       
     8  *  modify it under the terms of the GNU Library General Public
       
     9  *  License as published by the Free Software Foundation; either
       
    10  *  version 2 of the License, or (at your option) any later version.
       
    11  *
       
    12  *  This library is distributed in the hope that it will be useful,
       
    13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    15  *  Library General Public License for more details.
       
    16  *
       
    17  *  You should have received a copy of the GNU Library General Public License
       
    18  *  along with this library; see the file COPYING.LIB.  If not, write to
       
    19  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
    20  *  Boston, MA 02110-1301, USA.
       
    21  *
       
    22  */
       
    23 
       
    24 #include "config.h"
       
    25 #include "internal.h"
       
    26 
       
    27 #include "array_object.h"
       
    28 #include "bool_object.h"
       
    29 #include "collector.h"
       
    30 #include "context.h"
       
    31 #include "date_object.h"
       
    32 #include "debugger.h"
       
    33 #include "error_object.h"
       
    34 #include "function_object.h"
       
    35 #include "lexer.h"
       
    36 #include "math_object.h"
       
    37 #include "nodes.h"
       
    38 #include "number_object.h"
       
    39 #include "object.h"
       
    40 #include "object_object.h"
       
    41 #include "operations.h"
       
    42 #include "regexp_object.h"
       
    43 #include "string_object.h"
       
    44 #include <assert.h>
       
    45 #include <wtf/HashMap.h>
       
    46 #include <wtf/HashSet.h>
       
    47 #include <wtf/Vector.h>
       
    48 #include <math.h>
       
    49 #include <stdio.h>
       
    50 
       
    51 namespace KJS {
       
    52 
       
    53 #if PLATFORM(WIN_OS)
       
    54 #define copysign _copysign
       
    55 #endif
       
    56 
       
    57 // ------------------------------ StringImp ------------------------------------
       
    58 
       
    59 JSValue *StringImp::toPrimitive(ExecState *, JSType) const
       
    60 {
       
    61   return const_cast<StringImp *>(this);
       
    62 }
       
    63 
       
    64 bool StringImp::toBoolean(ExecState *) const
       
    65 {
       
    66   return (val.size() > 0);
       
    67 }
       
    68 
       
    69 double StringImp::toNumber(ExecState *) const
       
    70 {
       
    71   return val.toDouble();
       
    72 }
       
    73 
       
    74 UString StringImp::toString(ExecState *) const
       
    75 {
       
    76   return val;
       
    77 }
       
    78 
       
    79 JSObject* StringImp::toObject(ExecState *exec) const
       
    80 {
       
    81     return new StringInstance(exec->lexicalInterpreter()->builtinStringPrototype(), const_cast<StringImp*>(this));
       
    82 }
       
    83 
       
    84 // ------------------------------ NumberImp ------------------------------------
       
    85 
       
    86 JSValue *NumberImp::toPrimitive(ExecState *, JSType) const
       
    87 {
       
    88   return const_cast<NumberImp *>(this);
       
    89 }
       
    90 
       
    91 bool NumberImp::toBoolean(ExecState *) const
       
    92 {
       
    93   return val < 0.0 || val > 0.0; // false for NaN
       
    94 }
       
    95 
       
    96 double NumberImp::toNumber(ExecState *) const
       
    97 {
       
    98   return val;
       
    99 }
       
   100 
       
   101 UString NumberImp::toString(ExecState *) const
       
   102 {
       
   103   if (val == 0.0) // +0.0 or -0.0
       
   104     return "0";
       
   105   return UString::from(val);
       
   106 }
       
   107 
       
   108 JSObject *NumberImp::toObject(ExecState *exec) const
       
   109 {
       
   110   List args;
       
   111   args.append(const_cast<NumberImp*>(this));
       
   112   return static_cast<JSObject *>(exec->lexicalInterpreter()->builtinNumber()->construct(exec,args));
       
   113 }
       
   114 
       
   115 // FIXME: We can optimize this to work like JSValue::getUInt32. I'm ignoring it for now
       
   116 // because it never shows up on profiles.
       
   117 bool NumberImp::getUInt32(uint32_t& uint32) const
       
   118 {
       
   119   uint32 = (uint32_t)val;
       
   120   return (double)uint32 == val;
       
   121 }
       
   122 
       
   123 // --------------------------- GetterSetterImp ---------------------------------
       
   124 void GetterSetterImp::mark()
       
   125 {
       
   126     JSCell::mark();
       
   127 
       
   128     if (getter && !getter->marked())
       
   129         getter->mark();
       
   130     if (setter && !setter->marked())
       
   131         setter->mark();
       
   132 }
       
   133 
       
   134 JSValue *GetterSetterImp::toPrimitive(ExecState*, JSType) const
       
   135 {
       
   136     assert(false);
       
   137     return jsNull();
       
   138 }
       
   139 
       
   140 bool GetterSetterImp::toBoolean(ExecState*) const
       
   141 {
       
   142     assert(false);
       
   143     return false;
       
   144 }
       
   145 
       
   146 double GetterSetterImp::toNumber(ExecState *) const
       
   147 {
       
   148     assert(false);
       
   149     return 0.0;
       
   150 }
       
   151 
       
   152 UString GetterSetterImp::toString(ExecState *) const
       
   153 {
       
   154     assert(false);
       
   155     return UString::null();
       
   156 }
       
   157 
       
   158 JSObject *GetterSetterImp::toObject(ExecState *exec) const
       
   159 {
       
   160     assert(false);
       
   161     return jsNull()->toObject(exec);
       
   162 }
       
   163 
       
   164 // ------------------------------ LabelStack -----------------------------------
       
   165 
       
   166 bool LabelStack::push(const Identifier &id)
       
   167 {
       
   168   if (contains(id))
       
   169     return false;
       
   170 
       
   171   StackElem *newtos = new StackElem;
       
   172   newtos->id = id;
       
   173   newtos->prev = tos;
       
   174   tos = newtos;
       
   175   return true;
       
   176 }
       
   177 
       
   178 bool LabelStack::contains(const Identifier &id) const
       
   179 {
       
   180   if (id.isEmpty())
       
   181     return true;
       
   182 
       
   183   for (StackElem *curr = tos; curr; curr = curr->prev)
       
   184     if (curr->id == id)
       
   185       return true;
       
   186 
       
   187   return false;
       
   188 }
       
   189 
       
   190 // ------------------------------ InternalFunctionImp --------------------------
       
   191 
       
   192 const ClassInfo InternalFunctionImp::info = {"Function", 0, 0, 0};
       
   193 
       
   194 InternalFunctionImp::InternalFunctionImp()
       
   195 {
       
   196 }
       
   197 
       
   198 EXPORT
       
   199 InternalFunctionImp::InternalFunctionImp(FunctionPrototype* funcProto, const Identifier& name)
       
   200   : JSObject(funcProto)
       
   201   , m_name(name)
       
   202 {
       
   203 }
       
   204 
       
   205 EXPORT
       
   206 bool InternalFunctionImp::implementsCall() const
       
   207 {
       
   208   return true;
       
   209 }
       
   210 
       
   211 EXPORT
       
   212 bool InternalFunctionImp::implementsHasInstance() const
       
   213 {
       
   214   return true;
       
   215 }
       
   216 
       
   217 #if PLATFORM(SYMBIAN)
       
   218 EXPORT const ClassInfo* InternalFunctionImp::classInfo() const
       
   219 {
       
   220     return &info;
       
   221 }
       
   222 #endif
       
   223 
       
   224 
       
   225 // ------------------------------ global functions -----------------------------
       
   226 EXPORT
       
   227 double roundValue(ExecState *exec, JSValue *v)
       
   228 {
       
   229   double d = v->toNumber(exec);
       
   230   double ad = fabs(d);
       
   231   if (ad == 0 || isNaN(d) || isInf(d))
       
   232     return d;
       
   233   return copysign(floor(ad), d);
       
   234 }
       
   235 
       
   236 #ifndef NDEBUG
       
   237 #include <stdio.h>
       
   238 void printInfo(ExecState *exec, const char *s, JSValue *o, int lineno)
       
   239 {
       
   240   if (!o)
       
   241     fprintf(stderr, "KJS: %s: (null)", s);
       
   242   else {
       
   243     JSValue *v = o;
       
   244 
       
   245     UString name;
       
   246     switch (v->type()) {
       
   247     case UnspecifiedType:
       
   248       name = "Unspecified";
       
   249       break;
       
   250     case UndefinedType:
       
   251       name = "Undefined";
       
   252       break;
       
   253     case NullType:
       
   254       name = "Null";
       
   255       break;
       
   256     case BooleanType:
       
   257       name = "Boolean";
       
   258       break;
       
   259     case StringType:
       
   260       name = "String";
       
   261       break;
       
   262     case NumberType:
       
   263       name = "Number";
       
   264       break;
       
   265     case ObjectType:
       
   266       name = static_cast<JSObject *>(v)->className();
       
   267       if (name.isNull())
       
   268         name = "(unknown class)";
       
   269       break;
       
   270     case GetterSetterType:
       
   271       name = "GetterSetter";
       
   272       break;
       
   273     }
       
   274     UString vString = v->toString(exec);
       
   275     if ( vString.size() > 50 )
       
   276       vString = vString.substr( 0, 50 ) + "...";
       
   277     // Can't use two UString::ascii() in the same fprintf call
       
   278     CString tempString( vString.cstring() );
       
   279 
       
   280     fprintf(stderr, "KJS: %s: %s : %s (%p)",
       
   281             s, tempString.c_str(), name.ascii(), (void*)v);
       
   282 
       
   283     if (lineno >= 0)
       
   284       fprintf(stderr, ", line %d\n",lineno);
       
   285     else
       
   286       fprintf(stderr, "\n");
       
   287   }
       
   288 }
       
   289 #endif
       
   290 
       
   291 }