Version 2.2.7

Added support for ES5 date time string format to Date.parse.

Performance improvements in the x64 backend.

git-svn-id: http://v8.googlecode.com/svn/trunk@4565 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/runtime.cc b/src/runtime.cc
index 1442b98..0ac0641 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -1450,6 +1450,18 @@
 }
 
 
+static Object* Runtime_FunctionRemovePrototype(Arguments args) {
+  NoHandleAllocation ha;
+  ASSERT(args.length() == 1);
+
+  CONVERT_CHECKED(JSFunction, f, args[0]);
+  Object* obj = f->RemovePrototype();
+  if (obj->IsFailure()) return obj;
+
+  return Heap::undefined_value();
+}
+
+
 static Object* Runtime_FunctionGetScript(Arguments args) {
   HandleScope scope;
   ASSERT(args.length() == 1);
@@ -1523,6 +1535,7 @@
   ASSERT(args.length() == 2);
 
   CONVERT_CHECKED(JSFunction, fun, args[0]);
+  ASSERT(fun->should_have_prototype());
   Object* obj = Accessors::FunctionSetPrototype(fun, args[1], NULL);
   if (obj->IsFailure()) return obj;
   return args[0];  // return TOS
@@ -4212,7 +4225,7 @@
   int length = LocalPrototypeChainLength(*obj);
 
   // Find the number of local properties for each of the objects.
-  int* local_property_count = NewArray<int>(length);
+  ScopedVector<int> local_property_count(length);
   int total_property_count = 0;
   Handle<JSObject> jsproto = obj;
   for (int i = 0; i < length; i++) {
@@ -4265,7 +4278,6 @@
     }
   }
 
-  DeleteArray(local_property_count);
   return *Factory::NewJSArrayWithElements(names);
 }
 
@@ -5399,7 +5411,7 @@
 
   CONVERT_DOUBLE_CHECKED(x, args[0]);
   CONVERT_DOUBLE_CHECKED(y, args[1]);
-  return Heap::NewNumberFromDouble(x / y);
+  return Heap::NumberFromDouble(x / y);
 }
 
 
@@ -5411,8 +5423,8 @@
   CONVERT_DOUBLE_CHECKED(y, args[1]);
 
   x = modulo(x, y);
-  // NewNumberFromDouble may return a Smi instead of a Number object
-  return Heap::NewNumberFromDouble(x);
+  // NumberFromDouble may return a Smi instead of a Number object
+  return Heap::NumberFromDouble(x);
 }
 
 
@@ -6066,7 +6078,8 @@
 
   if (sign && value >= -0.5) return Heap::minus_zero_value();
 
-  return Heap::NumberFromDouble(floor(value + 0.5));
+  // Do not call NumberFromDouble() to avoid extra checks.
+  return Heap::AllocateHeapNumber(floor(value + 0.5));
 }
 
 
@@ -6541,6 +6554,16 @@
   }
 
   Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
+
+  // If function should not have prototype, construction is not allowed. In this
+  // case generated code bailouts here, since function has no initial_map.
+  if (!function->should_have_prototype()) {
+    Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
+    Handle<Object> type_error =
+        Factory::NewTypeError("not_constructor", arguments);
+    return Top::Throw(*type_error);
+  }
+
 #ifdef ENABLE_DEBUGGER_SUPPORT
   // Handle stepping into constructors if step into is active.
   if (Debug::StepInActive()) {
@@ -7749,6 +7772,38 @@
 }
 
 
+static Object* Runtime_SwapElements(Arguments args) {
+  HandleScope handle_scope;
+
+  ASSERT_EQ(3, args.length());
+
+  Handle<Object> object = args.at<Object>(0);
+  Handle<Object> key1 = args.at<Object>(1);
+  Handle<Object> key2 = args.at<Object>(2);
+
+  uint32_t index1, index2;
+  // That must be the most common case.
+  if (object->IsJSObject()
+      && Array::IndexFromObject(*key1, &index1)
+      && Array::IndexFromObject(*key2, &index2)) {
+    Handle<JSObject> jsobject = Handle<JSObject>::cast(object);
+    Handle<Object> tmp1 = GetElement(jsobject, index1);
+    Handle<Object> tmp2 = GetElement(jsobject, index2);
+
+    SetElement(jsobject, index1, tmp2);
+    SetElement(jsobject, index2, tmp1);
+  } else {
+    Handle<Object> tmp1 = GetProperty(object, key1);
+    Handle<Object> tmp2 = GetProperty(object, key2);
+
+    SetProperty(object, key1, tmp2, NONE);
+    SetProperty(object, key2, tmp1, NONE);
+  }
+
+  return Heap::undefined_value();
+}
+
+
 // Returns an array that tells you where in the [0, length) interval an array
 // might have elements.  Can either return keys or intervals.  Keys can have
 // gaps in (undefined).  Intervals can also span over some undefined keys.
@@ -9674,38 +9729,30 @@
   return result;
 }
 
