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

Side by Side Diff: src/runtime.cc

Issue 661369: Builtin function EQULAS partially rewritten in C++. Control branches that cal... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « src/runtime.h ('k') | src/runtime.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 3658 matching lines...) Expand 10 before | Expand all | Expand 10 after
3669 case JS_FUNCTION_TYPE: case JS_REGEXP_TYPE: 3669 case JS_FUNCTION_TYPE: case JS_REGEXP_TYPE:
3670 return Heap::function_symbol(); 3670 return Heap::function_symbol();
3671 default: 3671 default:
3672 // For any kind of object not handled above, the spec rule for 3672 // For any kind of object not handled above, the spec rule for
3673 // host objects gives that it is okay to return "object" 3673 // host objects gives that it is okay to return "object"
3674 return Heap::object_symbol(); 3674 return Heap::object_symbol();
3675 } 3675 }
3676 } 3676 }
3677 3677
3678 3678
3679 static double StringToNumber(String* subject) {
3680 subject->TryFlatten();
3681 return StringToDouble(subject, ALLOW_HEX);
3682 }
3683
3684
3679 static Object* Runtime_StringToNumber(Arguments args) { 3685 static Object* Runtime_StringToNumber(Arguments args) {
3680 NoHandleAllocation ha; 3686 NoHandleAllocation ha;
3681 ASSERT(args.length() == 1); 3687 ASSERT(args.length() == 1);
3682 CONVERT_CHECKED(String, subject, args[0]); 3688 CONVERT_CHECKED(String, subject, args[0]);
3683 subject->TryFlatten(); 3689 return Heap::NumberFromDouble(StringToNumber(subject));
3684 return Heap::NumberFromDouble(StringToDouble(subject, ALLOW_HEX));
3685 } 3690 }
3686 3691
3687 3692
3688 static Object* Runtime_StringFromCharCodeArray(Arguments args) { 3693 static Object* Runtime_StringFromCharCodeArray(Arguments args) {
3689 NoHandleAllocation ha; 3694 NoHandleAllocation ha;
3690 ASSERT(args.length() == 1); 3695 ASSERT(args.length() == 1);
3691 3696
3692 CONVERT_CHECKED(JSArray, codes, args[0]); 3697 CONVERT_CHECKED(JSArray, codes, args[0]);
3693 int length = Smi::cast(codes->length())->value(); 3698 int length = Smi::cast(codes->length())->value();
3694 3699
(...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after
4491 static Object* Runtime_NumberSar(Arguments args) { 4496 static Object* Runtime_NumberSar(Arguments args) {
4492 NoHandleAllocation ha; 4497 NoHandleAllocation ha;
4493 ASSERT(args.length() == 2); 4498 ASSERT(args.length() == 2);
4494 4499
4495 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); 4500 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
4496 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); 4501 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
4497 return Heap::NumberFromInt32(ArithmeticShiftRight(x, y & 0x1f)); 4502 return Heap::NumberFromInt32(ArithmeticShiftRight(x, y & 0x1f));
4498 } 4503 }
4499 4504
4500 4505
4501 static Object* Runtime_NumberEquals(Arguments args) { 4506 static Object* NumberEquals(double x, double y) {
4502 NoHandleAllocation ha;
4503 ASSERT(args.length() == 2);
4504
4505 CONVERT_DOUBLE_CHECKED(x, args[0]);
4506 CONVERT_DOUBLE_CHECKED(y, args[1]);
4507 if (isnan(x)) return Smi::FromInt(NOT_EQUAL); 4507 if (isnan(x)) return Smi::FromInt(NOT_EQUAL);
4508 if (isnan(y)) return Smi::FromInt(NOT_EQUAL); 4508 if (isnan(y)) return Smi::FromInt(NOT_EQUAL);
4509 if (x == y) return Smi::FromInt(EQUAL); 4509 if (x == y) return Smi::FromInt(EQUAL);
4510 Object* result; 4510 Object* result;
4511 if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) { 4511 if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
4512 result = Smi::FromInt(EQUAL); 4512 result = Smi::FromInt(EQUAL);
4513 } else { 4513 } else {
4514 result = Smi::FromInt(NOT_EQUAL); 4514 result = Smi::FromInt(NOT_EQUAL);
4515 } 4515 }
4516 return result; 4516 return result;
4517 } 4517 }
4518 4518
4519 4519
4520 static Object* Runtime_StringEquals(Arguments args) { 4520 static Object* Runtime_NumberEquals(Arguments args) {
4521 NoHandleAllocation ha; 4521 NoHandleAllocation ha;
4522 ASSERT(args.length() == 2); 4522 ASSERT(args.length() == 2);
4523 4523
4524 CONVERT_CHECKED(String, x, args[0]); 4524 CONVERT_DOUBLE_CHECKED(x, args[0]);
4525 CONVERT_CHECKED(String, y, args[1]); 4525 CONVERT_DOUBLE_CHECKED(y, args[1]);
4526 return NumberEquals(x, y);
4527 }
4526 4528
4529
4530 static Object* StringEquals(String* x, String* y) {
4527 bool not_equal = !x->Equals(y); 4531 bool not_equal = !x->Equals(y);
4528 // This is slightly convoluted because the value that signifies 4532 // This is slightly convoluted because the value that signifies
4529 // equality is 0 and inequality is 1 so we have to negate the result 4533 // equality is 0 and inequality is 1 so we have to negate the result
4530 // from String::Equals. 4534 // from String::Equals.
4531 ASSERT(not_equal == 0 || not_equal == 1); 4535 ASSERT(not_equal == 0 || not_equal == 1);
4532 STATIC_CHECK(EQUAL == 0); 4536 STATIC_CHECK(EQUAL == 0);
4533 STATIC_CHECK(NOT_EQUAL == 1); 4537 STATIC_CHECK(NOT_EQUAL == 1);
4534 return Smi::FromInt(not_equal); 4538 return Smi::FromInt(not_equal);
4535 } 4539 }
4536 4540
4537 4541
4542 static Object* Runtime_StringEquals(Arguments args) {
4543 NoHandleAllocation ha;
4544 ASSERT(args.length() == 2);
4545
4546 CONVERT_CHECKED(String, x, args[0]);
4547 CONVERT_CHECKED(String, y, args[1]);
4548
4549 return StringEquals(x, y);
4550 }
4551
4552
4538 static Object* Runtime_NumberCompare(Arguments args) { 4553 static Object* Runtime_NumberCompare(Arguments args) {
4539 NoHandleAllocation ha; 4554 NoHandleAllocation ha;
4540 ASSERT(args.length() == 3); 4555 ASSERT(args.length() == 3);
4541 4556
4542 CONVERT_DOUBLE_CHECKED(x, args[0]); 4557 CONVERT_DOUBLE_CHECKED(x, args[0]);
4543 CONVERT_DOUBLE_CHECKED(y, args[1]); 4558 CONVERT_DOUBLE_CHECKED(y, args[1]);
4544 if (isnan(x) || isnan(y)) return args[2]; 4559 if (isnan(x) || isnan(y)) return args[2];
4545 if (x == y) return Smi::FromInt(EQUAL); 4560 if (x == y) return Smi::FromInt(EQUAL);
4546 if (isless(x, y)) return Smi::FromInt(LESS); 4561 if (isless(x, y)) return Smi::FromInt(LESS);
4547 return Smi::FromInt(GREATER); 4562 return Smi::FromInt(GREATER);
(...skipping 3798 matching lines...) Expand 10 before | Expand all | Expand 10 after
8346 Logger::LogRuntime(chars, elms); 8361 Logger::LogRuntime(chars, elms);
8347 return Heap::undefined_value(); 8362 return Heap::undefined_value();
8348 } 8363 }
8349 8364
8350 8365
8351 static Object* Runtime_IS_VAR(Arguments args) { 8366 static Object* Runtime_IS_VAR(Arguments args) {
8352 UNREACHABLE(); // implemented as macro in the parser 8367 UNREACHABLE(); // implemented as macro in the parser
8353 return NULL; 8368 return NULL;
8354 } 8369 }
8355 8370
8371 static inline Object* StrictObjectEquals(Object* x, Object* y) {
8372 return (x == y) ? Smi::FromInt(EQUAL) : Smi::FromInt(NOT_EQUAL);
8373 }
8374
8375
8376 // Equivalent of JS 'x == null'.
8377 static bool EqualsToNull(Object* x) {
8378 return x->IsNull() || x->IsUndefined() || x->IsUndetectableObject();
8379 }
8380
8381
8382 static double BooleanToNumber(Object* x) {
8383 return x->IsTrue() ? 1 : 0;
8384 }
8385
8386
8387 static double ObjectToNumber(Object* x, bool* supported) {
8388 if (x->IsNumber()) {
8389 return x->Number();
8390 } else if (x->IsString()) {
8391 return StringToNumber(String::cast(x));
8392 } else if (x->IsBoolean()) {
8393 return BooleanToNumber(x);
8394 } else if (x->IsUndefined()) {
8395 return OS::nan_value();
8396 } else if (EqualsToNull(x)) {
8397 return 0;
8398 } else {
8399 *supported = false;
8400 return 0;
8401 }
8402 }
8403
8404
8405 static Object* Runtime_FastEquals(Arguments args) {
8406 // Partial implementation of the compare operations.
8407 // Returns EQUAL, NOT_EQUAL or a special case code which must be handled
8408 // in a builting function EQUAL (comparisons implying calling custom JS
8409 // code difficult to handle in C).
8410
8411 const int EQUALS_FIRST_ARG_TO_PRIMITIVE = 2;
8412 const int EQUALS_SECOND_ARG_TO_PRIMITIVE = 3;
8413 const int EQUALS_SECOND_ARG_TO_DEFAULT_VALUE = 4;
8414
8415 NoHandleAllocation ha;
8416 AssertNoAllocation na();
8417 Object* x = args[0];
8418 Object* y = args[1];
8419
8420 if (EqualsToNull(x)) {
8421 // NOTE: This checks for null, undefined and undetactable.
8422 // Undetactable check must be before string check.
8423 return EqualsToNull(y) ? Smi::FromInt(EQUAL) : Smi::FromInt(NOT_EQUAL);
8424 } else if (x->IsString()) {
8425 if (y->IsString()) return StringEquals(String::cast(x), String::cast(y));
8426 if (y->IsNumber()) {
8427 double dx = StringToNumber(String::cast(x)); // Type checked above.
8428 return NumberEquals(dx, y->Number());
8429 }
8430 if (y->IsBoolean()) {
8431 double dx = StringToNumber(String::cast(x)); // Type checked above.
8432 double dy = BooleanToNumber(y);
8433 return NumberEquals(dx, dy);
8434 }
8435 if (EqualsToNull(y)) {
8436 return Smi::FromInt(NOT_EQUAL);
8437 }
8438
8439 // Speclal case: y = %ToPrimitive(y, NO_HINT) and repeat.
8440 return Smi::FromInt(EQUALS_SECOND_ARG_TO_PRIMITIVE);
8441 } else if (x->IsNumber()) {
8442 if (EqualsToNull(y)) return Smi::FromInt(NOT_EQUAL);
8443 bool supported = true;
8444 double dy = ObjectToNumber(y, &supported); // y is not null.
8445 if (!supported) return Smi::FromInt(EQUALS_SECOND_ARG_TO_DEFAULT_VALUE);
8446 return NumberEquals(x->Number(), dy);
8447 } else if (x->IsBoolean()) {
8448 if (y->IsBoolean()) {
8449 return StrictObjectEquals(x, y);
8450 }
8451 if (EqualsToNull(y)) return Smi::FromInt(NOT_EQUAL);
8452 double dx = BooleanToNumber(x); // Type checked above.
8453 bool supported = true;
8454 double dy = ObjectToNumber(y, &supported);
8455 if (!supported) return Smi::FromInt(EQUALS_SECOND_ARG_TO_DEFAULT_VALUE);
8456 return NumberEquals(dx, dy);
8457 } else {
8458 // x is not a number, boolean, null or undefined.
8459 if (EqualsToNull(y)) return Smi::FromInt(NOT_EQUAL);
8460 if (y->IsJSObject()) {
8461 return StrictObjectEquals(x, y);
8462 }
8463 if (y->IsJSFunction()) {
8464 return StrictObjectEquals(x, y);
8465 }
8466
8467 // Speclal case: x = %ToPrimitive(x, NO_HINT) and repeat.
8468 return Smi::FromInt(EQUALS_FIRST_ARG_TO_PRIMITIVE);
8469 }
8470 }
8471
8356 8472
8357 // ---------------------------------------------------------------------------- 8473 // ----------------------------------------------------------------------------
8358 // Implementation of Runtime 8474 // Implementation of Runtime
8359 8475
8360 #define F(name, nargs, ressize) \ 8476 #define F(name, nargs, ressize) \
8361 { #name, FUNCTION_ADDR(Runtime_##name), nargs, \ 8477 { #name, FUNCTION_ADDR(Runtime_##name), nargs, \
8362 static_cast<int>(Runtime::k##name), ressize }, 8478 static_cast<int>(Runtime::k##name), ressize },
8363 8479
8364 static Runtime::Function Runtime_functions[] = { 8480 static Runtime::Function Runtime_functions[] = {
8365 RUNTIME_FUNCTION_LIST(F) 8481 RUNTIME_FUNCTION_LIST(F)
(...skipping 28 matching lines...) Expand all
8394 } else { 8510 } else {
8395 // Handle last resort GC and make sure to allow future allocations 8511 // Handle last resort GC and make sure to allow future allocations
8396 // to grow the heap without causing GCs (if possible). 8512 // to grow the heap without causing GCs (if possible).
8397 Counters::gc_last_resort_from_js.Increment(); 8513 Counters::gc_last_resort_from_js.Increment();
8398 Heap::CollectAllGarbage(false); 8514 Heap::CollectAllGarbage(false);
8399 } 8515 }
8400 } 8516 }
8401 8517
8402 8518
8403 } } // namespace v8::internal 8519 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/runtime.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698