/ runtime / MathObject.cpp
MathObject.cpp
  1  /*
  2   *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  3   *  Copyright (C) 2007-2019 Apple Inc. All Rights Reserved.
  4   *
  5   *  This library is free software; you can redistribute it and/or
  6   *  modify it under the terms of the GNU Lesser General Public
  7   *  License as published by the Free Software Foundation; either
  8   *  version 2 of the License, or (at your option) any later version.
  9   *
 10   *  This library is distributed in the hope that it will be useful,
 11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13   *  Lesser General Public License for more details.
 14   *
 15   *  You should have received a copy of the GNU Lesser General Public
 16   *  License along with this library; if not, write to the Free Software
 17   *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 18   *
 19   */
 20  
 21  #include "config.h"
 22  #include "MathObject.h"
 23  
 24  #include "JSCInlines.h"
 25  #include "MathCommon.h"
 26  #include <wtf/Assertions.h>
 27  #include <wtf/MathExtras.h>
 28  #include <wtf/Vector.h>
 29  
 30  namespace JSC {
 31  
 32  STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(MathObject);
 33  
 34  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncACos);
 35  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncACosh);
 36  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncASin);
 37  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncASinh);
 38  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncATan);
 39  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncATanh);
 40  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncATan2);
 41  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncCbrt);
 42  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncCeil);
 43  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncClz32);
 44  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncCos);
 45  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncCosh);
 46  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncExp);
 47  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncExpm1);
 48  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncFround);
 49  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncHypot);
 50  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncLog);
 51  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncLog1p);
 52  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncLog10);
 53  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncLog2);
 54  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncMax);
 55  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncPow);
 56  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncRandom);
 57  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncRound);
 58  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncSign);
 59  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncSin);
 60  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncSinh);
 61  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncSqrt);
 62  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncTan);
 63  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncTanh);
 64  static JSC_DECLARE_HOST_FUNCTION(mathProtoFuncIMul);
 65  
 66  const ClassInfo MathObject::s_info = { "Math", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(MathObject) };
 67  
 68  MathObject::MathObject(VM& vm, Structure* structure)
 69      : JSNonFinalObject(vm, structure)
 70  {
 71  }
 72  
 73  void MathObject::finishCreation(VM& vm, JSGlobalObject* globalObject)
 74  {
 75      Base::finishCreation(vm);
 76      ASSERT(inherits(vm, info()));
 77  
 78      putDirectWithoutTransition(vm, Identifier::fromString(vm, "E"), jsNumber(Math::exp(1.0)), PropertyAttribute::DontDelete | PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
 79      putDirectWithoutTransition(vm, Identifier::fromString(vm, "LN2"), jsNumber(Math::log(2.0)), PropertyAttribute::DontDelete | PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
 80      putDirectWithoutTransition(vm, Identifier::fromString(vm, "LN10"), jsNumber(Math::log(10.0)), PropertyAttribute::DontDelete | PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
 81      putDirectWithoutTransition(vm, Identifier::fromString(vm, "LOG2E"), jsNumber(1.0 / Math::log(2.0)), PropertyAttribute::DontDelete | PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
 82      putDirectWithoutTransition(vm, Identifier::fromString(vm, "LOG10E"), jsNumber(0.4342944819032518), PropertyAttribute::DontDelete | PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
 83      putDirectWithoutTransition(vm, Identifier::fromString(vm, "PI"), jsNumber(piDouble), PropertyAttribute::DontDelete | PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
 84      putDirectWithoutTransition(vm, Identifier::fromString(vm, "SQRT1_2"), jsNumber(sqrt(0.5)), PropertyAttribute::DontDelete | PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
 85      putDirectWithoutTransition(vm, Identifier::fromString(vm, "SQRT2"), jsNumber(sqrt(2.0)), PropertyAttribute::DontDelete | PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
 86      JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
 87  
 88      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "abs"), 1, mathProtoFuncAbs, AbsIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
 89      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "acos"), 1, mathProtoFuncACos, ACosIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
 90      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "asin"), 1, mathProtoFuncASin, ASinIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
 91      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "atan"), 1, mathProtoFuncATan, ATanIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
 92      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "acosh"), 1, mathProtoFuncACosh, ACoshIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
 93      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "asinh"), 1, mathProtoFuncASinh, ASinhIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
 94      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "atanh"), 1, mathProtoFuncATanh, ATanhIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
 95      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "atan2"), 2, mathProtoFuncATan2, NoIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
 96      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "cbrt"), 1, mathProtoFuncCbrt, CbrtIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
 97      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "ceil"), 1, mathProtoFuncCeil, CeilIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
 98      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "clz32"), 1, mathProtoFuncClz32, Clz32Intrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
 99      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "cos"), 1, mathProtoFuncCos, CosIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