-// Changes the source of the script to a new_source and creates a new
-// script representing the old version of the script source.
+// Changes the source of the script to a new_source.
+// If old_script_name is provided (i.e. is a String), also creates a copy of
+// the script with its original source and sends notification to debugger.
 static Object* Runtime_LiveEditReplaceScript(Arguments args) {
   ASSERT(args.length() == 3);
   HandleScope scope;
   CONVERT_CHECKED(JSValue, original_script_value, args[0]);
   CONVERT_ARG_CHECKED(String, new_source, 1);
-  CONVERT_ARG_CHECKED(String, old_script_name, 2);
-  Handle<Script> original_script =
-      Handle<Script>(Script::cast(original_script_value->value()));
+  Handle<Object> old_script_name(args[2]);
 
-  Handle<String> original_source(String::cast(original_script->source()));
+  CONVERT_CHECKED(Script, original_script_pointer,
+                  original_script_value->value());
+  Handle<Script> original_script(original_script_pointer);
 
-  original_script->set_source(*new_source);
-  Handle<Script> old_script = Factory::NewScript(original_source);
-  old_script->set_name(*old_script_name);
-  old_script->set_line_offset(original_script->line_offset());
-  old_script->set_column_offset(original_script->column_offset());
-  old_script->set_data(original_script->data());
-  old_script->set_type(original_script->type());
-  old_script->set_context_data(original_script->context_data());
-  old_script->set_compilation_type(original_script->compilation_type());
-  old_script->set_eval_from_shared(original_script->eval_from_shared());
-  old_script->set_eval_from_instructions_offset(
-      original_script->eval_from_instructions_offset());
+  Object* old_script = LiveEdit::ChangeScriptSource(original_script,
+                                                    new_source,
+                                                    old_script_name);
 
-  // Drop line ends so that they will be recalculated.
-  original_script->set_line_ends(Heap::undefined_value());
-
-  Debugger::OnAfterCompile(old_script, Debugger::SEND_WHEN_DEBUGGING);
-
-  return *(GetScriptWrapper(old_script));
+  if (old_script->IsScript()) {
+    Handle<Script> script_handle(Script::cast(old_script));
+    return *(GetScriptWrapper(script_handle));
+  } else {
+    return Heap::null_value();
+  }
 }
 
 // Replaces code of SharedFunctionInfo with a new one.
@@ -9721,35 +9768,60 @@
 }
 
 // Connects SharedFunctionInfo to another script.
-static Object* Runtime_LiveEditRelinkFunctionToScript(Arguments args) {
+static Object* Runtime_LiveEditFunctionSetScript(Arguments args) {
   ASSERT(args.length() == 2);
   HandleScope scope;
-  CONVERT_ARG_CHECKED(JSArray, shared_info_array, 0);
-  CONVERT_ARG_CHECKED(JSValue, script_value, 1);
-  Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
+  Handle<Object> function_object(args[0]);
+  Handle<Object> script_object(args[1]);
 
-  LiveEdit::RelinkFunctionToScript(shared_info_array, script);
+  if (function_object->IsJSValue()) {
+    Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
+    if (script_object->IsJSValue()) {
+      CONVERT_CHECKED(Script, script, JSValue::cast(*script_object)->value());
+      script_object = Handle<Object>(script);
+    }
+
+    LiveEdit::SetFunctionScript(function_wrapper, script_object);
+  } else {
+    // Just ignore this. We may not have a SharedFunctionInfo for some functions
+    // and we check it in this function.
+  }
 
   return Heap::undefined_value();
 }
 
+
+// In a code of a parent function replaces original function as embedded object
+// with a substitution one.
+static Object* Runtime_LiveEditReplaceRefToNestedFunction(Arguments args) {
+  ASSERT(args.length() == 3);
+  HandleScope scope;
+
+  CONVERT_ARG_CHECKED(JSValue, parent_wrapper, 0);
+  CONVERT_ARG_CHECKED(JSValue, orig_wrapper, 1);
+  CONVERT_ARG_CHECKED(JSValue, subst_wrapper, 2);
+
+  LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper,
+                                       subst_wrapper);
+
+  return Heap::undefined_value();
+}
+
+
 // Updates positions of a shared function info (first parameter) according
 // to script source change. Text change is described in second parameter as
 // array of groups of 3 numbers:
 // (change_begin, change_end, change_end_new_position).
 // Each group describes a change in text; groups are sorted by change_begin.
-// Returns an array of pairs (new source position, breakpoint_object/array)
-// so that JS side could update positions in breakpoint objects.
 static Object* Runtime_LiveEditPatchFunctionPositions(Arguments args) {
   ASSERT(args.length() == 2);
   HandleScope scope;
   CONVERT_ARG_CHECKED(JSArray, shared_array, 0);
   CONVERT_ARG_CHECKED(JSArray, position_change_array, 1);
 
-  Handle<Object> result =
-      LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
+  LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
 
-  return *result;
+  return Heap::undefined_value();
 }