Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: src/runtime.js

Issue 1333843002: [runtime] Move binary operator fallbacks into the runtime. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: No need for frame states in bytecode handlers. Add test case. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 // This files contains runtime support implemented in JavaScript. 5 // This files contains runtime support implemented in JavaScript.
6 6
7 // CAUTION: Some of the functions specified in this file are called 7 // CAUTION: Some of the functions specified in this file are called
8 // directly from compiled code. These are the functions with names in 8 // directly from compiled code. These are the functions with names in
9 // ALL CAPS. The compiled code passes the first argument in 'this'. 9 // ALL CAPS. The compiled code passes the first argument in 'this'.
10 10
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 throw %make_type_error(kStrongImplicitConversion); 149 throw %make_type_error(kStrongImplicitConversion);
150 } 150 }
151 151
152 152
153 153
154 /* ----------------------------------- 154 /* -----------------------------------
155 - - - A r i t h m e t i c - - - 155 - - - A r i t h m e t i c - - -
156 ----------------------------------- 156 -----------------------------------
157 */ 157 */
158 158
159 // ECMA-262, section 11.6.1, page 50.
160 function ADD(x) {
161 // Fast case: Check for number operands and do the addition.
162 if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x);
163 if (IS_STRING(this) && IS_STRING(x)) return %_StringAdd(this, x);
164
165 // Default implementation.
166 var a = %to_primitive(this, NO_HINT);
167 var b = %to_primitive(x, NO_HINT);
168
169 if (IS_STRING(a)) {
170 return %_StringAdd(a, %to_string_fun(b));
171 } else if (IS_STRING(b)) {
172 return %_StringAdd(%non_string_to_string(a), b);
173 } else {
174 return %NumberAdd(%to_number_fun(a), %to_number_fun(b));
175 }
176 }
177
178
179 // Strong mode ADD throws if an implicit conversion would be performed
180 function ADD_STRONG(x) {
181 if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x);
182 if (IS_STRING(this) && IS_STRING(x)) return %_StringAdd(this, x);
183
184 throw %make_type_error(kStrongImplicitConversion);
185 }
186
187
188 // Left operand (this) is already a string. 159 // Left operand (this) is already a string.
189 function STRING_ADD_LEFT(y) { 160 function STRING_ADD_LEFT(y) {
190 if (!IS_STRING(y)) { 161 if (!IS_STRING(y)) {
191 if (IS_STRING_WRAPPER(y) && %_IsStringWrapperSafeForDefaultValueOf(y)) { 162 if (IS_STRING_WRAPPER(y) && %_IsStringWrapperSafeForDefaultValueOf(y)) {
192 y = %_ValueOf(y); 163 y = %_ValueOf(y);
193 } else { 164 } else {
194 y = IS_NUMBER(y) 165 y = IS_NUMBER(y)
195 ? %_NumberToString(y) 166 ? %_NumberToString(y)
196 : %to_string_fun(%to_primitive(y, NO_HINT)); 167 : %to_string_fun(%to_primitive(y, NO_HINT));
197 } 168 }
(...skipping 11 matching lines...) Expand all
209 } else { 180 } else {
210 x = IS_NUMBER(x) 181 x = IS_NUMBER(x)
211 ? %_NumberToString(x) 182 ? %_NumberToString(x)
212 : %to_string_fun(%to_primitive(x, NO_HINT)); 183 : %to_string_fun(%to_primitive(x, NO_HINT));
213 } 184 }
214 } 185 }
215 return %_StringAdd(x, y); 186 return %_StringAdd(x, y);
216 } 187 }
217 188
218 189
219 // ECMA-262, section 11.6.2, page 50.
220 function SUB(y) {
221 var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
222 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
223 return %NumberSub(x, y);
224 }
225
226
227 // Strong mode SUB throws if an implicit conversion would be performed
228 function SUB_STRONG(y) {
229 if (IS_NUMBER(this) && IS_NUMBER(y)) {
230 return %NumberSub(this, y);
231 }
232 throw %make_type_error(kStrongImplicitConversion);
233 }
234
235
236 // ECMA-262, section 11.5.1, page 48.
237 function MUL(y) {
238 var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
239 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
240 return %NumberMul(x, y);
241 }
242
243
244 // Strong mode MUL throws if an implicit conversion would be performed
245 function MUL_STRONG(y) {
246 if (IS_NUMBER(this) && IS_NUMBER(y)) {
247 return %NumberMul(this, y);
248 }
249 throw %make_type_error(kStrongImplicitConversion);
250 }
251
252
253 // ECMA-262, section 11.5.2, page 49.
254 function DIV(y) {
255 var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
256 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
257 return %NumberDiv(x, y);
258 }
259
260
261 // Strong mode DIV throws if an implicit conversion would be performed
262 function DIV_STRONG(y) {
263 if (IS_NUMBER(this) && IS_NUMBER(y)) {
264 return %NumberDiv(this, y);
265 }
266 throw %make_type_error(kStrongImplicitConversion);
267 }
268
269
270 // ECMA-262, section 11.5.3, page 49.
271 function MOD(y) {
272 var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
273 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
274 return %NumberMod(x, y);
275 }
276
277
278 // Strong mode MOD throws if an implicit conversion would be performed
279 function MOD_STRONG(y) {
280 if (IS_NUMBER(this) && IS_NUMBER(y)) {
281 return %NumberMod(this, y);
282 }
283 throw %make_type_error(kStrongImplicitConversion);
284 }
285
286
287 /* -------------------------------------------
288 - - - B i t o p e r a t i o n s - - -
289 -------------------------------------------
290 */
291
292 // ECMA-262, section 11.10, page 57.
293 function BIT_OR(y) {
294 var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
295 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
296 return %NumberOr(x, y);
297 }
298
299
300 // Strong mode BIT_OR throws if an implicit conversion would be performed
301 function BIT_OR_STRONG(y) {
302 if (IS_NUMBER(this) && IS_NUMBER(y)) {
303 return %NumberOr(this, y);
304 }
305 throw %make_type_error(kStrongImplicitConversion);
306 }
307
308
309 // ECMA-262, section 11.10, page 57.
310 function BIT_AND(y) {
311 var x;
312 if (IS_NUMBER(this)) {
313 x = this;
314 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
315 } else {
316 x = %non_number_to_number(this);
317 // Make sure to convert the right operand to a number before
318 // bailing out in the fast case, but after converting the
319 // left operand. This ensures that valueOf methods on the right
320 // operand are always executed.
321 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
322 // Optimize for the case where we end up AND'ing a value
323 // that doesn't convert to a number. This is common in
324 // certain benchmarks.
325 if (NUMBER_IS_NAN(x)) return 0;
326 }
327 return %NumberAnd(x, y);
328 }
329
330
331 // Strong mode BIT_AND throws if an implicit conversion would be performed
332 function BIT_AND_STRONG(y) {
333 if (IS_NUMBER(this) && IS_NUMBER(y)) {
334 return %NumberAnd(this, y);
335 }
336 throw %make_type_error(kStrongImplicitConversion);
337 }
338
339
340 // ECMA-262, section 11.10, page 57.
341 function BIT_XOR(y) {
342 var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
343 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
344 return %NumberXor(x, y);
345 }
346
347
348 // Strong mode BIT_XOR throws if an implicit conversion would be performed
349 function BIT_XOR_STRONG(y) {
350 if (IS_NUMBER(this) && IS_NUMBER(y)) {
351 return %NumberXor(this, y);
352 }
353 throw %make_type_error(kStrongImplicitConversion);
354 }
355
356
357 // ECMA-262, section 11.7.1, page 51.
358 function SHL(y) {
359 var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
360 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
361 return %NumberShl(x, y);
362 }
363
364
365 // Strong mode SHL throws if an implicit conversion would be performed
366 function SHL_STRONG(y) {
367 if (IS_NUMBER(this) && IS_NUMBER(y)) {
368 return %NumberShl(this, y);
369 }
370 throw %make_type_error(kStrongImplicitConversion);
371 }
372
373
374 // ECMA-262, section 11.7.2, page 51.
375 function SAR(y) {
376 var x;
377 if (IS_NUMBER(this)) {
378 x = this;
379 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
380 } else {
381 x = %non_number_to_number(this);
382 // Make sure to convert the right operand to a number before
383 // bailing out in the fast case, but after converting the
384 // left operand. This ensures that valueOf methods on the right
385 // operand are always executed.
386 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
387 // Optimize for the case where we end up shifting a value
388 // that doesn't convert to a number. This is common in
389 // certain benchmarks.
390 if (NUMBER_IS_NAN(x)) return 0;
391 }
392 return %NumberSar(x, y);
393 }
394
395
396 // Strong mode SAR throws if an implicit conversion would be performed
397 function SAR_STRONG(y) {
398 if (IS_NUMBER(this) && IS_NUMBER(y)) {
399 return %NumberSar(this, y);
400 }
401 throw %make_type_error(kStrongImplicitConversion);
402 }
403
404
405 // ECMA-262, section 11.7.3, page 52.
406 function SHR(y) {
407 var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
408 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
409 return %NumberShr(x, y);
410 }
411
412
413 // Strong mode SHR throws if an implicit conversion would be performed
414 function SHR_STRONG(y) {
415 if (IS_NUMBER(this) && IS_NUMBER(y)) {
416 return %NumberShr(this, y);
417 }
418 throw %make_type_error(kStrongImplicitConversion);
419 }
420
421
422 /* ----------------------------- 190 /* -----------------------------
423 - - - H e l p e r s - - - 191 - - - H e l p e r s - - -
424 ----------------------------- 192 -----------------------------
425 */ 193 */
426 194
427 function CALL_NON_FUNCTION_AS_CONSTRUCTOR() { 195 function CALL_NON_FUNCTION_AS_CONSTRUCTOR() {
428 var delegate = %GetConstructorDelegate(this); 196 var delegate = %GetConstructorDelegate(this);
429 return %Apply(delegate, this, arguments, 0, %_ArgumentsLength()); 197 return %Apply(delegate, this, arguments, 0, %_ArgumentsLength());
430 } 198 }
431 199
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 $sameValue = SameValue; 542 $sameValue = SameValue;
775 $sameValueZero = SameValueZero; 543 $sameValueZero = SameValueZero;
776 $toInteger = ToInteger; 544 $toInteger = ToInteger;
777 $toLength = ToLength; 545 $toLength = ToLength;
778 $toNumber = ToNumber; 546 $toNumber = ToNumber;
779 $toPositiveInteger = ToPositiveInteger; 547 $toPositiveInteger = ToPositiveInteger;
780 $toPrimitive = ToPrimitive; 548 $toPrimitive = ToPrimitive;
781 $toString = ToString; 549 $toString = ToString;
782 550
783 %InstallToContext([ 551 %InstallToContext([
784 "add_builtin", ADD,
785 "add_strong_builtin", ADD_STRONG,
786 "apply_prepare_builtin", APPLY_PREPARE, 552 "apply_prepare_builtin", APPLY_PREPARE,
787 "bit_and_builtin", BIT_AND,
788 "bit_and_strong_builtin", BIT_AND_STRONG,
789 "bit_or_builtin", BIT_OR,
790 "bit_or_strong_builtin", BIT_OR_STRONG,
791 "bit_xor_builtin", BIT_XOR,
792 "bit_xor_strong_builtin", BIT_XOR_STRONG,
793 "call_function_proxy_as_constructor_builtin", CALL_FUNCTION_PROXY_AS_CONSTRUCT OR, 553 "call_function_proxy_as_constructor_builtin", CALL_FUNCTION_PROXY_AS_CONSTRUCT OR,
794 "call_non_function_as_constructor_builtin", CALL_NON_FUNCTION_AS_CONSTRUCTOR, 554 "call_non_function_as_constructor_builtin", CALL_NON_FUNCTION_AS_CONSTRUCTOR,
795 "compare_builtin", COMPARE, 555 "compare_builtin", COMPARE,
796 "compare_strong_builtin", COMPARE_STRONG, 556 "compare_strong_builtin", COMPARE_STRONG,
797 "concat_iterable_to_array_builtin", CONCAT_ITERABLE_TO_ARRAY, 557 "concat_iterable_to_array_builtin", CONCAT_ITERABLE_TO_ARRAY,
798 "div_builtin", DIV,
799 "div_strong_builtin", DIV_STRONG,
800 "equals_builtin", EQUALS, 558 "equals_builtin", EQUALS,
801 "mod_builtin", MOD,
802 "mod_strong_builtin", MOD_STRONG,
803 "mul_builtin", MUL,
804 "mul_strong_builtin", MUL_STRONG,
805 "reflect_apply_prepare_builtin", REFLECT_APPLY_PREPARE, 559 "reflect_apply_prepare_builtin", REFLECT_APPLY_PREPARE,
806 "reflect_construct_prepare_builtin", REFLECT_CONSTRUCT_PREPARE, 560 "reflect_construct_prepare_builtin", REFLECT_CONSTRUCT_PREPARE,
807 "sar_builtin", SAR,
808 "sar_strong_builtin", SAR_STRONG,
809 "shl_builtin", SHL,
810 "shl_strong_builtin", SHL_STRONG,
811 "shr_builtin", SHR,
812 "shr_strong_builtin", SHR_STRONG,
813 "stack_overflow_builtin", STACK_OVERFLOW, 561 "stack_overflow_builtin", STACK_OVERFLOW,
814 "string_add_left_builtin", STRING_ADD_LEFT, 562 "string_add_left_builtin", STRING_ADD_LEFT,
815 "string_add_right_builtin", STRING_ADD_RIGHT, 563 "string_add_right_builtin", STRING_ADD_RIGHT,
816 "sub_builtin", SUB,
817 "sub_strong_builtin", SUB_STRONG,
818 ]); 564 ]);
819 565
820 %InstallToContext([ 566 %InstallToContext([
821 "concat_iterable_to_array", ConcatIterableToArray, 567 "concat_iterable_to_array", ConcatIterableToArray,
822 "non_number_to_number", NonNumberToNumber, 568 "non_number_to_number", NonNumberToNumber,
823 "non_string_to_string", NonStringToString, 569 "non_string_to_string", NonStringToString,
824 "to_integer_fun", ToInteger, 570 "to_integer_fun", ToInteger,
825 "to_length_fun", ToLength, 571 "to_length_fun", ToLength,
826 "to_number_fun", ToNumber, 572 "to_number_fun", ToNumber,
827 "to_primitive", ToPrimitive, 573 "to_primitive", ToPrimitive,
828 "to_string_fun", ToString, 574 "to_string_fun", ToString,
829 ]); 575 ]);
830 576
831 utils.Export(function(to) { 577 utils.Export(function(to) {
832 to.ToBoolean = ToBoolean; 578 to.ToBoolean = ToBoolean;
833 to.ToLength = ToLength; 579 to.ToLength = ToLength;
834 to.ToNumber = ToNumber; 580 to.ToNumber = ToNumber;
835 to.ToPrimitive = ToPrimitive; 581 to.ToPrimitive = ToPrimitive;
836 to.ToString = ToString; 582 to.ToString = ToString;
837 }); 583 });
838 584
839 }) 585 })
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698