100      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "cosh"), 1, mathProtoFuncCosh, CoshIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
101      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "exp"), 1, mathProtoFuncExp, ExpIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
102      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "expm1"), 1, mathProtoFuncExpm1, Expm1Intrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
103      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "floor"), 1, mathProtoFuncFloor, FloorIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
104      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "fround"), 1, mathProtoFuncFround, FRoundIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
105      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "hypot"), 2, mathProtoFuncHypot, NoIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
106      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "log"), 1, mathProtoFuncLog, LogIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
107      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "log10"), 1, mathProtoFuncLog10, Log10Intrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
108      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "log1p"), 1, mathProtoFuncLog1p, Log1pIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
109      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "log2"), 1, mathProtoFuncLog2, Log2Intrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
110      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "max"), 2, mathProtoFuncMax, MaxIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
111      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "min"), 2, mathProtoFuncMin, MinIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
112      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "pow"), 2, mathProtoFuncPow, PowIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
113      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "random"), 0, mathProtoFuncRandom, RandomIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
114      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "round"), 1, mathProtoFuncRound, RoundIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
115      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "sign"), 1, mathProtoFuncSign, NoIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
116      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "sin"), 1, mathProtoFuncSin, SinIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
117      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "sinh"), 1, mathProtoFuncSinh, SinhIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
118      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "sqrt"), 1, mathProtoFuncSqrt, SqrtIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
119      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "tan"), 1, mathProtoFuncTan, TanIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
120      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "tanh"), 1, mathProtoFuncTanh, TanhIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
121      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "trunc"), 1, mathProtoFuncTrunc, TruncIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
122      putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(vm, "imul"), 2, mathProtoFuncIMul, IMulIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
123  }
124  
125  // ------------------------------ Functions --------------------------------
126  
127  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncAbs, (JSGlobalObject* globalObject, CallFrame* callFrame))
128  {
129      return JSValue::encode(jsNumber(fabs(callFrame->argument(0).toNumber(globalObject))));
130  }
131  
132  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncACos, (JSGlobalObject* globalObject, CallFrame* callFrame))
133  {
134      return JSValue::encode(jsDoubleNumber(Math::acos(callFrame->argument(0).toNumber(globalObject))));
135  }
136  
137  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncASin, (JSGlobalObject* globalObject, CallFrame* callFrame))
138  {
139      return JSValue::encode(jsDoubleNumber(Math::asin(callFrame->argument(0).toNumber(globalObject))));
140  }
141  
142  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncATan, (JSGlobalObject* globalObject, CallFrame* callFrame))
143  {
144      return JSValue::encode(jsDoubleNumber(Math::atan(callFrame->argument(0).toNumber(globalObject))));
145  }
146  
147  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncATan2, (JSGlobalObject* globalObject, CallFrame* callFrame))
148  {
149      VM& vm = globalObject->vm();
150      auto scope = DECLARE_THROW_SCOPE(vm);
151      double arg0 = callFrame->argument(0).toNumber(globalObject);
152      RETURN_IF_EXCEPTION(scope, encodedJSValue());
153      scope.release();
154      double arg1 = callFrame->argument(1).toNumber(globalObject);
155      return JSValue::encode(jsDoubleNumber(atan2(arg0, arg1)));
156  }
157  
158  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncCeil, (JSGlobalObject* globalObject, CallFrame* callFrame))
159  {
160      return JSValue::encode(jsNumber(ceil(callFrame->argument(0).toNumber(globalObject))));
161  }
162  
163  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncClz32, (JSGlobalObject* globalObject, CallFrame* callFrame))
164  {
165      VM& vm = globalObject->vm();
166      auto scope = DECLARE_THROW_SCOPE(vm);
167      uint32_t value = callFrame->argument(0).toUInt32(globalObject);
168      RETURN_IF_EXCEPTION(scope, encodedJSValue());
169      return JSValue::encode(JSValue(clz(value)));
170  }
171  
172  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncCos, (JSGlobalObject* globalObject, CallFrame* callFrame))
173  {
174      return JSValue::encode(jsDoubleNumber(Math::cos(callFrame->argument(0).toNumber(globalObject))));
175  }
176  
177  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncExp, (JSGlobalObject* globalObject, CallFrame* callFrame))
178  {
179      return JSValue::encode(jsDoubleNumber(Math::exp(callFrame->argument(0).toNumber(globalObject))));
180  }
181  
182  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncFloor, (JSGlobalObject* globalObject, CallFrame* callFrame))
183  {
184      return JSValue::encode(jsNumber(floor(callFrame->argument(0).toNumber(globalObject))));
185  }
186  
187  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncHypot, (JSGlobalObject* globalObject, CallFrame* callFrame))
188  {
189      VM& vm = globalObject->vm();
190      auto scope = DECLARE_THROW_SCOPE(vm);
191      unsigned argsCount = callFrame->argumentCount();
192      double max = 0;
193      Vector<double, 8> args;
194      args.reserveInitialCapacity(argsCount);
195      for (unsigned i = 0; i < argsCount; ++i) {
196          args.uncheckedAppend(callFrame->uncheckedArgument(i).toNumber(globalObject));
197          RETURN_IF_EXCEPTION(scope, encodedJSValue());
198          if (std::isinf(args[i]))
199              return JSValue::encode(jsDoubleNumber(+std::numeric_limits<double>::infinity()));
200          max = std::max(fabs(args[i]), max);
201      }
202      if (!max)
203          max = 1;
204      // Kahan summation algorithm significantly reduces the numerical error in the total obtained.
205      double sum = 0;
206      double compensation = 0;
207      for (double argument : args) {
208          double scaledArgument = argument / max;
209          double summand = scaledArgument * scaledArgument - compensation;
210          double preliminary = sum + summand;
211          compensation = (preliminary - sum) - summand;
212          sum = preliminary;
213      }
214      return JSValue::encode(jsDoubleNumber(sqrt(sum) * max));
215  }
216  
217  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncLog, (JSGlobalObject* globalObject, CallFrame* callFrame))
218  {
219      return JSValue::encode(jsDoubleNumber(Math::log(callFrame->argument(0).toNumber(globalObject))));
220  }
221  
222  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncMax, (JSGlobalObject* globalObject, CallFrame* callFrame))
223  {
224      VM& vm = globalObject->vm();
225      auto scope = DECLARE_THROW_SCOPE(vm);
226      unsigned argsCount = callFrame->argumentCount();
227      double result = -std::numeric_limits<double>::infinity();
228      for (unsigned k = 0; k < argsCount; ++k) {
229          double val = callFrame->uncheckedArgument(k).toNumber(globalObject);
230          RETURN_IF_EXCEPTION(scope, encodedJSValue());
231          if (std::isnan(val)) {
232              result = PNaN;
233          } else if (val > result || (!val && !result && !std::signbit(val)))
234              result = val;
235      }
236      return JSValue::encode(jsNumber(result));
237  }
238  
239  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncMin, (JSGlobalObject* globalObject, CallFrame* callFrame))
240  {
241      VM& vm = globalObject->vm();
242      auto scope = DECLARE_THROW_SCOPE(vm);
243      unsigned argsCount = callFrame->argumentCount();
244      double result = +std::numeric_limits<double>::infinity();
245      for (unsigned k = 0; k < argsCount; ++k) {
246          double val = callFrame->uncheckedArgument(k).toNumber(globalObject);
247          RETURN_IF_EXCEPTION(scope, encodedJSValue());
248          if (std::isnan(val)) {
249              result = PNaN;
250          } else if (val < result || (!val && !result && std::signbit(val)))
251              result = val;
252      }
253      return JSValue::encode(jsNumber(result));
254  }
255  
256  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncPow, (JSGlobalObject* globalObject, CallFrame* callFrame))
257  {
258      // ECMA 15.8.2.1.13
259  
260      VM& vm = globalObject->vm();
261      auto scope = DECLARE_THROW_SCOPE(vm);
262  
263      double arg = callFrame->argument(0).toNumber(globalObject);
264      RETURN_IF_EXCEPTION(scope, encodedJSValue());
265      scope.release();
266      double arg2 = callFrame->argument(1).toNumber(globalObject);
267  
268      return JSValue::encode(JSValue(operationMathPow(arg, arg2)));
269  }
270  
271  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncRandom, (JSGlobalObject* globalObject, CallFrame*))
272  {
273      return JSValue::encode(jsDoubleNumber(globalObject->weakRandomNumber()));
274  }
275  
276  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncRound, (JSGlobalObject* globalObject, CallFrame* callFrame))
277  {
278      return JSValue::encode(jsNumber(Math::roundDouble(callFrame->argument(0).toNumber(globalObject))));
279  }
280  
281  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncSign, (JSGlobalObject* globalObject, CallFrame* callFrame))
282  {
283      double arg = callFrame->argument(0).toNumber(globalObject);
284      if (std::isnan(arg))
285          return JSValue::encode(jsNaN());
286      if (!arg)
287          return JSValue::encode(std::signbit(arg) ? jsNumber(-0.0) : jsNumber(0));
288      return JSValue::encode(jsNumber(std::signbit(arg) ? -1 : 1));
289  }
290  
291  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncSin, (JSGlobalObject* globalObject, CallFrame* callFrame))
292  {
293      return JSValue::encode(jsDoubleNumber(Math::sin(callFrame->argument(0).toNumber(globalObject))));
294  }
295  
296  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncSqrt, (JSGlobalObject* globalObject, CallFrame* callFrame))
297  {
298      return JSValue::encode(jsDoubleNumber(sqrt(callFrame->argument(0).toNumber(globalObject))));
299  }
300  
301  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncTan, (JSGlobalObject* globalObject, CallFrame* callFrame))
302  {
303      return JSValue::encode(jsDoubleNumber(Math::tan(callFrame->argument(0).toNumber(globalObject))));
304  }
305  
306  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncIMul, (JSGlobalObject* globalObject, CallFrame* callFrame))
307  {
308      VM& vm = globalObject->vm();
309      auto scope = DECLARE_THROW_SCOPE(vm);
310      int32_t left = callFrame->argument(0).toInt32(globalObject);
311      RETURN_IF_EXCEPTION(scope, encodedJSValue());
312      scope.release();
313      int32_t right = callFrame->argument(1).toInt32(globalObject);
314      return JSValue::encode(jsNumber(left * right));
315  }
316  
317  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncACosh, (JSGlobalObject* globalObject, CallFrame* callFrame))
318  {
319      return JSValue::encode(jsDoubleNumber(Math::acosh(callFrame->argument(0).toNumber(globalObject))));
320  }
321  
322  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncASinh, (JSGlobalObject* globalObject, CallFrame* callFrame))
323  {
324      return JSValue::encode(jsDoubleNumber(Math::asinh(callFrame->argument(0).toNumber(globalObject))));
325  }
326  
327  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncATanh, (JSGlobalObject* globalObject, CallFrame* callFrame))
328  {
329      return JSValue::encode(jsDoubleNumber(Math::atanh(callFrame->argument(0).toNumber(globalObject))));
330  }
331  
332  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncCbrt, (JSGlobalObject* globalObject, CallFrame* callFrame))
333  {
334      return JSValue::encode(jsDoubleNumber(Math::cbrt(callFrame->argument(0).toNumber(globalObject))));
335  }
336  
337  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncCosh, (JSGlobalObject* globalObject, CallFrame* callFrame))
338  {
339      return JSValue::encode(jsDoubleNumber(Math::cosh(callFrame->argument(0).toNumber(globalObject))));
340  }
341  
342  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncExpm1, (JSGlobalObject* globalObject, CallFrame* callFrame))
343  {
344      return JSValue::encode(jsDoubleNumber(Math::expm1(callFrame->argument(0).toNumber(globalObject))));
345  }
346  
347  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncFround, (JSGlobalObject* globalObject, CallFrame* callFrame))
348  {
349      return JSValue::encode(jsDoubleNumber(static_cast<float>(callFrame->argument(0).toNumber(globalObject))));
350  }
351  
352  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncLog1p, (JSGlobalObject* globalObject, CallFrame* callFrame))
353  {
354      return JSValue::encode(jsDoubleNumber(Math::log1p(callFrame->argument(0).toNumber(globalObject))));
355  }
356  
357  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncLog10, (JSGlobalObject* globalObject, CallFrame* callFrame))
358  {
359      return JSValue::encode(jsDoubleNumber(Math::log10(callFrame->argument(0).toNumber(globalObject))));
360  }
361  
362  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncLog2, (JSGlobalObject* globalObject, CallFrame* callFrame))
363  {
364      return JSValue::encode(jsDoubleNumber(Math::log2(callFrame->argument(0).toNumber(globalObject))));
365  }
366  
367  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncSinh, (JSGlobalObject* globalObject, CallFrame* callFrame))
368  {
369      return JSValue::encode(jsDoubleNumber(Math::sinh(callFrame->argument(0).toNumber(globalObject))));
370  }
371  
372  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncTanh, (JSGlobalObject* globalObject, CallFrame* callFrame))
373  {
374      return JSValue::encode(jsDoubleNumber(Math::tanh(callFrame->argument(0).toNumber(globalObject))));
375  }
376  
377  JSC_DEFINE_HOST_FUNCTION(mathProtoFuncTrunc, (JSGlobalObject* globalObject, CallFrame* callFrame))
378  {
379      return JSValue::encode(jsNumber(callFrame->argument(0).toIntegerPreserveNaN(globalObject)));
380  }
381  
382  } // namespace JSC