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

Unified 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, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/runtime.h ('k') | src/runtime.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
===================================================================
--- src/runtime.cc (revision 4001)
+++ src/runtime.cc (working copy)
@@ -3676,12 +3676,17 @@
}
+static double StringToNumber(String* subject) {
+ subject->TryFlatten();
+ return StringToDouble(subject, ALLOW_HEX);
+}
+
+
static Object* Runtime_StringToNumber(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
CONVERT_CHECKED(String, subject, args[0]);
- subject->TryFlatten();
- return Heap::NumberFromDouble(StringToDouble(subject, ALLOW_HEX));
+ return Heap::NumberFromDouble(StringToNumber(subject));
}
@@ -4498,12 +4503,7 @@
}
-static Object* Runtime_NumberEquals(Arguments args) {
- NoHandleAllocation ha;
- ASSERT(args.length() == 2);
-
- CONVERT_DOUBLE_CHECKED(x, args[0]);
- CONVERT_DOUBLE_CHECKED(y, args[1]);
+static Object* NumberEquals(double x, double y) {
if (isnan(x)) return Smi::FromInt(NOT_EQUAL);
if (isnan(y)) return Smi::FromInt(NOT_EQUAL);
if (x == y) return Smi::FromInt(EQUAL);
@@ -4517,13 +4517,17 @@
}
-static Object* Runtime_StringEquals(Arguments args) {
+static Object* Runtime_NumberEquals(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 2);
- CONVERT_CHECKED(String, x, args[0]);
- CONVERT_CHECKED(String, y, args[1]);
+ CONVERT_DOUBLE_CHECKED(x, args[0]);
+ CONVERT_DOUBLE_CHECKED(y, args[1]);
+ return NumberEquals(x, y);
+}
+
+static Object* StringEquals(String* x, String* y) {
bool not_equal = !x->Equals(y);
// This is slightly convoluted because the value that signifies
// equality is 0 and inequality is 1 so we have to negate the result
@@ -4535,6 +4539,17 @@
}
+static Object* Runtime_StringEquals(Arguments args) {
+ NoHandleAllocation ha;
+ ASSERT(args.length() == 2);
+
+ CONVERT_CHECKED(String, x, args[0]);
+ CONVERT_CHECKED(String, y, args[1]);
+
+ return StringEquals(x, y);
+}
+
+
static Object* Runtime_NumberCompare(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 3);
@@ -8353,7 +8368,108 @@
return NULL;
}
+static inline Object* StrictObjectEquals(Object* x, Object* y) {
+ return (x == y) ? Smi::FromInt(EQUAL) : Smi::FromInt(NOT_EQUAL);
+}
+
+// Equivalent of JS 'x == null'.
+static bool EqualsToNull(Object* x) {
+ return x->IsNull() || x->IsUndefined() || x->IsUndetectableObject();
+}
+
+
+static double BooleanToNumber(Object* x) {
+ return x->IsTrue() ? 1 : 0;
+}
+
+
+static double ObjectToNumber(Object* x, bool* supported) {
+ if (x->IsNumber()) {
+ return x->Number();
+ } else if (x->IsString()) {
+ return StringToNumber(String::cast(x));
+ } else if (x->IsBoolean()) {
+ return BooleanToNumber(x);
+ } else if (x->IsUndefined()) {
+ return OS::nan_value();
+ } else if (EqualsToNull(x)) {
+ return 0;
+ } else {
+ *supported = false;
+ return 0;
+ }
+}
+
+
+static Object* Runtime_FastEquals(Arguments args) {
+ // Partial implementation of the compare operations.
+ // Returns EQUAL, NOT_EQUAL or a special case code which must be handled
+ // in a builting function EQUAL (comparisons implying calling custom JS
+ // code difficult to handle in C).
+
+ const int EQUALS_FIRST_ARG_TO_PRIMITIVE = 2;
+ const int EQUALS_SECOND_ARG_TO_PRIMITIVE = 3;
+ const int EQUALS_SECOND_ARG_TO_DEFAULT_VALUE = 4;
+
+ NoHandleAllocation ha;
+ AssertNoAllocation na();
+ Object* x = args[0];
+ Object* y = args[1];
+
+ if (EqualsToNull(x)) {
+ // NOTE: This checks for null, undefined and undetactable.
+ // Undetactable check must be before string check.
+ return EqualsToNull(y) ? Smi::FromInt(EQUAL) : Smi::FromInt(NOT_EQUAL);
+ } else if (x->IsString()) {
+ if (y->IsString()) return StringEquals(String::cast(x), String::cast(y));
+ if (y->IsNumber()) {
+ double dx = StringToNumber(String::cast(x)); // Type checked above.
+ return NumberEquals(dx, y->Number());
+ }
+ if (y->IsBoolean()) {
+ double dx = StringToNumber(String::cast(x)); // Type checked above.
+ double dy = BooleanToNumber(y);
+ return NumberEquals(dx, dy);
+ }
+ if (EqualsToNull(y)) {
+ return Smi::FromInt(NOT_EQUAL);
+ }
+
+ // Speclal case: y = %ToPrimitive(y, NO_HINT) and repeat.
+ return Smi::FromInt(EQUALS_SECOND_ARG_TO_PRIMITIVE);
+ } else if (x->IsNumber()) {
+ if (EqualsToNull(y)) return Smi::FromInt(NOT_EQUAL);
+ bool supported = true;
+ double dy = ObjectToNumber(y, &supported); // y is not null.
+ if (!supported) return Smi::FromInt(EQUALS_SECOND_ARG_TO_DEFAULT_VALUE);
+ return NumberEquals(x->Number(), dy);
+ } else if (x->IsBoolean()) {
+ if (y->IsBoolean()) {
+ return StrictObjectEquals(x, y);
+ }
+ if (EqualsToNull(y)) return Smi::FromInt(NOT_EQUAL);
+ double dx = BooleanToNumber(x); // Type checked above.
+ bool supported = true;
+ double dy = ObjectToNumber(y, &supported);
+ if (!supported) return Smi::FromInt(EQUALS_SECOND_ARG_TO_DEFAULT_VALUE);
+ return NumberEquals(dx, dy);
+ } else {
+ // x is not a number, boolean, null or undefined.
+ if (EqualsToNull(y)) return Smi::FromInt(NOT_EQUAL);
+ if (y->IsJSObject()) {
+ return StrictObjectEquals(x, y);
+ }
+ if (y->IsJSFunction()) {
+ return StrictObjectEquals(x, y);
+ }
+
+ // Speclal case: x = %ToPrimitive(x, NO_HINT) and repeat.
+ return Smi::FromInt(EQUALS_FIRST_ARG_TO_PRIMITIVE);
+ }
+}
+
+
// ----------------------------------------------------------------------------
// Implementation of Runtime
« 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