Push version 3.0.3 to trunk.

Reapplied all changes for version 3.0.1.

Improved debugger protocol for remote debugging.

Added experimental support for using gyp to generate build files for V8.

Fixed implementation of String::Write in the API (issue 975).


git-svn-id: http://v8.googlecode.com/svn/trunk@6061 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/assembler.cc b/src/assembler.cc
index d71a35a..3b44efa 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -66,6 +66,7 @@
 
 const double DoubleConstant::min_int = kMinInt;
 const double DoubleConstant::one_half = 0.5;
+const double DoubleConstant::negative_infinity = -V8_INFINITY;
 
 
 // -----------------------------------------------------------------------------
@@ -722,6 +723,12 @@
 }
 
 
+ExternalReference ExternalReference::address_of_negative_infinity() {
+  return ExternalReference(reinterpret_cast<void*>(
+      const_cast<double*>(&DoubleConstant::negative_infinity)));
+}
+
+
 #ifndef V8_INTERPRETED_REGEXP
 
 ExternalReference ExternalReference::re_check_stack_guard_state() {
@@ -793,6 +800,51 @@
 }
 
 
+// Helper function to compute x^y, where y is known to be an
+// integer. Uses binary decomposition to limit the number of
+// multiplications; see the discussion in "Hacker's Delight" by Henry
+// S. Warren, Jr., figure 11-6, page 213.
+double power_double_int(double x, int y) {
+  double m = (y < 0) ? 1 / x : x;
+  unsigned n = (y < 0) ? -y : y;
+  double p = 1;
+  while (n != 0) {
+    if ((n & 1) != 0) p *= m;
+    m *= m;
+    if ((n & 2) != 0) p *= m;
+    m *= m;
+    n >>= 2;
+  }
+  return p;
+}
+
+
+double power_double_double(double x, double y) {
+  int y_int = static_cast<int>(y);
+  if (y == y_int) {
+    return power_double_int(x, y_int);  // Returns 1.0 for exponent 0.
+  }
+  if (!isinf(x)) {
+    if (y == 0.5) return sqrt(x);
+    if (y == -0.5) return 1.0 / sqrt(x);
+  }
+  if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) {
+    return OS::nan_value();
+  }
+  return pow(x, y);
+}
+
+
+ExternalReference ExternalReference::power_double_double_function() {
+  return ExternalReference(Redirect(FUNCTION_ADDR(power_double_double)));
+}
+
+
+ExternalReference ExternalReference::power_double_int_function() {
+  return ExternalReference(Redirect(FUNCTION_ADDR(power_double_int)));
+}
+
+
 static int native_compare_doubles(double y, double x) {
   if (x == y) return EQUAL;
   return x < y ? LESS : GREATER;