~ubuntu-branches/ubuntu/maverick/webkit/maverick

« back to all changes in this revision

Viewing changes to JavaScriptCore/kjs/math_object.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mike Hommey
  • Date: 2007-08-19 15:54:12 UTC
  • Revision ID: james.westby@ubuntu.com-20070819155412-uxxg1h9plpghmtbi
Tags: upstream-0~svn25144
ImportĀ upstreamĀ versionĀ 0~svn25144

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- c-basic-offset: 2 -*-
 
2
/*
 
3
 *  This file is part of the KDE libraries
 
4
 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
 
5
 *
 
6
 *  This library is free software; you can redistribute it and/or
 
7
 *  modify it under the terms of the GNU Lesser General Public
 
8
 *  License as published by the Free Software Foundation; either
 
9
 *  version 2 of the License, or (at your option) any later version.
 
10
 *
 
11
 *  This library is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 *  Lesser General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU Lesser General Public
 
17
 *  License along with this library; if not, write to the Free Software
 
18
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
19
 *
 
20
 */
 
21
 
 
22
#include "config.h"
 
23
#include "math_object.h"
 
24
#include "math_object.lut.h"
 
25
#include "wtf/MathExtras.h"
 
26
 
 
27
#include "operations.h"
 
28
#include <math.h>
 
29
#include <time.h>
 
30
 
 
31
using namespace KJS;
 
32
 
 
33
// ------------------------------ MathObjectImp --------------------------------
 
34
 
 
35
const ClassInfo MathObjectImp::info = { "Math", 0, &mathTable, 0 };
 
36
 
 
37
/* Source for math_object.lut.h
 
38
@begin mathTable 21
 
39
  E             MathObjectImp::Euler    DontEnum|DontDelete|ReadOnly
 
40
  LN2           MathObjectImp::Ln2      DontEnum|DontDelete|ReadOnly
 
41
  LN10          MathObjectImp::Ln10     DontEnum|DontDelete|ReadOnly
 
42
  LOG2E         MathObjectImp::Log2E    DontEnum|DontDelete|ReadOnly
 
43
  LOG10E        MathObjectImp::Log10E   DontEnum|DontDelete|ReadOnly
 
44
  PI            MathObjectImp::Pi       DontEnum|DontDelete|ReadOnly
 
45
  SQRT1_2       MathObjectImp::Sqrt1_2  DontEnum|DontDelete|ReadOnly
 
46
  SQRT2         MathObjectImp::Sqrt2    DontEnum|DontDelete|ReadOnly
 
47
  abs           MathObjectImp::Abs      DontEnum|Function 1
 
48
  acos          MathObjectImp::ACos     DontEnum|Function 1
 
49
  asin          MathObjectImp::ASin     DontEnum|Function 1
 
50
  atan          MathObjectImp::ATan     DontEnum|Function 1
 
51
  atan2         MathObjectImp::ATan2    DontEnum|Function 2
 
52
  ceil          MathObjectImp::Ceil     DontEnum|Function 1
 
53
  cos           MathObjectImp::Cos      DontEnum|Function 1
 
54
  exp           MathObjectImp::Exp      DontEnum|Function 1
 
55
  floor         MathObjectImp::Floor    DontEnum|Function 1
 
56
  log           MathObjectImp::Log      DontEnum|Function 1
 
57
  max           MathObjectImp::Max      DontEnum|Function 2
 
58
  min           MathObjectImp::Min      DontEnum|Function 2
 
59
  pow           MathObjectImp::Pow      DontEnum|Function 2
 
60
  random        MathObjectImp::Random   DontEnum|Function 0
 
61
  round         MathObjectImp::Round    DontEnum|Function 1
 
62
  sin           MathObjectImp::Sin      DontEnum|Function 1
 
63
  sqrt          MathObjectImp::Sqrt     DontEnum|Function 1
 
64
  tan           MathObjectImp::Tan      DontEnum|Function 1
 
65
@end
 
66
*/
 
67
 
 
68
MathObjectImp::MathObjectImp(ExecState * /*exec*/,
 
69
                             ObjectPrototype *objProto)
 
70
  : JSObject(objProto)
 
71
{
 
72
}
 
73
 
 
74
// ECMA 15.8
 
75
 
 
76
bool MathObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot &slot)
 
77
{
 
78
  return getStaticPropertySlot<MathFuncImp, MathObjectImp, JSObject>(exec, &mathTable, this, propertyName, slot);
 
79
}
 
80
 
 
81
JSValue *MathObjectImp::getValueProperty(ExecState *, int token) const
 
82
{
 
83
  double d = -42; // ;)
 
84
  switch (token) {
 
85
  case Euler:
 
86
    d = exp(1.0);
 
87
    break;
 
88
  case Ln2:
 
89
    d = log(2.0);
 
90
    break;
 
91
  case Ln10:
 
92
    d = log(10.0);
 
93
    break;
 
94
  case Log2E:
 
95
    d = 1.0/log(2.0);
 
96
    break;
 
97
  case Log10E:
 
98
    d = 1.0/log(10.0);
 
99
    break;
 
100
  case Pi:
 
101
    d = piDouble;
 
102
    break;
 
103
  case Sqrt1_2:
 
104
    d = sqrt(0.5);
 
105
    break;
 
106
  case Sqrt2:
 
107
    d = sqrt(2.0);
 
108
    break;
 
109
  default:
 
110
    assert(0);
 
111
  }
 
112
 
 
113
  return jsNumber(d);
 
114
}
 
