OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 x = %ToPrimitive(x, NO_HINT); | 90 x = %ToPrimitive(x, NO_HINT); |
91 } | 91 } |
92 } | 92 } |
93 } | 93 } |
94 | 94 |
95 // ECMA-262, section 11.9.4, page 56. | 95 // ECMA-262, section 11.9.4, page 56. |
96 function STRICT_EQUALS(x) { | 96 function STRICT_EQUALS(x) { |
97 if (IS_STRING(this)) { | 97 if (IS_STRING(this)) { |
98 if (!IS_STRING(x)) return 1; // not equal | 98 if (!IS_STRING(x)) return 1; // not equal |
99 return %StringEquals(this, x); | 99 return %StringEquals(this, x); |
100 } | 100 } |
101 | 101 |
102 if (IS_NUMBER(this)) { | 102 if (IS_NUMBER(this)) { |
103 if (!IS_NUMBER(x)) return 1; // not equal | 103 if (!IS_NUMBER(x)) return 1; // not equal |
104 return %NumberEquals(this, x); | 104 return %NumberEquals(this, x); |
105 } | 105 } |
106 | 106 |
107 // If anything else gets here, we just do simple identity check. | 107 // If anything else gets here, we just do simple identity check. |
108 // Objects (including functions), null, undefined and booleans were | 108 // Objects (including functions), null, undefined and booleans were |
109 // checked in the CompareStub, so there should be nothing left. | 109 // checked in the CompareStub, so there should be nothing left. |
110 return %_ObjectEquals(this, x) ? 0 : 1; | 110 return %_ObjectEquals(this, x) ? 0 : 1; |
111 } | 111 } |
112 | 112 |
113 | 113 |
114 // ECMA-262, section 11.8.5, page 53. The 'ncr' parameter is used as | 114 // ECMA-262, section 11.8.5, page 53. The 'ncr' parameter is used as |
115 // the result when either (or both) the operands are NaN. | 115 // the result when either (or both) the operands are NaN. |
(...skipping 25 matching lines...) Expand all Loading... |
141 | 141 |
142 // ECMA-262, section 11.6.1, page 50. | 142 // ECMA-262, section 11.6.1, page 50. |
143 function ADD(x) { | 143 function ADD(x) { |
144 // Fast case: Check for number operands and do the addition. | 144 // Fast case: Check for number operands and do the addition. |
145 if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x); | 145 if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x); |
146 if (IS_STRING(this) && IS_STRING(x)) return %StringAdd(this, x); | 146 if (IS_STRING(this) && IS_STRING(x)) return %StringAdd(this, x); |
147 | 147 |
148 // Default implementation. | 148 // Default implementation. |
149 var a = %ToPrimitive(this, NO_HINT); | 149 var a = %ToPrimitive(this, NO_HINT); |
150 var b = %ToPrimitive(x, NO_HINT); | 150 var b = %ToPrimitive(x, NO_HINT); |
151 | 151 |
152 if (IS_STRING(a)) { | 152 if (IS_STRING(a)) { |
153 return %StringAdd(a, %ToString(b)); | 153 return %StringAdd(a, %ToString(b)); |
154 } else if (IS_STRING(b)) { | 154 } else if (IS_STRING(b)) { |
155 return %StringAdd(%ToString(a), b); | 155 return %StringAdd(%ToString(a), b); |
156 } else { | 156 } else { |
157 return %NumberAdd(%ToNumber(a), %ToNumber(b)); | 157 return %NumberAdd(%ToNumber(a), %ToNumber(b)); |
158 } | 158 } |
159 } | 159 } |
160 | 160 |
161 | 161 |
162 // Left operand (this) is already a string. | 162 // Left operand (this) is already a string. |
163 function STRING_ADD_LEFT(x) { | 163 function STRING_ADD_LEFT(y) { |
164 x = %ToString(%ToPrimitive(x, NO_HINT)); | 164 if (!IS_STRING(y)) y = %ToString(%ToPrimitive(y, NO_HINT)); |
165 return %StringAdd(this, x); | 165 return %StringAdd(this, y); |
166 } | 166 } |
167 | 167 |
168 | 168 |
169 // Right operand (x) is already a string. | 169 // Right operand (y) is already a string. |
170 function STRING_ADD_RIGHT(x) { | 170 function STRING_ADD_RIGHT(y) { |
171 var a = %ToString(%ToPrimitive(this, NO_HINT)); | 171 var x = IS_STRING(this) ? this : %ToString(%ToPrimitive(this, NO_HINT)); |
172 return %StringAdd(a, x); | 172 return %StringAdd(x, y); |
173 } | 173 } |
174 | 174 |
175 | 175 |
176 // ECMA-262, section 11.6.2, page 50. | 176 // ECMA-262, section 11.6.2, page 50. |
177 function SUB(x) { | 177 function SUB(y) { |
178 return %NumberSub(%ToNumber(this), %ToNumber(x)); | 178 var x = IS_NUMBER(this) ? this : %ToNumber(this); |
| 179 if (!IS_NUMBER(y)) y = %ToNumber(y); |
| 180 return %NumberSub(x, y); |
179 } | 181 } |
180 | 182 |
181 | 183 |
182 // ECMA-262, section 11.5.1, page 48. | 184 // ECMA-262, section 11.5.1, page 48. |
183 function MUL(x) { | 185 function MUL(y) { |
184 return %NumberMul(%ToNumber(this), %ToNumber(x)); | 186 var x = IS_NUMBER(this) ? this : %ToNumber(this); |
| 187 if (!IS_NUMBER(y)) y = %ToNumber(y); |
| 188 return %NumberMul(x, y); |
185 } | 189 } |
186 | 190 |
187 | 191 |
188 // ECMA-262, section 11.5.2, page 49. | 192 // ECMA-262, section 11.5.2, page 49. |
189 function DIV(x) { | 193 function DIV(y) { |
190 return %NumberDiv(%ToNumber(this), %ToNumber(x)); | 194 var x = IS_NUMBER(this) ? this : %ToNumber(this); |
| 195 if (!IS_NUMBER(y)) y = %ToNumber(y); |
| 196 return %NumberDiv(x, y); |
191 } | 197 } |
192 | 198 |
193 | 199 |
194 // ECMA-262, section 11.5.3, page 49. | 200 // ECMA-262, section 11.5.3, page 49. |
195 function MOD(x) { | 201 function MOD(y) { |
196 return %NumberMod(%ToNumber(this), %ToNumber(x)); | 202 var x = IS_NUMBER(this) ? this : %ToNumber(this); |
| 203 if (!IS_NUMBER(y)) y = %ToNumber(y); |
| 204 return %NumberMod(x, y); |
197 } | 205 } |
198 | 206 |
199 | 207 |
200 | 208 |
201 /* ------------------------------------------- | 209 /* ------------------------------------------- |
202 - - - B i t o p e r a t i o n s - - - | 210 - - - B i t o p e r a t i o n s - - - |
203 ------------------------------------------- | 211 ------------------------------------------- |
204 */ | 212 */ |
205 | 213 |
206 // ECMA-262, section 11.10, page 57. | 214 // ECMA-262, section 11.10, page 57. |
207 function BIT_OR(x) { | 215 function BIT_OR(y) { |
208 return %NumberOr(%ToNumber(this), %ToNumber(x)); | 216 var x = IS_NUMBER(this) ? this : %ToNumber(this); |
| 217 if (!IS_NUMBER(y)) y = %ToNumber(y); |
| 218 return %NumberOr(x, y); |
209 } | 219 } |
210 | 220 |
211 | 221 |
212 // ECMA-262, section 11.10, page 57. | 222 // ECMA-262, section 11.10, page 57. |
213 function BIT_AND(x) { | 223 function BIT_AND(y) { |
214 return %NumberAnd(%ToNumber(this), %ToNumber(x)); | 224 var x; |
| 225 if (IS_NUMBER(this)) { |
| 226 x = this; |
| 227 } else { |
| 228 x = %ToNumber(this); |
| 229 // Optimize for the case where we end up AND'ing a value |
| 230 // that doesn't convert to a number. This is common in |
| 231 // certain benchmarks. |
| 232 if (NUMBER_IS_NAN(x)) return 0; |
| 233 } |
| 234 if (!IS_NUMBER(y)) y = %ToNumber(y); |
| 235 return %NumberAnd(x, y); |
215 } | 236 } |
216 | 237 |
217 | 238 |
218 // ECMA-262, section 11.10, page 57. | 239 // ECMA-262, section 11.10, page 57. |
219 function BIT_XOR(x) { | 240 function BIT_XOR(y) { |
220 return %NumberXor(%ToNumber(this), %ToNumber(x)); | 241 var x = IS_NUMBER(this) ? this : %ToNumber(this); |
| 242 if (!IS_NUMBER(y)) y = %ToNumber(y); |
| 243 return %NumberXor(x, y); |
221 } | 244 } |
222 | 245 |
223 | 246 |
224 // ECMA-262, section 11.4.7, page 47. | 247 // ECMA-262, section 11.4.7, page 47. |
225 function UNARY_MINUS() { | 248 function UNARY_MINUS() { |
226 return %NumberUnaryMinus(%ToNumber(this)); | 249 var x = IS_NUMBER(this) ? this : %ToNumber(this); |
| 250 return %NumberUnaryMinus(x); |
227 } | 251 } |
228 | 252 |
229 | 253 |
230 // ECMA-262, section 11.4.8, page 48. | 254 // ECMA-262, section 11.4.8, page 48. |
231 function BIT_NOT() { | 255 function BIT_NOT() { |
232 return %NumberNot(%ToNumber(this)); | 256 var x = IS_NUMBER(this) ? this : %ToNumber(this); |
| 257 return %NumberNot(x); |
233 } | 258 } |
234 | 259 |
235 | 260 |
236 // ECMA-262, section 11.7.1, page 51. | 261 // ECMA-262, section 11.7.1, page 51. |
237 function SHL(x) { | 262 function SHL(y) { |
238 return %NumberShl(%ToNumber(this), %ToNumber(x)); | 263 var x = IS_NUMBER(this) ? this : %ToNumber(this); |
| 264 if (!IS_NUMBER(y)) y = %ToNumber(y); |
| 265 return %NumberShl(x, y); |
239 } | 266 } |
240 | 267 |
241 | 268 |
242 // ECMA-262, section 11.7.2, page 51. | 269 // ECMA-262, section 11.7.2, page 51. |
243 function SAR(x) { | 270 function SAR(y) { |
244 return %NumberSar(%ToNumber(this), %ToNumber(x)); | 271 var x; |
| 272 if (IS_NUMBER(this)) { |
| 273 x = this; |
| 274 } else { |
| 275 x = %ToNumber(this); |
| 276 // Optimize for the case where we end up shifting a value |
| 277 // that doesn't convert to a number. This is common in |
| 278 // certain benchmarks. |
| 279 if (NUMBER_IS_NAN(x)) return 0; |
| 280 } |
| 281 if (!IS_NUMBER(y)) y = %ToNumber(y); |
| 282 return %NumberSar(x, y); |
245 } | 283 } |
246 | 284 |
247 | 285 |
248 // ECMA-262, section 11.7.3, page 52. | 286 // ECMA-262, section 11.7.3, page 52. |
249 function SHR(x) { | 287 function SHR(y) { |
250 return %NumberShr(%ToNumber(this), %ToNumber(x)); | 288 var x = IS_NUMBER(this) ? this : %ToNumber(this); |
| 289 if (!IS_NUMBER(y)) y = %ToNumber(y); |
| 290 return %NumberShr(x, y); |
251 } | 291 } |
252 | 292 |
253 | 293 |
254 | 294 |
255 /* ----------------------------- | 295 /* ----------------------------- |
256 - - - H e l p e r s - - - | 296 - - - H e l p e r s - - - |
257 ----------------------------- | 297 ----------------------------- |
258 */ | 298 */ |
259 | 299 |
260 // ECMA-262, section 11.4.1, page 46. | 300 // ECMA-262, section 11.4.1, page 46. |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 throw %MakeTypeError('cannot_convert_to_primitive', []); | 568 throw %MakeTypeError('cannot_convert_to_primitive', []); |
529 } | 569 } |
530 | 570 |
531 | 571 |
532 // NOTE: Setting the prototype for Array must take place as early as | 572 // NOTE: Setting the prototype for Array must take place as early as |
533 // possible due to code generation for array literals. When | 573 // possible due to code generation for array literals. When |
534 // generating code for a array literal a boilerplate array is created | 574 // generating code for a array literal a boilerplate array is created |
535 // that is cloned when running the code. It is essiential that the | 575 // that is cloned when running the code. It is essiential that the |
536 // boilerplate gets the right prototype. | 576 // boilerplate gets the right prototype. |
537 %FunctionSetPrototype($Array, new $Array(0)); | 577 %FunctionSetPrototype($Array, new $Array(0)); |
OLD | NEW |