OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/builtins/builtins.h" | 5 #include "src/builtins/builtins.h" |
6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
7 | 7 |
8 namespace v8 { | 8 namespace v8 { |
9 namespace internal { | 9 namespace internal { |
10 | 10 |
11 // ----------------------------------------------------------------------------- | 11 // ----------------------------------------------------------------------------- |
12 // ES6 section 20.1 Number Objects | 12 // ES6 section 20.1 Number Objects |
13 | 13 |
| 14 // ES6 section 20.1.2.2 Number.isFinite ( number ) |
| 15 void Builtins::Generate_NumberIsFinite(CodeStubAssembler* assembler) { |
| 16 typedef CodeStubAssembler::Label Label; |
| 17 typedef compiler::Node Node; |
| 18 |
| 19 Node* number = assembler->Parameter(1); |
| 20 |
| 21 Label return_true(assembler), return_false(assembler); |
| 22 |
| 23 // Check if {number} is a Smi. |
| 24 assembler->GotoIf(assembler->WordIsSmi(number), &return_true); |
| 25 |
| 26 // Check if {number} is a HeapNumber. |
| 27 assembler->GotoUnless( |
| 28 assembler->WordEqual(assembler->LoadMap(number), |
| 29 assembler->HeapNumberMapConstant()), |
| 30 &return_false); |
| 31 |
| 32 // Check if {number} contains a finite, non-NaN value. |
| 33 Node* number_value = assembler->LoadHeapNumberValue(number); |
| 34 assembler->BranchIfFloat64IsNaN( |
| 35 assembler->Float64Sub(number_value, number_value), &return_false, |
| 36 &return_true); |
| 37 |
| 38 assembler->Bind(&return_true); |
| 39 assembler->Return(assembler->BooleanConstant(true)); |
| 40 |
| 41 assembler->Bind(&return_false); |
| 42 assembler->Return(assembler->BooleanConstant(false)); |
| 43 } |
| 44 |
| 45 // ES6 section 20.1.2.3 Number.isInteger ( number ) |
| 46 void Builtins::Generate_NumberIsInteger(CodeStubAssembler* assembler) { |
| 47 typedef CodeStubAssembler::Label Label; |
| 48 typedef compiler::Node Node; |
| 49 |
| 50 Node* number = assembler->Parameter(1); |
| 51 |
| 52 Label return_true(assembler), return_false(assembler); |
| 53 |
| 54 // Check if {number} is a Smi. |
| 55 assembler->GotoIf(assembler->WordIsSmi(number), &return_true); |
| 56 |
| 57 // Check if {number} is a HeapNumber. |
| 58 assembler->GotoUnless( |
| 59 assembler->WordEqual(assembler->LoadMap(number), |
| 60 assembler->HeapNumberMapConstant()), |
| 61 &return_false); |
| 62 |
| 63 // Load the actual value of {number}. |
| 64 Node* number_value = assembler->LoadHeapNumberValue(number); |
| 65 |
| 66 // Truncate the value of {number} to an integer (or an infinity). |
| 67 Node* integer = assembler->Float64Trunc(number_value); |
| 68 |
| 69 // Check if {number}s value matches the integer (ruling out the infinities). |
| 70 assembler->BranchIfFloat64Equal(assembler->Float64Sub(number_value, integer), |
| 71 assembler->Float64Constant(0.0), &return_true, |
| 72 &return_false); |
| 73 |
| 74 assembler->Bind(&return_true); |
| 75 assembler->Return(assembler->BooleanConstant(true)); |
| 76 |
| 77 assembler->Bind(&return_false); |
| 78 assembler->Return(assembler->BooleanConstant(false)); |
| 79 } |
| 80 |
| 81 // ES6 section 20.1.2.4 Number.isNaN ( number ) |
| 82 void Builtins::Generate_NumberIsNaN(CodeStubAssembler* assembler) { |
| 83 typedef CodeStubAssembler::Label Label; |
| 84 typedef compiler::Node Node; |
| 85 |
| 86 Node* number = assembler->Parameter(1); |
| 87 |
| 88 Label return_true(assembler), return_false(assembler); |
| 89 |
| 90 // Check if {number} is a Smi. |
| 91 assembler->GotoIf(assembler->WordIsSmi(number), &return_false); |
| 92 |
| 93 // Check if {number} is a HeapNumber. |
| 94 assembler->GotoUnless( |
| 95 assembler->WordEqual(assembler->LoadMap(number), |
| 96 assembler->HeapNumberMapConstant()), |
| 97 &return_false); |
| 98 |
| 99 // Check if {number} contains a NaN value. |
| 100 Node* number_value = assembler->LoadHeapNumberValue(number); |
| 101 assembler->BranchIfFloat64IsNaN(number_value, &return_true, &return_false); |
| 102 |
| 103 assembler->Bind(&return_true); |
| 104 assembler->Return(assembler->BooleanConstant(true)); |
| 105 |
| 106 assembler->Bind(&return_false); |
| 107 assembler->Return(assembler->BooleanConstant(false)); |
| 108 } |
| 109 |
| 110 // ES6 section 20.1.2.5 Number.isSafeInteger ( number ) |
| 111 void Builtins::Generate_NumberIsSafeInteger(CodeStubAssembler* assembler) { |
| 112 typedef CodeStubAssembler::Label Label; |
| 113 typedef compiler::Node Node; |
| 114 |
| 115 Node* number = assembler->Parameter(1); |
| 116 |
| 117 Label return_true(assembler), return_false(assembler); |
| 118 |
| 119 // Check if {number} is a Smi. |
| 120 assembler->GotoIf(assembler->WordIsSmi(number), &return_true); |
| 121 |
| 122 // Check if {number} is a HeapNumber. |
| 123 assembler->GotoUnless( |
| 124 assembler->WordEqual(assembler->LoadMap(number), |
| 125 assembler->HeapNumberMapConstant()), |
| 126 &return_false); |
| 127 |
| 128 // Load the actual value of {number}. |
| 129 Node* number_value = assembler->LoadHeapNumberValue(number); |
| 130 |
| 131 // Truncate the value of {number} to an integer (or an infinity). |
| 132 Node* integer = assembler->Float64Trunc(number_value); |
| 133 |
| 134 // Check if {number}s value matches the integer (ruling out the infinities). |
| 135 assembler->GotoUnless( |
| 136 assembler->Float64Equal(assembler->Float64Sub(number_value, integer), |
| 137 assembler->Float64Constant(0.0)), |
| 138 &return_false); |
| 139 |
| 140 // Check if the {integer} value is in safe integer range. |
| 141 assembler->BranchIfFloat64LessThanOrEqual( |
| 142 assembler->Float64Abs(integer), |
| 143 assembler->Float64Constant(kMaxSafeInteger), &return_true, &return_false); |
| 144 |
| 145 assembler->Bind(&return_true); |
| 146 assembler->Return(assembler->BooleanConstant(true)); |
| 147 |
| 148 assembler->Bind(&return_false); |
| 149 assembler->Return(assembler->BooleanConstant(false)); |
| 150 } |
| 151 |
14 // ES6 section 20.1.3.2 Number.prototype.toExponential ( fractionDigits ) | 152 // ES6 section 20.1.3.2 Number.prototype.toExponential ( fractionDigits ) |
15 BUILTIN(NumberPrototypeToExponential) { | 153 BUILTIN(NumberPrototypeToExponential) { |
16 HandleScope scope(isolate); | 154 HandleScope scope(isolate); |
17 Handle<Object> value = args.at<Object>(0); | 155 Handle<Object> value = args.at<Object>(0); |
18 Handle<Object> fraction_digits = args.atOrUndefined(isolate, 1); | 156 Handle<Object> fraction_digits = args.atOrUndefined(isolate, 1); |
19 | 157 |
20 // Unwrap the receiver {value}. | 158 // Unwrap the receiver {value}. |
21 if (value->IsJSValue()) { | 159 if (value->IsJSValue()) { |
22 value = handle(Handle<JSValue>::cast(value)->value(), isolate); | 160 value = handle(Handle<JSValue>::cast(value)->value(), isolate); |
23 } | 161 } |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 Node* receiver = assembler->Parameter(0); | 364 Node* receiver = assembler->Parameter(0); |
227 Node* context = assembler->Parameter(3); | 365 Node* context = assembler->Parameter(3); |
228 | 366 |
229 Node* result = assembler->ToThisValue( | 367 Node* result = assembler->ToThisValue( |
230 context, receiver, PrimitiveType::kNumber, "Number.prototype.valueOf"); | 368 context, receiver, PrimitiveType::kNumber, "Number.prototype.valueOf"); |
231 assembler->Return(result); | 369 assembler->Return(result); |
232 } | 370 } |
233 | 371 |
234 } // namespace internal | 372 } // namespace internal |
235 } // namespace v8 | 373 } // namespace v8 |
OLD | NEW |