115
 
 
116
// ------------------------------ MathObjectImp --------------------------------
 
117
 
 
118
static bool randomSeeded = false;
 
119
 
 
120
MathFuncImp::MathFuncImp(ExecState* exec, int i, int l, const Identifier& name)
 
121
  : InternalFunctionImp(static_cast<FunctionPrototype*>(exec->lexicalInterpreter()->builtinFunctionPrototype()), name)
 
122
  , id(i)
 
123
{
 
124
  putDirect(exec->propertyNames().length, l, DontDelete|ReadOnly|DontEnum);
 
125
}
 
126
 
 
127
JSValue *MathFuncImp::callAsFunction(ExecState *exec, JSObject* /*thisObj*/, const List &args)
 
128
{
 
129
  double arg = args[0]->toNumber(exec);
 
130
  double arg2 = args[1]->toNumber(exec);
 
131
  double result;
 
132
 
 
133
  switch (id) {
 
134
  case MathObjectImp::Abs:
 
135
    result = ( arg < 0 || arg == -0) ? (-arg) : arg;
 
136
    break;
 
137
  case MathObjectImp::ACos:
 
138
    result = acos(arg);
 
139
    break;
 
140
  case MathObjectImp::ASin:
 
141
    result = asin(arg);
 
142
    break;
 
143
  case MathObjectImp::ATan:
 
144
    result = atan(arg);
 
145
    break;
 
146
  case MathObjectImp::ATan2:
 
147
    result = atan2(arg, arg2);
 
148
    break;
 
149
  case MathObjectImp::Ceil:
 
150
    result = ceil(arg);
 
151
    break;
 
152
  case MathObjectImp::Cos:
 
153
    result = cos(arg);
 
154
    break;
 
155
  case MathObjectImp::Exp:
 
156
    result = exp(arg);
 
157
    break;
 
158
  case MathObjectImp::Floor:
 
159
    result = floor(arg);
 
160
    break;
 
161
  case MathObjectImp::Log:
 
162
    result = log(arg);
 
163
    break;
 
164
  case MathObjectImp::Max: {
 
165
    unsigned int argsCount = args.size();
 
166
    result = -Inf;
 
167
    for ( unsigned int k = 0 ; k < argsCount ; ++k ) {
 
168
      double val = args[k]->toNumber(exec);
 
169
      if ( isNaN( val ) )
 
170
      {
 
171
        result = NaN;
 
172
        break;
 
173
      }
 
174
      if ( val > result || (val == 0 && result == 0 && !signbit(val)) )
 
175
        result = val;
 
176
    }
 
177
    break;
 
178
  }
 
179
  case MathObjectImp::Min: {
 
180
    unsigned int argsCount = args.size();
 
181
    result = +Inf;
 
182
    for ( unsigned int k = 0 ; k < argsCount ; ++k ) {
 
183
      double val = args[k]->toNumber(exec);
 
184
      if ( isNaN( val ) )
 
185
      {
 
186
        result = NaN;
 
187
        break;
 
188
      }
 
189
      if ( val < result || (val == 0 && result == 0 && signbit(val)) )
 
190
        result = val;
 
191
    }
 
192
    break;
 
193
  }
 
194
  case MathObjectImp::Pow:
 
195
    // ECMA 15.8.2.1.13 (::pow takes care of most of the critera)
 
196
    if (isNaN(arg2))
 
197
      result = NaN;
 
198
    else if (isNaN(arg) && arg2 != 0)
 
199
      result = NaN;
 
200
    else if (fabs(arg) == 1 && isInf(arg2))
 
201
      result = NaN;
 
202
    else if (arg2 == 0 && arg != 0)
 
203
      result = 1;
 
204
    else
 
205
      result = ::pow(arg, arg2);
 
206
    break;
 
207
  case MathObjectImp::Random:
 
208
      if (!randomSeeded) {
 
209
          srand(static_cast<unsigned>(time(0)));
 
210
          randomSeeded = true;
 
211
      }
 
212
      result = (double)rand() / RAND_MAX;
 
213
      break;
 
214
  case MathObjectImp::Round:
 
215
    if (signbit(arg) && arg >= -0.5)
 
216
        result = -0.0;
 
217
    else
 
218
        result = floor(arg + 0.5);
 
219
    break;
 
220
  case MathObjectImp::Sin:
 
221
    result = sin(arg);
 
222
    break;
 
223
  case MathObjectImp::Sqrt:
 
224
    result = sqrt(arg);
 
225
    break;
 
226
  case MathObjectImp::Tan:
 
227
    result = tan(arg);
 
228
    break;
 
229
 
 
230
  default:
 
231
    result = 0.0;
 
232
    assert(0);
 
233
  }
 
234
 
 
235
  return jsNumber(result);
 
236
}