Ignore:
Timestamp:
Mar 21, 2002, 4:31:57 PM (23 years ago)
Author:
mjs
Message:

Merged changes from LABYRINTH_KDE_3_MERGE branch.

File:
1 edited

Legend:

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

    r6 r798  
     1// -*- c-basic-offset: 2 -*-
    12/*
    23 *  This file is part of the KDE libraries
     
    1617 *  License along with this library; if not, write to the Free Software
    1718 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     19 *
     20 *  $Id$
    1821 */
    1922
    2023#include <math.h>
    2124#include <stdlib.h>
    22 
    23 #include "kjs.h"
     25#include <stdio.h>
     26#include <assert.h>
     27
     28#include "value.h"
     29#include "object.h"
    2430#include "types.h"
     31#include "interpreter.h"
    2532#include "operations.h"
    2633#include "math_object.h"
    27 #include "lookup.h"
    2834
    2935#include "math_object.lut.h"
     
    3137using namespace KJS;
    3238
    33 KJSO Math::get(const UString &p) const
    34 {
    35   int token = Lookup::find(&mathTable, p);
    36 
    37   if (token < 0)
    38     return Imp::get(p);
    39 
    40   double d;
    41   int len = 1;
     39// ------------------------------ MathObjectImp --------------------------------
     40
     41const ClassInfo MathObjectImp::info = { "Math", 0, &mathTable, 0 };
     42
     43/* Source for math_object.lut.h
     44@begin mathTable 21
     45  E             MathObjectImp::Euler    DontEnum
     46  LN2           MathObjectImp::Ln2      DontEnum
     47  LN10          MathObjectImp::Ln10     DontEnum
     48  LOG2E         MathObjectImp::Log2E    DontEnum
     49  LOG10E        MathObjectImp::Log10E   DontEnum
     50  PI            MathObjectImp::Pi       DontEnum
     51  SQRT1_2       MathObjectImp::Sqrt1_2  DontEnum
     52  SQRT2         MathObjectImp::Sqrt2    DontEnum
     53  abs           MathObjectImp::Abs      DontEnum|Function 1
     54  acos          MathObjectImp::ACos     DontEnum|Function 1
     55  asin          MathObjectImp::ASin     DontEnum|Function 1
     56  atan          MathObjectImp::ATan     DontEnum|Function 1
     57  atan2         MathObjectImp::ATan2    DontEnum|Function 2
     58  ceil          MathObjectImp::Ceil     DontEnum|Function 1
     59  cos           MathObjectImp::Cos      DontEnum|Function 1
     60  exp           MathObjectImp::Exp      DontEnum|Function 1
     61  floor         MathObjectImp::Floor    DontEnum|Function 1
     62  log           MathObjectImp::Log      DontEnum|Function 1
     63  max           MathObjectImp::Max      DontEnum|Function 2
     64  min           MathObjectImp::Min      DontEnum|Function 2
     65  pow           MathObjectImp::Pow      DontEnum|Function 2
     66  random        MathObjectImp::Random   DontEnum|Function 0
     67  round         MathObjectImp::Round    DontEnum|Function 1
     68  sin           MathObjectImp::Sin      DontEnum|Function 1
     69  sqrt          MathObjectImp::Sqrt     DontEnum|Function 1
     70  tan           MathObjectImp::Tan      DontEnum|Function 1
     71@end
     72*/
     73
     74MathObjectImp::MathObjectImp(ExecState * /*exec*/,
     75                             ObjectPrototypeImp *objProto)
     76  : ObjectImp(Object(objProto))
     77{
     78}
     79
     80// ECMA 15.8
     81Value MathObjectImp::get(ExecState *exec, const UString &propertyName) const
     82{
     83  return lookupGet<MathFuncImp, MathObjectImp, ObjectImp>( exec, propertyName, &mathTable, this );
     84}
     85
     86Value MathObjectImp::getValueProperty(ExecState *, int token) const
     87{
     88  double d = -42; // ;)
    4289  switch (token) {
    43   case Math::Euler:
     90  case Euler:
    4491    d = exp(1.0);
    4592    break;
    46   case Math::Ln2:
     93  case Ln2:
    4794    d = log(2.0);
    4895    break;
    49   case Math::Ln10:
     96  case Ln10:
    5097    d = log(10.0);
    5198    break;
    52   case Math::Log2E:
     99  case Log2E:
    53100    d = 1.0/log(2.0);
    54101    break;
    55   case Math::Log10E:
     102  case Log10E:
    56103    d = 1.0/log(10.0);
    57104    break;
    58   case Math::Pi:
     105  case Pi:
    59106    d = 2.0 * asin(1.0);
    60107    break;
    61   case Math::Sqrt1_2:
     108  case Sqrt1_2:
    62109    d = sqrt(0.5);
    63110    break;
    64   case Math::Sqrt2:
     111  case Sqrt2:
    65112    d = sqrt(2.0);
    66113    break;
    67114  default:
    68     if (token == Math::Min || token == Math::Max || token == Math::Pow)
    69       len = 2;
    70     return Function(new MathFunc(token, len));
    71   };
     115    fprintf( stderr, "Internal error in MathObjectImp: unhandled token %d\n", token );
     116    break;
     117  }
    72118
    73119  return Number(d);
    74120}
    75121
    76 bool Math::hasProperty(const UString &p, bool recursive) const
    77 {
    78   return (Lookup::find(&mathTable, p) >= 0 ||
    79           (recursive && Imp::hasProperty(p, recursive)));
    80 }
    81 
    82 Completion MathFunc::execute(const List &args)
    83 {
    84   KJSO v = args[0];
    85   Number n = v.toNumber();
     122// ------------------------------ MathObjectImp --------------------------------
     123
     124MathFuncImp::MathFuncImp(ExecState *exec, int i, int l)
     125  : InternalFunctionImp(
     126    static_cast<FunctionPrototypeImp*>(exec->interpreter()->builtinFunctionPrototype().imp())
     127    ), id(i)
     128{
     129  Value protect(this);
     130  put(exec,"length",Number(l),DontDelete|ReadOnly|DontEnum);
     131}
     132
     133bool MathFuncImp::implementsCall() const
     134{
     135  return true;
     136}
     137
     138Value MathFuncImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
     139{
     140  Value v = args[0];
     141  Number n = v.toNumber(exec);
    86142  double arg = n.value();
    87143
    88   KJSO v2 = args[1];
    89   Number n2 = v2.toNumber();
     144  Value v2 = args[1];
     145  Number n2 = v2.toNumber(exec);
    90146  double arg2 = n2.value();
    91147  double result;
    92148
    93149  switch (id) {
    94   case Math::Abs:
    95     result = ( arg < 0 ) ? (-arg) : arg;
    96     break;
    97   case Math::ACos:
     150  case MathObjectImp::Abs:
     151    result = ( arg < 0 || arg == -0) ? (-arg) : arg;
     152    break;
     153  case MathObjectImp::ACos:
    98154    result = ::acos(arg);
    99155    break;
    100   case Math::ASin:
     156  case MathObjectImp::ASin:
    101157    result = ::asin(arg);
    102158    break;
    103   case Math::ATan:
     159  case MathObjectImp::ATan:
    104160    result = ::atan(arg);
    105161    break;
    106   case Math::ATan2:
     162  case MathObjectImp::ATan2:
    107163    result = ::atan2(arg, arg2);
    108164    break;
    109   case Math::Ceil:
     165  case MathObjectImp::Ceil:
    110166    result = ::ceil(arg);
    111167    break;
    112   case Math::Cos:
     168  case MathObjectImp::Cos:
    113169    result = ::cos(arg);
    114170    break;
    115   case Math::Exp:
     171  case MathObjectImp::Exp:
    116172    result = ::exp(arg);
    117173    break;
    118   case Math::Floor:
     174  case MathObjectImp::Floor:
    119175    result = ::floor(arg);
    120176    break;
    121   case Math::Log:
     177  case MathObjectImp::Log:
    122178    result = ::log(arg);
    123179    break;
    124   case Math::Max:
    125     result = ( arg > arg2 ) ? arg : arg2;
    126     break;
    127   case Math::Min:
    128     result = ( arg < arg2 ) ? arg : arg2;
    129     break;
    130   case Math::Pow:
    131     result = ::pow(arg, arg2);
    132     break;
    133   case Math::Random:
     180  case MathObjectImp::Max: {
     181    unsigned int argsCount = args.size();
     182    result = -Inf;
     183    for ( unsigned int k = 0 ; k < argsCount ; ++k ) {
     184      double val = args[k].toNumber(exec);
     185      if ( isNaN( val ) )
     186      {
     187        result = NaN;
     188        break;
     189      }
     190      if ( val > result )
     191        result = val;
     192    }
     193    break;
     194  }
     195  case MathObjectImp::Min: {
     196    unsigned int argsCount = args.size();
     197    result = +Inf;
     198    for ( unsigned int k = 0 ; k < argsCount ; ++k ) {
     199      double val = args[k].toNumber(exec);
     200      if ( isNaN( val ) )
     201      {
     202        result = NaN;
     203        break;
     204      }
     205      if ( val < result )
     206        result = val;
     207    }
     208    break;
     209  }
     210  case MathObjectImp::Pow:
     211    // ECMA 15.8.2.1.13 (::pow takes care of most of the critera)
     212    if (KJS::isNaN(arg2))
     213      result = NaN;
     214    else if (arg2 == 0)
     215      result = 1;
     216    else if (KJS::isNaN(arg) && arg2 != 0)
     217      result = NaN;
     218    else if (::fabs(arg) > 1 && KJS::isPosInf(arg2))
     219      result = Inf;
     220    else if (::fabs(arg) > 1 && KJS::isNegInf(arg2))
     221      result = +0;
     222    else if (::fabs(arg) == 1 && KJS::isPosInf(arg2))
     223      result = NaN;
     224    else if (::fabs(arg) == 1 && KJS::isNegInf(arg2))
     225      result = NaN;
     226    else if (::fabs(arg) < 1 && KJS::isPosInf(arg2))
     227      result = +0;
     228    else if (::fabs(arg) < 1 && KJS::isNegInf(arg2))
     229      result = Inf;
     230    else
     231      result = ::pow(arg, arg2);
     232    break;
     233  case MathObjectImp::Random:
    134234    result = ::rand();
    135235    result = result / RAND_MAX;
    136236    break;
    137   case Math::Round:
     237  case MathObjectImp::Round:
    138238    if (isNaN(arg))
    139239      result = arg;
     
    145245      result = (double)(arg >= 0.0 ? int(arg + 0.5) : int(arg - 0.5));
    146246    break;
    147   case Math::Sin:
     247  case MathObjectImp::Sin:
    148248    result = ::sin(arg);
    149249    break;
    150   case Math::Sqrt:
     250  case MathObjectImp::Sqrt:
    151251    result = ::sqrt(arg);
    152252    break;
    153   case Math::Tan:
     253  case MathObjectImp::Tan:
    154254    result = ::tan(arg);
    155255    break;
     
    160260  }
    161261
    162   return Completion(ReturnValue, Number(result));
    163 }
     262  return Number(result);
     263}
Note: See TracChangeset for help on using the changeset viewer.