| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright 2016 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.h" | 
|  | 6 #include "src/builtins/builtins-utils.h" | 
|  | 7 | 
|  | 8 #include "src/code-factory.h" | 
|  | 9 | 
|  | 10 namespace v8 { | 
|  | 11 namespace internal { | 
|  | 12 | 
|  | 13 // ----------------------------------------------------------------------------- | 
|  | 14 // ES6 section 20.2.2 Function Properties of the Math Object | 
|  | 15 | 
|  | 16 // ES6 section - 20.2.2.1 Math.abs ( x ) | 
|  | 17 void Builtins::Generate_MathAbs(CodeStubAssembler* assembler) { | 
|  | 18   using compiler::Node; | 
|  | 19   Node* x = assembler->Parameter(1); | 
|  | 20   Node* context = assembler->Parameter(4); | 
|  | 21   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 22   Node* value = assembler->Float64Abs(x_value); | 
|  | 23   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 24   assembler->Return(result); | 
|  | 25 } | 
|  | 26 | 
|  | 27 // ES6 section 20.2.2.2 Math.acos ( x ) | 
|  | 28 void Builtins::Generate_MathAcos(CodeStubAssembler* assembler) { | 
|  | 29   using compiler::Node; | 
|  | 30 | 
|  | 31   Node* x = assembler->Parameter(1); | 
|  | 32   Node* context = assembler->Parameter(4); | 
|  | 33   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 34   Node* value = assembler->Float64Acos(x_value); | 
|  | 35   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 36   assembler->Return(result); | 
|  | 37 } | 
|  | 38 | 
|  | 39 // ES6 section 20.2.2.3 Math.acosh ( x ) | 
|  | 40 void Builtins::Generate_MathAcosh(CodeStubAssembler* assembler) { | 
|  | 41   using compiler::Node; | 
|  | 42 | 
|  | 43   Node* x = assembler->Parameter(1); | 
|  | 44   Node* context = assembler->Parameter(4); | 
|  | 45   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 46   Node* value = assembler->Float64Acosh(x_value); | 
|  | 47   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 48   assembler->Return(result); | 
|  | 49 } | 
|  | 50 | 
|  | 51 // ES6 section 20.2.2.4 Math.asin ( x ) | 
|  | 52 void Builtins::Generate_MathAsin(CodeStubAssembler* assembler) { | 
|  | 53   using compiler::Node; | 
|  | 54 | 
|  | 55   Node* x = assembler->Parameter(1); | 
|  | 56   Node* context = assembler->Parameter(4); | 
|  | 57   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 58   Node* value = assembler->Float64Asin(x_value); | 
|  | 59   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 60   assembler->Return(result); | 
|  | 61 } | 
|  | 62 | 
|  | 63 // ES6 section 20.2.2.5 Math.asinh ( x ) | 
|  | 64 void Builtins::Generate_MathAsinh(CodeStubAssembler* assembler) { | 
|  | 65   using compiler::Node; | 
|  | 66 | 
|  | 67   Node* x = assembler->Parameter(1); | 
|  | 68   Node* context = assembler->Parameter(4); | 
|  | 69   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 70   Node* value = assembler->Float64Asinh(x_value); | 
|  | 71   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 72   assembler->Return(result); | 
|  | 73 } | 
|  | 74 | 
|  | 75 // ES6 section 20.2.2.6 Math.atan ( x ) | 
|  | 76 void Builtins::Generate_MathAtan(CodeStubAssembler* assembler) { | 
|  | 77   using compiler::Node; | 
|  | 78 | 
|  | 79   Node* x = assembler->Parameter(1); | 
|  | 80   Node* context = assembler->Parameter(4); | 
|  | 81   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 82   Node* value = assembler->Float64Atan(x_value); | 
|  | 83   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 84   assembler->Return(result); | 
|  | 85 } | 
|  | 86 | 
|  | 87 // ES6 section 20.2.2.7 Math.atanh ( x ) | 
|  | 88 void Builtins::Generate_MathAtanh(CodeStubAssembler* assembler) { | 
|  | 89   using compiler::Node; | 
|  | 90 | 
|  | 91   Node* x = assembler->Parameter(1); | 
|  | 92   Node* context = assembler->Parameter(4); | 
|  | 93   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 94   Node* value = assembler->Float64Atanh(x_value); | 
|  | 95   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 96   assembler->Return(result); | 
|  | 97 } | 
|  | 98 | 
|  | 99 // ES6 section 20.2.2.8 Math.atan2 ( y, x ) | 
|  | 100 void Builtins::Generate_MathAtan2(CodeStubAssembler* assembler) { | 
|  | 101   using compiler::Node; | 
|  | 102 | 
|  | 103   Node* y = assembler->Parameter(1); | 
|  | 104   Node* x = assembler->Parameter(2); | 
|  | 105   Node* context = assembler->Parameter(5); | 
|  | 106   Node* y_value = assembler->TruncateTaggedToFloat64(context, y); | 
|  | 107   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 108   Node* value = assembler->Float64Atan2(y_value, x_value); | 
|  | 109   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 110   assembler->Return(result); | 
|  | 111 } | 
|  | 112 | 
|  | 113 namespace { | 
|  | 114 | 
|  | 115 void Generate_MathRoundingOperation( | 
|  | 116     CodeStubAssembler* assembler, | 
|  | 117     compiler::Node* (CodeStubAssembler::*float64op)(compiler::Node*)) { | 
|  | 118   typedef CodeStubAssembler::Label Label; | 
|  | 119   typedef compiler::Node Node; | 
|  | 120   typedef CodeStubAssembler::Variable Variable; | 
|  | 121 | 
|  | 122   Node* context = assembler->Parameter(4); | 
|  | 123 | 
|  | 124   // We might need to loop once for ToNumber conversion. | 
|  | 125   Variable var_x(assembler, MachineRepresentation::kTagged); | 
|  | 126   Label loop(assembler, &var_x); | 
|  | 127   var_x.Bind(assembler->Parameter(1)); | 
|  | 128   assembler->Goto(&loop); | 
|  | 129   assembler->Bind(&loop); | 
|  | 130   { | 
|  | 131     // Load the current {x} value. | 
|  | 132     Node* x = var_x.value(); | 
|  | 133 | 
|  | 134     // Check if {x} is a Smi or a HeapObject. | 
|  | 135     Label if_xissmi(assembler), if_xisnotsmi(assembler); | 
|  | 136     assembler->Branch(assembler->WordIsSmi(x), &if_xissmi, &if_xisnotsmi); | 
|  | 137 | 
|  | 138     assembler->Bind(&if_xissmi); | 
|  | 139     { | 
|  | 140       // Nothing to do when {x} is a Smi. | 
|  | 141       assembler->Return(x); | 
|  | 142     } | 
|  | 143 | 
|  | 144     assembler->Bind(&if_xisnotsmi); | 
|  | 145     { | 
|  | 146       // Check if {x} is a HeapNumber. | 
|  | 147       Label if_xisheapnumber(assembler), | 
|  | 148           if_xisnotheapnumber(assembler, Label::kDeferred); | 
|  | 149       assembler->Branch( | 
|  | 150           assembler->WordEqual(assembler->LoadMap(x), | 
|  | 151                                assembler->HeapNumberMapConstant()), | 
|  | 152           &if_xisheapnumber, &if_xisnotheapnumber); | 
|  | 153 | 
|  | 154       assembler->Bind(&if_xisheapnumber); | 
|  | 155       { | 
|  | 156         Node* x_value = assembler->LoadHeapNumberValue(x); | 
|  | 157         Node* value = (assembler->*float64op)(x_value); | 
|  | 158         Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 159         assembler->Return(result); | 
|  | 160       } | 
|  | 161 | 
|  | 162       assembler->Bind(&if_xisnotheapnumber); | 
|  | 163       { | 
|  | 164         // Need to convert {x} to a Number first. | 
|  | 165         Callable callable = | 
|  | 166             CodeFactory::NonNumberToNumber(assembler->isolate()); | 
|  | 167         var_x.Bind(assembler->CallStub(callable, context, x)); | 
|  | 168         assembler->Goto(&loop); | 
|  | 169       } | 
|  | 170     } | 
|  | 171   } | 
|  | 172 } | 
|  | 173 | 
|  | 174 }  // namespace | 
|  | 175 | 
|  | 176 // ES6 section 20.2.2.10 Math.ceil ( x ) | 
|  | 177 void Builtins::Generate_MathCeil(CodeStubAssembler* assembler) { | 
|  | 178   Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Ceil); | 
|  | 179 } | 
|  | 180 | 
|  | 181 // ES6 section 20.2.2.9 Math.cbrt ( x ) | 
|  | 182 void Builtins::Generate_MathCbrt(CodeStubAssembler* assembler) { | 
|  | 183   using compiler::Node; | 
|  | 184 | 
|  | 185   Node* x = assembler->Parameter(1); | 
|  | 186   Node* context = assembler->Parameter(4); | 
|  | 187   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 188   Node* value = assembler->Float64Cbrt(x_value); | 
|  | 189   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 190   assembler->Return(result); | 
|  | 191 } | 
|  | 192 | 
|  | 193 // ES6 section 20.2.2.11 Math.clz32 ( x ) | 
|  | 194 void Builtins::Generate_MathClz32(CodeStubAssembler* assembler) { | 
|  | 195   typedef CodeStubAssembler::Label Label; | 
|  | 196   typedef compiler::Node Node; | 
|  | 197   typedef CodeStubAssembler::Variable Variable; | 
|  | 198 | 
|  | 199   Node* context = assembler->Parameter(4); | 
|  | 200 | 
|  | 201   // Shared entry point for the clz32 operation. | 
|  | 202   Variable var_clz32_x(assembler, MachineRepresentation::kWord32); | 
|  | 203   Label do_clz32(assembler); | 
|  | 204 | 
|  | 205   // We might need to loop once for ToNumber conversion. | 
|  | 206   Variable var_x(assembler, MachineRepresentation::kTagged); | 
|  | 207   Label loop(assembler, &var_x); | 
|  | 208   var_x.Bind(assembler->Parameter(1)); | 
|  | 209   assembler->Goto(&loop); | 
|  | 210   assembler->Bind(&loop); | 
|  | 211   { | 
|  | 212     // Load the current {x} value. | 
|  | 213     Node* x = var_x.value(); | 
|  | 214 | 
|  | 215     // Check if {x} is a Smi or a HeapObject. | 
|  | 216     Label if_xissmi(assembler), if_xisnotsmi(assembler); | 
|  | 217     assembler->Branch(assembler->WordIsSmi(x), &if_xissmi, &if_xisnotsmi); | 
|  | 218 | 
|  | 219     assembler->Bind(&if_xissmi); | 
|  | 220     { | 
|  | 221       var_clz32_x.Bind(assembler->SmiToWord32(x)); | 
|  | 222       assembler->Goto(&do_clz32); | 
|  | 223     } | 
|  | 224 | 
|  | 225     assembler->Bind(&if_xisnotsmi); | 
|  | 226     { | 
|  | 227       // Check if {x} is a HeapNumber. | 
|  | 228       Label if_xisheapnumber(assembler), | 
|  | 229           if_xisnotheapnumber(assembler, Label::kDeferred); | 
|  | 230       assembler->Branch( | 
|  | 231           assembler->WordEqual(assembler->LoadMap(x), | 
|  | 232                                assembler->HeapNumberMapConstant()), | 
|  | 233           &if_xisheapnumber, &if_xisnotheapnumber); | 
|  | 234 | 
|  | 235       assembler->Bind(&if_xisheapnumber); | 
|  | 236       { | 
|  | 237         var_clz32_x.Bind(assembler->TruncateHeapNumberValueToWord32(x)); | 
|  | 238         assembler->Goto(&do_clz32); | 
|  | 239       } | 
|  | 240 | 
|  | 241       assembler->Bind(&if_xisnotheapnumber); | 
|  | 242       { | 
|  | 243         // Need to convert {x} to a Number first. | 
|  | 244         Callable callable = | 
|  | 245             CodeFactory::NonNumberToNumber(assembler->isolate()); | 
|  | 246         var_x.Bind(assembler->CallStub(callable, context, x)); | 
|  | 247         assembler->Goto(&loop); | 
|  | 248       } | 
|  | 249     } | 
|  | 250   } | 
|  | 251 | 
|  | 252   assembler->Bind(&do_clz32); | 
|  | 253   { | 
|  | 254     Node* x_value = var_clz32_x.value(); | 
|  | 255     Node* value = assembler->Word32Clz(x_value); | 
|  | 256     Node* result = assembler->ChangeInt32ToTagged(value); | 
|  | 257     assembler->Return(result); | 
|  | 258   } | 
|  | 259 } | 
|  | 260 | 
|  | 261 // ES6 section 20.2.2.12 Math.cos ( x ) | 
|  | 262 void Builtins::Generate_MathCos(CodeStubAssembler* assembler) { | 
|  | 263   using compiler::Node; | 
|  | 264 | 
|  | 265   Node* x = assembler->Parameter(1); | 
|  | 266   Node* context = assembler->Parameter(4); | 
|  | 267   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 268   Node* value = assembler->Float64Cos(x_value); | 
|  | 269   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 270   assembler->Return(result); | 
|  | 271 } | 
|  | 272 | 
|  | 273 // ES6 section 20.2.2.13 Math.cosh ( x ) | 
|  | 274 void Builtins::Generate_MathCosh(CodeStubAssembler* assembler) { | 
|  | 275   using compiler::Node; | 
|  | 276 | 
|  | 277   Node* x = assembler->Parameter(1); | 
|  | 278   Node* context = assembler->Parameter(4); | 
|  | 279   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 280   Node* value = assembler->Float64Cosh(x_value); | 
|  | 281   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 282   assembler->Return(result); | 
|  | 283 } | 
|  | 284 | 
|  | 285 // ES6 section 20.2.2.14 Math.exp ( x ) | 
|  | 286 void Builtins::Generate_MathExp(CodeStubAssembler* assembler) { | 
|  | 287   using compiler::Node; | 
|  | 288 | 
|  | 289   Node* x = assembler->Parameter(1); | 
|  | 290   Node* context = assembler->Parameter(4); | 
|  | 291   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 292   Node* value = assembler->Float64Exp(x_value); | 
|  | 293   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 294   assembler->Return(result); | 
|  | 295 } | 
|  | 296 | 
|  | 297 // ES6 section 20.2.2.16 Math.floor ( x ) | 
|  | 298 void Builtins::Generate_MathFloor(CodeStubAssembler* assembler) { | 
|  | 299   Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Floor); | 
|  | 300 } | 
|  | 301 | 
|  | 302 // ES6 section 20.2.2.17 Math.fround ( x ) | 
|  | 303 void Builtins::Generate_MathFround(CodeStubAssembler* assembler) { | 
|  | 304   using compiler::Node; | 
|  | 305 | 
|  | 306   Node* x = assembler->Parameter(1); | 
|  | 307   Node* context = assembler->Parameter(4); | 
|  | 308   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 309   Node* value32 = assembler->TruncateFloat64ToFloat32(x_value); | 
|  | 310   Node* value = assembler->ChangeFloat32ToFloat64(value32); | 
|  | 311   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 312   assembler->Return(result); | 
|  | 313 } | 
|  | 314 | 
|  | 315 // ES6 section 20.2.2.18 Math.hypot ( value1, value2, ...values ) | 
|  | 316 BUILTIN(MathHypot) { | 
|  | 317   HandleScope scope(isolate); | 
|  | 318   int const length = args.length() - 1; | 
|  | 319   if (length == 0) return Smi::FromInt(0); | 
|  | 320   DCHECK_LT(0, length); | 
|  | 321   double max = 0; | 
|  | 322   bool one_arg_is_nan = false; | 
|  | 323   List<double> abs_values(length); | 
|  | 324   for (int i = 0; i < length; i++) { | 
|  | 325     Handle<Object> x = args.at<Object>(i + 1); | 
|  | 326     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x)); | 
|  | 327     double abs_value = std::abs(x->Number()); | 
|  | 328 | 
|  | 329     if (std::isnan(abs_value)) { | 
|  | 330       one_arg_is_nan = true; | 
|  | 331     } else { | 
|  | 332       abs_values.Add(abs_value); | 
|  | 333       if (max < abs_value) { | 
|  | 334         max = abs_value; | 
|  | 335       } | 
|  | 336     } | 
|  | 337   } | 
|  | 338 | 
|  | 339   if (max == V8_INFINITY) { | 
|  | 340     return *isolate->factory()->NewNumber(V8_INFINITY); | 
|  | 341   } | 
|  | 342 | 
|  | 343   if (one_arg_is_nan) { | 
|  | 344     return *isolate->factory()->nan_value(); | 
|  | 345   } | 
|  | 346 | 
|  | 347   if (max == 0) { | 
|  | 348     return Smi::FromInt(0); | 
|  | 349   } | 
|  | 350   DCHECK_GT(max, 0); | 
|  | 351 | 
|  | 352   // Kahan summation to avoid rounding errors. | 
|  | 353   // Normalize the numbers to the largest one to avoid overflow. | 
|  | 354   double sum = 0; | 
|  | 355   double compensation = 0; | 
|  | 356   for (int i = 0; i < length; i++) { | 
|  | 357     double n = abs_values.at(i) / max; | 
|  | 358     double summand = n * n - compensation; | 
|  | 359     double preliminary = sum + summand; | 
|  | 360     compensation = (preliminary - sum) - summand; | 
|  | 361     sum = preliminary; | 
|  | 362   } | 
|  | 363 | 
|  | 364   return *isolate->factory()->NewNumber(std::sqrt(sum) * max); | 
|  | 365 } | 
|  | 366 | 
|  | 367 // ES6 section 20.2.2.19 Math.imul ( x, y ) | 
|  | 368 void Builtins::Generate_MathImul(CodeStubAssembler* assembler) { | 
|  | 369   using compiler::Node; | 
|  | 370 | 
|  | 371   Node* x = assembler->Parameter(1); | 
|  | 372   Node* y = assembler->Parameter(2); | 
|  | 373   Node* context = assembler->Parameter(5); | 
|  | 374   Node* x_value = assembler->TruncateTaggedToWord32(context, x); | 
|  | 375   Node* y_value = assembler->TruncateTaggedToWord32(context, y); | 
|  | 376   Node* value = assembler->Int32Mul(x_value, y_value); | 
|  | 377   Node* result = assembler->ChangeInt32ToTagged(value); | 
|  | 378   assembler->Return(result); | 
|  | 379 } | 
|  | 380 | 
|  | 381 // ES6 section 20.2.2.20 Math.log ( x ) | 
|  | 382 void Builtins::Generate_MathLog(CodeStubAssembler* assembler) { | 
|  | 383   using compiler::Node; | 
|  | 384 | 
|  | 385   Node* x = assembler->Parameter(1); | 
|  | 386   Node* context = assembler->Parameter(4); | 
|  | 387   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 388   Node* value = assembler->Float64Log(x_value); | 
|  | 389   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 390   assembler->Return(result); | 
|  | 391 } | 
|  | 392 | 
|  | 393 // ES6 section 20.2.2.21 Math.log1p ( x ) | 
|  | 394 void Builtins::Generate_MathLog1p(CodeStubAssembler* assembler) { | 
|  | 395   using compiler::Node; | 
|  | 396 | 
|  | 397   Node* x = assembler->Parameter(1); | 
|  | 398   Node* context = assembler->Parameter(4); | 
|  | 399   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 400   Node* value = assembler->Float64Log1p(x_value); | 
|  | 401   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 402   assembler->Return(result); | 
|  | 403 } | 
|  | 404 | 
|  | 405 // ES6 section 20.2.2.22 Math.log10 ( x ) | 
|  | 406 void Builtins::Generate_MathLog10(CodeStubAssembler* assembler) { | 
|  | 407   using compiler::Node; | 
|  | 408 | 
|  | 409   Node* x = assembler->Parameter(1); | 
|  | 410   Node* context = assembler->Parameter(4); | 
|  | 411   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 412   Node* value = assembler->Float64Log10(x_value); | 
|  | 413   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 414   assembler->Return(result); | 
|  | 415 } | 
|  | 416 | 
|  | 417 // ES6 section 20.2.2.23 Math.log2 ( x ) | 
|  | 418 void Builtins::Generate_MathLog2(CodeStubAssembler* assembler) { | 
|  | 419   using compiler::Node; | 
|  | 420 | 
|  | 421   Node* x = assembler->Parameter(1); | 
|  | 422   Node* context = assembler->Parameter(4); | 
|  | 423   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 424   Node* value = assembler->Float64Log2(x_value); | 
|  | 425   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 426   assembler->Return(result); | 
|  | 427 } | 
|  | 428 | 
|  | 429 // ES6 section 20.2.2.15 Math.expm1 ( x ) | 
|  | 430 void Builtins::Generate_MathExpm1(CodeStubAssembler* assembler) { | 
|  | 431   using compiler::Node; | 
|  | 432 | 
|  | 433   Node* x = assembler->Parameter(1); | 
|  | 434   Node* context = assembler->Parameter(4); | 
|  | 435   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 436   Node* value = assembler->Float64Expm1(x_value); | 
|  | 437   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 438   assembler->Return(result); | 
|  | 439 } | 
|  | 440 | 
|  | 441 // ES6 section 20.2.2.26 Math.pow ( x, y ) | 
|  | 442 void Builtins::Generate_MathPow(CodeStubAssembler* assembler) { | 
|  | 443   using compiler::Node; | 
|  | 444 | 
|  | 445   Node* x = assembler->Parameter(1); | 
|  | 446   Node* y = assembler->Parameter(2); | 
|  | 447   Node* context = assembler->Parameter(5); | 
|  | 448   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 449   Node* y_value = assembler->TruncateTaggedToFloat64(context, y); | 
|  | 450   Node* value = assembler->Float64Pow(x_value, y_value); | 
|  | 451   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 452   assembler->Return(result); | 
|  | 453 } | 
|  | 454 | 
|  | 455 // ES6 section 20.2.2.28 Math.round ( x ) | 
|  | 456 void Builtins::Generate_MathRound(CodeStubAssembler* assembler) { | 
|  | 457   Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Round); | 
|  | 458 } | 
|  | 459 | 
|  | 460 // ES6 section 20.2.2.29 Math.sign ( x ) | 
|  | 461 void Builtins::Generate_MathSign(CodeStubAssembler* assembler) { | 
|  | 462   typedef CodeStubAssembler::Label Label; | 
|  | 463   using compiler::Node; | 
|  | 464 | 
|  | 465   // Convert the {x} value to a Number. | 
|  | 466   Node* x = assembler->Parameter(1); | 
|  | 467   Node* context = assembler->Parameter(4); | 
|  | 468   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 469 | 
|  | 470   // Return -1 if {x} is negative, 1 if {x} is positive, or {x} itself. | 
|  | 471   Label if_xisnegative(assembler), if_xispositive(assembler); | 
|  | 472   assembler->GotoIf( | 
|  | 473       assembler->Float64LessThan(x_value, assembler->Float64Constant(0.0)), | 
|  | 474       &if_xisnegative); | 
|  | 475   assembler->GotoIf( | 
|  | 476       assembler->Float64LessThan(assembler->Float64Constant(0.0), x_value), | 
|  | 477       &if_xispositive); | 
|  | 478   assembler->Return(assembler->ChangeFloat64ToTagged(x_value)); | 
|  | 479 | 
|  | 480   assembler->Bind(&if_xisnegative); | 
|  | 481   assembler->Return(assembler->SmiConstant(Smi::FromInt(-1))); | 
|  | 482 | 
|  | 483   assembler->Bind(&if_xispositive); | 
|  | 484   assembler->Return(assembler->SmiConstant(Smi::FromInt(1))); | 
|  | 485 } | 
|  | 486 | 
|  | 487 // ES6 section 20.2.2.30 Math.sin ( x ) | 
|  | 488 void Builtins::Generate_MathSin(CodeStubAssembler* assembler) { | 
|  | 489   using compiler::Node; | 
|  | 490 | 
|  | 491   Node* x = assembler->Parameter(1); | 
|  | 492   Node* context = assembler->Parameter(4); | 
|  | 493   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 494   Node* value = assembler->Float64Sin(x_value); | 
|  | 495   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 496   assembler->Return(result); | 
|  | 497 } | 
|  | 498 | 
|  | 499 // ES6 section 20.2.2.31 Math.sinh ( x ) | 
|  | 500 void Builtins::Generate_MathSinh(CodeStubAssembler* assembler) { | 
|  | 501   using compiler::Node; | 
|  | 502 | 
|  | 503   Node* x = assembler->Parameter(1); | 
|  | 504   Node* context = assembler->Parameter(4); | 
|  | 505   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 506   Node* value = assembler->Float64Sinh(x_value); | 
|  | 507   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 508   assembler->Return(result); | 
|  | 509 } | 
|  | 510 | 
|  | 511 // ES6 section 20.2.2.32 Math.sqrt ( x ) | 
|  | 512 void Builtins::Generate_MathSqrt(CodeStubAssembler* assembler) { | 
|  | 513   using compiler::Node; | 
|  | 514 | 
|  | 515   Node* x = assembler->Parameter(1); | 
|  | 516   Node* context = assembler->Parameter(4); | 
|  | 517   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 518   Node* value = assembler->Float64Sqrt(x_value); | 
|  | 519   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 520   assembler->Return(result); | 
|  | 521 } | 
|  | 522 | 
|  | 523 // ES6 section 20.2.2.33 Math.tan ( x ) | 
|  | 524 void Builtins::Generate_MathTan(CodeStubAssembler* assembler) { | 
|  | 525   using compiler::Node; | 
|  | 526 | 
|  | 527   Node* x = assembler->Parameter(1); | 
|  | 528   Node* context = assembler->Parameter(4); | 
|  | 529   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 530   Node* value = assembler->Float64Tan(x_value); | 
|  | 531   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 532   assembler->Return(result); | 
|  | 533 } | 
|  | 534 | 
|  | 535 // ES6 section 20.2.2.34 Math.tanh ( x ) | 
|  | 536 void Builtins::Generate_MathTanh(CodeStubAssembler* assembler) { | 
|  | 537   using compiler::Node; | 
|  | 538 | 
|  | 539   Node* x = assembler->Parameter(1); | 
|  | 540   Node* context = assembler->Parameter(4); | 
|  | 541   Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 
|  | 542   Node* value = assembler->Float64Tanh(x_value); | 
|  | 543   Node* result = assembler->ChangeFloat64ToTagged(value); | 
|  | 544   assembler->Return(result); | 
|  | 545 } | 
|  | 546 | 
|  | 547 // ES6 section 20.2.2.35 Math.trunc ( x ) | 
|  | 548 void Builtins::Generate_MathTrunc(CodeStubAssembler* assembler) { | 
|  | 549   Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Trunc); | 
|  | 550 } | 
|  | 551 | 
|  | 552 void Builtins::Generate_MathMax(MacroAssembler* masm) { | 
|  | 553   Generate_MathMaxMin(masm, MathMaxMinKind::kMax); | 
|  | 554 } | 
|  | 555 | 
|  | 556 void Builtins::Generate_MathMin(MacroAssembler* masm) { | 
|  | 557   Generate_MathMaxMin(masm, MathMaxMinKind::kMin); | 
|  | 558 } | 
|  | 559 | 
|  | 560 }  // namespace internal | 
|  | 561 }  // namespace v8 | 
| OLD | NEW | 
|---|