Line data Source code
1 : // Copyright 2017 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/builtins/builtins-math-gen.h"
6 :
7 : #include "src/builtins/builtins-utils-gen.h"
8 : #include "src/builtins/builtins.h"
9 : #include "src/code-factory.h"
10 : #include "src/code-stub-assembler.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 : // -----------------------------------------------------------------------------
16 : // ES6 section 20.2.2 Function Properties of the Math Object
17 :
18 : // ES6 #sec-math.abs
19 224 : TF_BUILTIN(MathAbs, CodeStubAssembler) {
20 : Node* context = Parameter(Descriptor::kContext);
21 :
22 : // We might need to loop once for ToNumber conversion.
23 56 : VARIABLE(var_x, MachineRepresentation::kTagged);
24 56 : Label loop(this, &var_x);
25 56 : var_x.Bind(Parameter(Descriptor::kX));
26 56 : Goto(&loop);
27 56 : BIND(&loop);
28 : {
29 : // Load the current {x} value.
30 56 : Node* x = var_x.value();
31 :
32 : // Check if {x} is a Smi or a HeapObject.
33 56 : Label if_xissmi(this), if_xisnotsmi(this);
34 112 : Branch(TaggedIsSmi(x), &if_xissmi, &if_xisnotsmi);
35 :
36 56 : BIND(&if_xissmi);
37 : {
38 : Label if_overflow(this, Label::kDeferred);
39 :
40 : // check if support abs function
41 56 : if (IsIntPtrAbsWithOverflowSupported()) {
42 0 : Node* pair = IntPtrAbsWithOverflow(x);
43 0 : Node* overflow = Projection(1, pair);
44 0 : GotoIf(overflow, &if_overflow);
45 :
46 : // There is a Smi representation for negated {x}.
47 0 : Node* result = Projection(0, pair);
48 0 : Return(BitcastWordToTagged(result));
49 :
50 : } else {
51 : // Check if {x} is already positive.
52 56 : Label if_xispositive(this), if_xisnotpositive(this);
53 : BranchIfSmiLessThanOrEqual(SmiConstant(0), CAST(x), &if_xispositive,
54 56 : &if_xisnotpositive);
55 :
56 56 : BIND(&if_xispositive);
57 : {
58 : // Just return the input {x}.
59 56 : Return(x);
60 : }
61 :
62 56 : BIND(&if_xisnotpositive);
63 : {
64 : // Try to negate the {x} value.
65 56 : TNode<Smi> result = TrySmiSub(SmiConstant(0), CAST(x), &if_overflow);
66 56 : Return(result);
67 56 : }
68 : }
69 :
70 56 : BIND(&if_overflow);
71 112 : { Return(NumberConstant(0.0 - Smi::kMinValue)); }
72 : }
73 :
74 56 : BIND(&if_xisnotsmi);
75 : {
76 : // Check if {x} is a HeapNumber.
77 56 : Label if_xisheapnumber(this), if_xisnotheapnumber(this, Label::kDeferred);
78 112 : Branch(IsHeapNumber(x), &if_xisheapnumber, &if_xisnotheapnumber);
79 :
80 56 : BIND(&if_xisheapnumber);
81 : {
82 112 : Node* x_value = LoadHeapNumberValue(x);
83 112 : Node* value = Float64Abs(x_value);
84 112 : Node* result = AllocateHeapNumberWithValue(value);
85 56 : Return(result);
86 : }
87 :
88 56 : BIND(&if_xisnotheapnumber);
89 : {
90 : // Need to convert {x} to a Number first.
91 112 : var_x.Bind(CallBuiltin(Builtins::kNonNumberToNumber, context, x));
92 56 : Goto(&loop);
93 56 : }
94 56 : }
95 56 : }
96 56 : }
97 :
98 224 : void MathBuiltinsAssembler::MathRoundingOperation(
99 : Node* context, Node* x,
100 : TNode<Float64T> (CodeStubAssembler::*float64op)(SloppyTNode<Float64T>)) {
101 : // We might need to loop once for ToNumber conversion.
102 224 : VARIABLE(var_x, MachineRepresentation::kTagged, x);
103 224 : Label loop(this, &var_x);
104 224 : Goto(&loop);
105 224 : BIND(&loop);
106 : {
107 : // Load the current {x} value.
108 224 : Node* x = var_x.value();
109 :
110 : // Check if {x} is a Smi or a HeapObject.
111 224 : Label if_xissmi(this), if_xisnotsmi(this);
112 448 : Branch(TaggedIsSmi(x), &if_xissmi, &if_xisnotsmi);
113 :
114 224 : BIND(&if_xissmi);
115 : {
116 : // Nothing to do when {x} is a Smi.
117 224 : Return(x);
118 : }
119 :
120 224 : BIND(&if_xisnotsmi);
121 : {
122 : // Check if {x} is a HeapNumber.
123 224 : Label if_xisheapnumber(this), if_xisnotheapnumber(this, Label::kDeferred);
124 448 : Branch(IsHeapNumber(x), &if_xisheapnumber, &if_xisnotheapnumber);
125 :
126 224 : BIND(&if_xisheapnumber);
127 : {
128 448 : Node* x_value = LoadHeapNumberValue(x);
129 672 : Node* value = (this->*float64op)(x_value);
130 448 : Node* result = ChangeFloat64ToTagged(value);
131 224 : Return(result);
132 : }
133 :
134 224 : BIND(&if_xisnotheapnumber);
135 : {
136 : // Need to convert {x} to a Number first.
137 448 : var_x.Bind(CallBuiltin(Builtins::kNonNumberToNumber, context, x));
138 224 : Goto(&loop);
139 224 : }
140 224 : }
141 224 : }
142 224 : }
143 :
144 1120 : void MathBuiltinsAssembler::MathUnaryOperation(
145 : Node* context, Node* x,
146 : TNode<Float64T> (CodeStubAssembler::*float64op)(SloppyTNode<Float64T>)) {
147 1120 : Node* x_value = TruncateTaggedToFloat64(context, x);
148 3360 : Node* value = (this->*float64op)(x_value);
149 2240 : Node* result = AllocateHeapNumberWithValue(value);
150 1120 : Return(result);
151 1120 : }
152 :
153 112 : void MathBuiltinsAssembler::MathMaxMin(
154 : Node* context, Node* argc,
155 : TNode<Float64T> (CodeStubAssembler::*float64op)(SloppyTNode<Float64T>,
156 : SloppyTNode<Float64T>),
157 : double default_val) {
158 336 : CodeStubArguments arguments(this, ChangeInt32ToIntPtr(argc));
159 : argc = arguments.GetLength(INTPTR_PARAMETERS);
160 :
161 112 : VARIABLE(result, MachineRepresentation::kFloat64);
162 224 : result.Bind(Float64Constant(default_val));
163 :
164 224 : CodeStubAssembler::VariableList vars({&result}, zone());
165 112 : arguments.ForEach(vars, [=, &result](Node* arg) {
166 112 : Node* float_value = TruncateTaggedToFloat64(context, arg);
167 448 : result.Bind((this->*float64op)(result.value(), float_value));
168 448 : });
169 :
170 336 : arguments.PopAndReturn(ChangeFloat64ToTagged(result.value()));
171 112 : }
172 :
173 : // ES6 #sec-math.acos
174 224 : TF_BUILTIN(MathAcos, MathBuiltinsAssembler) {
175 : Node* context = Parameter(Descriptor::kContext);
176 : Node* x = Parameter(Descriptor::kX);
177 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Acos);
178 56 : }
179 :
180 : // ES6 #sec-math.acosh
181 224 : TF_BUILTIN(MathAcosh, MathBuiltinsAssembler) {
182 : Node* context = Parameter(Descriptor::kContext);
183 : Node* x = Parameter(Descriptor::kX);
184 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Acosh);
185 56 : }
186 :
187 : // ES6 #sec-math.asin
188 224 : TF_BUILTIN(MathAsin, MathBuiltinsAssembler) {
189 : Node* context = Parameter(Descriptor::kContext);
190 : Node* x = Parameter(Descriptor::kX);
191 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Asin);
192 56 : }
193 :
194 : // ES6 #sec-math.asinh
195 224 : TF_BUILTIN(MathAsinh, MathBuiltinsAssembler) {
196 : Node* context = Parameter(Descriptor::kContext);
197 : Node* x = Parameter(Descriptor::kX);
198 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Asinh);
199 56 : }
200 :
201 : // ES6 #sec-math.atan
202 224 : TF_BUILTIN(MathAtan, MathBuiltinsAssembler) {
203 : Node* context = Parameter(Descriptor::kContext);
204 : Node* x = Parameter(Descriptor::kX);
205 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Atan);
206 56 : }
207 :
208 : // ES6 #sec-math.atanh
209 224 : TF_BUILTIN(MathAtanh, MathBuiltinsAssembler) {
210 : Node* context = Parameter(Descriptor::kContext);
211 : Node* x = Parameter(Descriptor::kX);
212 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Atanh);
213 56 : }
214 :
215 : // ES6 #sec-math.atan2
216 168 : TF_BUILTIN(MathAtan2, CodeStubAssembler) {
217 : Node* context = Parameter(Descriptor::kContext);
218 : Node* y = Parameter(Descriptor::kY);
219 : Node* x = Parameter(Descriptor::kX);
220 :
221 56 : Node* y_value = TruncateTaggedToFloat64(context, y);
222 56 : Node* x_value = TruncateTaggedToFloat64(context, x);
223 112 : Node* value = Float64Atan2(y_value, x_value);
224 112 : Node* result = AllocateHeapNumberWithValue(value);
225 56 : Return(result);
226 56 : }
227 :
228 : // ES6 #sec-math.ceil
229 224 : TF_BUILTIN(MathCeil, MathBuiltinsAssembler) {
230 : Node* context = Parameter(Descriptor::kContext);
231 : Node* x = Parameter(Descriptor::kX);
232 56 : MathRoundingOperation(context, x, &CodeStubAssembler::Float64Ceil);
233 56 : }
234 :
235 : // ES6 #sec-math.cbrt
236 224 : TF_BUILTIN(MathCbrt, MathBuiltinsAssembler) {
237 : Node* context = Parameter(Descriptor::kContext);
238 : Node* x = Parameter(Descriptor::kX);
239 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Cbrt);
240 56 : }
241 :
242 : // ES6 #sec-math.clz32
243 224 : TF_BUILTIN(MathClz32, CodeStubAssembler) {
244 : Node* context = Parameter(Descriptor::kContext);
245 :
246 : // Shared entry point for the clz32 operation.
247 56 : VARIABLE(var_clz32_x, MachineRepresentation::kWord32);
248 56 : Label do_clz32(this);
249 :
250 : // We might need to loop once for ToNumber conversion.
251 112 : VARIABLE(var_x, MachineRepresentation::kTagged);
252 56 : Label loop(this, &var_x);
253 56 : var_x.Bind(Parameter(Descriptor::kX));
254 56 : Goto(&loop);
255 56 : BIND(&loop);
256 : {
257 : // Load the current {x} value.
258 56 : Node* x = var_x.value();
259 :
260 : // Check if {x} is a Smi or a HeapObject.
261 56 : Label if_xissmi(this), if_xisnotsmi(this);
262 112 : Branch(TaggedIsSmi(x), &if_xissmi, &if_xisnotsmi);
263 :
264 56 : BIND(&if_xissmi);
265 : {
266 112 : var_clz32_x.Bind(SmiToInt32(x));
267 56 : Goto(&do_clz32);
268 : }
269 :
270 56 : BIND(&if_xisnotsmi);
271 : {
272 : // Check if {x} is a HeapNumber.
273 56 : Label if_xisheapnumber(this), if_xisnotheapnumber(this, Label::kDeferred);
274 112 : Branch(IsHeapNumber(x), &if_xisheapnumber, &if_xisnotheapnumber);
275 :
276 56 : BIND(&if_xisheapnumber);
277 : {
278 56 : var_clz32_x.Bind(TruncateHeapNumberValueToWord32(x));
279 56 : Goto(&do_clz32);
280 : }
281 :
282 56 : BIND(&if_xisnotheapnumber);
283 : {
284 : // Need to convert {x} to a Number first.
285 112 : var_x.Bind(CallBuiltin(Builtins::kNonNumberToNumber, context, x));
286 56 : Goto(&loop);
287 56 : }
288 56 : }
289 : }
290 :
291 56 : BIND(&do_clz32);
292 : {
293 56 : Node* x_value = var_clz32_x.value();
294 112 : Node* value = Word32Clz(x_value);
295 112 : Node* result = ChangeInt32ToTagged(value);
296 56 : Return(result);
297 56 : }
298 56 : }
299 :
300 : // ES6 #sec-math.cos
301 224 : TF_BUILTIN(MathCos, MathBuiltinsAssembler) {
302 : Node* context = Parameter(Descriptor::kContext);
303 : Node* x = Parameter(Descriptor::kX);
304 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Cos);
305 56 : }
306 :
307 : // ES6 #sec-math.cosh
308 224 : TF_BUILTIN(MathCosh, MathBuiltinsAssembler) {
309 : Node* context = Parameter(Descriptor::kContext);
310 : Node* x = Parameter(Descriptor::kX);
311 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Cosh);
312 56 : }
313 :
314 : // ES6 #sec-math.exp
315 224 : TF_BUILTIN(MathExp, MathBuiltinsAssembler) {
316 : Node* context = Parameter(Descriptor::kContext);
317 : Node* x = Parameter(Descriptor::kX);
318 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Exp);
319 56 : }
320 :
321 : // ES6 #sec-math.expm1
322 224 : TF_BUILTIN(MathExpm1, MathBuiltinsAssembler) {
323 : Node* context = Parameter(Descriptor::kContext);
324 : Node* x = Parameter(Descriptor::kX);
325 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Expm1);
326 56 : }
327 :
328 : // ES6 #sec-math.floor
329 224 : TF_BUILTIN(MathFloor, MathBuiltinsAssembler) {
330 : Node* context = Parameter(Descriptor::kContext);
331 : Node* x = Parameter(Descriptor::kX);
332 56 : MathRoundingOperation(context, x, &CodeStubAssembler::Float64Floor);
333 56 : }
334 :
335 : // ES6 #sec-math.fround
336 168 : TF_BUILTIN(MathFround, CodeStubAssembler) {
337 : Node* context = Parameter(Descriptor::kContext);
338 : Node* x = Parameter(Descriptor::kX);
339 56 : Node* x_value = TruncateTaggedToFloat64(context, x);
340 112 : Node* value32 = TruncateFloat64ToFloat32(x_value);
341 112 : Node* value = ChangeFloat32ToFloat64(value32);
342 112 : Node* result = AllocateHeapNumberWithValue(value);
343 56 : Return(result);
344 56 : }
345 :
346 : // ES6 #sec-math.imul
347 168 : TF_BUILTIN(MathImul, CodeStubAssembler) {
348 : Node* context = Parameter(Descriptor::kContext);
349 : Node* x = Parameter(Descriptor::kX);
350 : Node* y = Parameter(Descriptor::kY);
351 56 : Node* x_value = TruncateTaggedToWord32(context, x);
352 56 : Node* y_value = TruncateTaggedToWord32(context, y);
353 112 : Node* value = Int32Mul(x_value, y_value);
354 112 : Node* result = ChangeInt32ToTagged(value);
355 56 : Return(result);
356 56 : }
357 :
358 : // ES6 #sec-math.log
359 224 : TF_BUILTIN(MathLog, MathBuiltinsAssembler) {
360 : Node* context = Parameter(Descriptor::kContext);
361 : Node* x = Parameter(Descriptor::kX);
362 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Log);
363 56 : }
364 :
365 : // ES6 #sec-math.log1p
366 224 : TF_BUILTIN(MathLog1p, MathBuiltinsAssembler) {
367 : Node* context = Parameter(Descriptor::kContext);
368 : Node* x = Parameter(Descriptor::kX);
369 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Log1p);
370 56 : }
371 :
372 : // ES6 #sec-math.log10
373 224 : TF_BUILTIN(MathLog10, MathBuiltinsAssembler) {
374 : Node* context = Parameter(Descriptor::kContext);
375 : Node* x = Parameter(Descriptor::kX);
376 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Log10);
377 56 : }
378 :
379 : // ES6 #sec-math.log2
380 224 : TF_BUILTIN(MathLog2, MathBuiltinsAssembler) {
381 : Node* context = Parameter(Descriptor::kContext);
382 : Node* x = Parameter(Descriptor::kX);
383 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Log2);
384 56 : }
385 :
386 112 : CodeStubAssembler::Node* MathBuiltinsAssembler::MathPow(Node* context,
387 : Node* base,
388 : Node* exponent) {
389 112 : Node* base_value = TruncateTaggedToFloat64(context, base);
390 112 : Node* exponent_value = TruncateTaggedToFloat64(context, exponent);
391 224 : Node* value = Float64Pow(base_value, exponent_value);
392 224 : return ChangeFloat64ToTagged(value);
393 : }
394 :
395 : // ES6 #sec-math.pow
396 224 : TF_BUILTIN(MathPow, MathBuiltinsAssembler) {
397 : Return(MathPow(Parameter(Descriptor::kContext), Parameter(Descriptor::kBase),
398 112 : Parameter(Descriptor::kExponent)));
399 56 : }
400 :
401 : // ES6 #sec-math.random
402 168 : TF_BUILTIN(MathRandom, CodeStubAssembler) {
403 : Node* context = Parameter(Descriptor::kContext);
404 112 : Node* native_context = LoadNativeContext(context);
405 :
406 : // Load cache index.
407 : TVARIABLE(Smi, smi_index);
408 112 : smi_index = CAST(
409 : LoadContextElement(native_context, Context::MATH_RANDOM_INDEX_INDEX));
410 :
411 : // Cached random numbers are exhausted if index is 0. Go to slow path.
412 56 : Label if_cached(this);
413 168 : GotoIf(SmiAbove(smi_index.value(), SmiConstant(0)), &if_cached);
414 :
415 : // Cache exhausted, populate the cache. Return value is the new index.
416 : Node* const refill_math_random =
417 112 : ExternalConstant(ExternalReference::refill_math_random());
418 : Node* const isolate_ptr =
419 112 : ExternalConstant(ExternalReference::isolate_address(isolate()));
420 56 : MachineType type_tagged = MachineType::AnyTagged();
421 56 : MachineType type_ptr = MachineType::Pointer();
422 :
423 : smi_index =
424 56 : CAST(CallCFunction2(type_tagged, type_ptr, type_tagged,
425 : refill_math_random, isolate_ptr, native_context));
426 56 : Goto(&if_cached);
427 :
428 : // Compute next index by decrement.
429 56 : BIND(&if_cached);
430 112 : TNode<Smi> new_smi_index = SmiSub(smi_index.value(), SmiConstant(1));
431 : StoreContextElement(native_context, Context::MATH_RANDOM_INDEX_INDEX,
432 56 : new_smi_index);
433 :
434 : // Load and return next cached random number.
435 : Node* array =
436 112 : LoadContextElement(native_context, Context::MATH_RANDOM_CACHE_INDEX);
437 : Node* random = LoadFixedDoubleArrayElement(
438 112 : array, new_smi_index, MachineType::Float64(), 0, SMI_PARAMETERS);
439 112 : Return(AllocateHeapNumberWithValue(random));
440 56 : }
441 :
442 : // ES6 #sec-math.round
443 224 : TF_BUILTIN(MathRound, MathBuiltinsAssembler) {
444 : Node* context = Parameter(Descriptor::kContext);
445 : Node* x = Parameter(Descriptor::kX);
446 56 : MathRoundingOperation(context, x, &CodeStubAssembler::Float64Round);
447 56 : }
448 :
449 : // ES6 #sec-math.sign
450 168 : TF_BUILTIN(MathSign, CodeStubAssembler) {
451 : // Convert the {x} value to a Number.
452 : Node* context = Parameter(Descriptor::kContext);
453 : Node* x = Parameter(Descriptor::kX);
454 56 : Node* x_value = TruncateTaggedToFloat64(context, x);
455 :
456 : // Return -1 if {x} is negative, 1 if {x} is positive, or {x} itself.
457 56 : Label if_xisnegative(this), if_xispositive(this);
458 168 : GotoIf(Float64LessThan(x_value, Float64Constant(0.0)), &if_xisnegative);
459 168 : GotoIf(Float64LessThan(Float64Constant(0.0), x_value), &if_xispositive);
460 112 : Return(ChangeFloat64ToTagged(x_value));
461 :
462 56 : BIND(&if_xisnegative);
463 112 : Return(SmiConstant(-1));
464 :
465 56 : BIND(&if_xispositive);
466 168 : Return(SmiConstant(1));
467 56 : }
468 :
469 : // ES6 #sec-math.sin
470 224 : TF_BUILTIN(MathSin, MathBuiltinsAssembler) {
471 : Node* context = Parameter(Descriptor::kContext);
472 : Node* x = Parameter(Descriptor::kX);
473 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Sin);
474 56 : }
475 :
476 : // ES6 #sec-math.sinh
477 224 : TF_BUILTIN(MathSinh, MathBuiltinsAssembler) {
478 : Node* context = Parameter(Descriptor::kContext);
479 : Node* x = Parameter(Descriptor::kX);
480 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Sinh);
481 56 : }
482 :
483 : // ES6 #sec-math.sqrt
484 224 : TF_BUILTIN(MathSqrt, MathBuiltinsAssembler) {
485 : Node* context = Parameter(Descriptor::kContext);
486 : Node* x = Parameter(Descriptor::kX);
487 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Sqrt);
488 56 : }
489 :
490 : // ES6 #sec-math.tan
491 224 : TF_BUILTIN(MathTan, MathBuiltinsAssembler) {
492 : Node* context = Parameter(Descriptor::kContext);
493 : Node* x = Parameter(Descriptor::kX);
494 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Tan);
495 56 : }
496 :
497 : // ES6 #sec-math.tanh
498 224 : TF_BUILTIN(MathTanh, MathBuiltinsAssembler) {
499 : Node* context = Parameter(Descriptor::kContext);
500 : Node* x = Parameter(Descriptor::kX);
501 56 : MathUnaryOperation(context, x, &CodeStubAssembler::Float64Tanh);
502 56 : }
503 :
504 : // ES6 #sec-math.trunc
505 224 : TF_BUILTIN(MathTrunc, MathBuiltinsAssembler) {
506 : Node* context = Parameter(Descriptor::kContext);
507 : Node* x = Parameter(Descriptor::kX);
508 56 : MathRoundingOperation(context, x, &CodeStubAssembler::Float64Trunc);
509 56 : }
510 :
511 : // ES6 #sec-math.max
512 224 : TF_BUILTIN(MathMax, MathBuiltinsAssembler) {
513 : // TODO(ishell): use constants from Descriptor once the JSFunction linkage
514 : // arguments are reordered.
515 : Node* context = Parameter(Descriptor::kContext);
516 : Node* argc = Parameter(Descriptor::kJSActualArgumentsCount);
517 56 : MathMaxMin(context, argc, &CodeStubAssembler::Float64Max, -1.0 * V8_INFINITY);
518 56 : }
519 :
520 : // ES6 #sec-math.min
521 224 : TF_BUILTIN(MathMin, MathBuiltinsAssembler) {
522 : // TODO(ishell): use constants from Descriptor once the JSFunction linkage
523 : // arguments are reordered.
524 : Node* context = Parameter(Descriptor::kContext);
525 : Node* argc = Parameter(Descriptor::kJSActualArgumentsCount);
526 56 : MathMaxMin(context, argc, &CodeStubAssembler::Float64Min, V8_INFINITY);
527 56 : }
528 :
529 : } // namespace internal
530 94089 : } // namespace v8
|