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