Revision: 15024
Author:   [email protected]
Date:     Mon Jun 10 00:41:16 2013
Log:      add a default value for return value

[email protected]
BUG=

Review URL: https://codereview.chromium.org/16642003
http://code.google.com/p/v8/source/detail?r=15024

Modified:
 /branches/bleeding_edge/include/v8.h
 /branches/bleeding_edge/src/arguments.h
 /branches/bleeding_edge/src/arm/stub-cache-arm.cc
 /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
 /branches/bleeding_edge/src/x64/stub-cache-x64.cc
 /branches/bleeding_edge/test/cctest/test-api.cc

=======================================
--- /branches/bleeding_edge/include/v8.h        Fri Jun  7 08:02:20 2013
+++ /branches/bleeding_edge/include/v8.h        Mon Jun 10 00:41:16 2013
@@ -2852,6 +2852,7 @@
   template<class F> friend class ReturnValue;
   template<class F> friend class FunctionCallbackInfo;
   template<class F> friend class PropertyCallbackInfo;
+  V8_INLINE(internal::Object* GetDefaultValue());
   V8_INLINE(explicit ReturnValue(internal::Object** slot));
   internal::Object** value_;
 };
@@ -2876,16 +2877,17 @@
   V8_INLINE(Isolate* GetIsolate() const);
   V8_INLINE(ReturnValue<T> GetReturnValue() const);
   // This shouldn't be public, but the arm compiler needs it.
-  static const int kArgsLength = 5;
+  static const int kArgsLength = 6;

  protected:
   friend class internal::FunctionCallbackArguments;
   friend class internal::CustomArguments<FunctionCallbackInfo>;
   static const int kReturnValueIndex = 0;
-  static const int kIsolateIndex = -1;
-  static const int kDataIndex = -2;
-  static const int kCalleeIndex = -3;
-  static const int kHolderIndex = -4;
+  static const int kReturnValueDefaultValueIndex = -1;
+  static const int kIsolateIndex = -2;
+  static const int kDataIndex = -3;
+  static const int kCalleeIndex = -4;
+  static const int kHolderIndex = -5;

   V8_INLINE(FunctionCallbackInfo(internal::Object** implicit_args,
                    internal::Object** values,
@@ -2920,7 +2922,7 @@
   V8_INLINE(Local<Object> Holder() const);
   V8_INLINE(ReturnValue<T> GetReturnValue() const);
   // This shouldn't be public, but the arm compiler needs it.
-  static const int kArgsLength = 5;
+  static const int kArgsLength = 6;

  protected:
   friend class MacroAssembler;
@@ -2930,7 +2932,8 @@
   static const int kHolderIndex = -1;
   static const int kDataIndex = -2;
   static const int kReturnValueIndex = -3;
-  static const int kIsolateIndex = -4;
+  static const int kReturnValueDefaultValueIndex = -4;
+  static const int kIsolateIndex = -5;

   V8_INLINE(PropertyCallbackInfo(internal::Object** args))
       : args_(args) { }
@@ -5658,7 +5661,7 @@
 void ReturnValue<T>::Set(const Persistent<S>& handle) {
   TYPE_CHECK(T, S);
   if (V8_UNLIKELY(handle.IsEmpty())) {
-    SetUndefined();
+    *value_ = GetDefaultValue();
   } else {
     *value_ = *reinterpret_cast<internal::Object**>(*handle);
   }
@@ -5669,7 +5672,7 @@
 void ReturnValue<T>::Set(const Handle<S> handle) {
   TYPE_CHECK(T, S);
   if (V8_UNLIKELY(handle.IsEmpty())) {
-    SetUndefined();
+    *value_ = GetDefaultValue();
   } else {
     *value_ = *reinterpret_cast<internal::Object**>(*handle);
   }
@@ -5728,8 +5731,14 @@

 template<typename T>
 Isolate* ReturnValue<T>::GetIsolate() {
-  // Isolate is always the pointer below value_ on the stack.
-  return *reinterpret_cast<Isolate**>(&value_[-1]);
+  // Isolate is always the pointer below the default value on the stack.
+  return *reinterpret_cast<Isolate**>(&value_[-2]);
+}
+
+template<typename T>
+internal::Object* ReturnValue<T>::GetDefaultValue() {
+  // Default value is always the pointer below value_ on the stack.
+  return value_[-1];
 }


=======================================
--- /branches/bleeding_edge/src/arguments.h     Wed Jun  5 05:36:33 2013
+++ /branches/bleeding_edge/src/arguments.h     Mon Jun 10 00:41:16 2013
@@ -253,6 +253,10 @@
     values[T::kHolderIndex] = holder;
     values[T::kDataIndex] = data;
     values[T::kIsolateIndex] = reinterpret_cast<Object*>(isolate);
+    // Here the hole is set as default value.
+    // It cannot escape into js as it's remove in Call below.
+    values[T::kReturnValueDefaultValueIndex] =
+        isolate->heap()->the_hole_value();
     values[T::kReturnValueIndex] = isolate->heap()->the_hole_value();
     ASSERT(values[T::kHolderIndex]->IsHeapObject());
     ASSERT(values[T::kIsolateIndex]->IsSmi());
@@ -313,6 +317,10 @@
     values[T::kCalleeIndex] = callee;
     values[T::kHolderIndex] = holder;
values[T::kIsolateIndex] = reinterpret_cast<internal::Object*>(isolate);
+    // Here the hole is set as default value.
+    // It cannot escape into js as it's remove in Call below.
+    values[T::kReturnValueDefaultValueIndex] =
+        isolate->heap()->the_hole_value();
     values[T::kReturnValueIndex] = isolate->heap()->the_hole_value();
     ASSERT(values[T::kCalleeIndex]->IsJSFunction());
     ASSERT(values[T::kHolderIndex]->IsHeapObject());
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Wed Jun 5 01:43:25 2013 +++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Mon Jun 10 00:41:16 2013
@@ -893,11 +893,12 @@
   //  -- sp[4]              : callee JS function
   //  -- sp[8]              : call data
   //  -- sp[12]             : isolate
-  //  -- sp[16]             : ReturnValue
-  //  -- sp[20]             : last JS argument
+  //  -- sp[16]             : ReturnValue default value
+  //  -- sp[20]             : ReturnValue
+  //  -- sp[24]             : last JS argument
   //  -- ...
-  //  -- sp[(argc + 4) * 4] : first JS argument
-  //  -- sp[(argc + 5) * 4] : receiver
+  //  -- sp[(argc + 5) * 4] : first JS argument
+  //  -- sp[(argc + 6) * 4] : receiver
   // -----------------------------------
   // Get the function and setup the context.
   Handle<JSFunction> function = optimization.constant_function();
@@ -914,13 +915,14 @@
     __ Move(r6, call_data);
   }
   __ mov(r7, Operand(ExternalReference::isolate_address(masm->isolate())));
-  // Store JS function, call data, isolate and ReturnValue.
+ // Store JS function, call data, isolate ReturnValue default and ReturnValue.
   __ stm(ib, sp, r5.bit() | r6.bit() | r7.bit());
   __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
   __ str(r5, MemOperand(sp, 4 * kPointerSize));
+  __ str(r5, MemOperand(sp, 5 * kPointerSize));

   // Prepare arguments.
-  __ add(r2, sp, Operand(4 * kPointerSize));
+  __ add(r2, sp, Operand(5 * kPointerSize));

   // Allocate the v8::Arguments structure in the arguments' space since
   // it's not controlled by GC.
@@ -1434,9 +1436,11 @@
   }
   __ Push(reg, scratch3());
   __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
+  __ mov(scratch4(), scratch3());
+  __ Push(scratch3(), scratch4());
   __ mov(scratch4(),
          Operand(ExternalReference::isolate_address(isolate())));
-  __ Push(scratch3(), scratch4(), name());
+  __ Push(scratch4(), name());
   __ mov(r0, sp);  // r0 = Handle<Name>

   const int kApiStackSpace = 1;
@@ -1462,7 +1466,7 @@
   __ CallApiFunctionAndReturn(ref,
                               kStackUnwindSpace,
                               returns_handle,
-                              4);
+                              5);
 }


=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Wed Jun 5 01:43:25 2013 +++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Mon Jun 10 00:41:16 2013
@@ -469,11 +469,12 @@
   //                           (first fast api call extra argument)
   //  -- esp[12]             : api call data
   //  -- esp[16]             : isolate
-  //  -- esp[20]             : ReturnValue
-  //  -- esp[24]             : last argument
+  //  -- esp[20]             : ReturnValue default value
+  //  -- esp[24]             : ReturnValue
+  //  -- esp[28]             : last argument
   //  -- ...
-  //  -- esp[(argc + 5) * 4] : first argument
-  //  -- esp[(argc + 6) * 4] : receiver
+  //  -- esp[(argc + 6) * 4] : first argument
+  //  -- esp[(argc + 7) * 4] : receiver
   // -----------------------------------
   // Get the function and setup the context.
   Handle<JSFunction> function = optimization.constant_function();
@@ -495,9 +496,11 @@
          Immediate(reinterpret_cast<int>(masm->isolate())));
   __ mov(Operand(esp, 5 * kPointerSize),
          masm->isolate()->factory()->undefined_value());
+  __ mov(Operand(esp, 6 * kPointerSize),
+         masm->isolate()->factory()->undefined_value());

   // Prepare arguments.
-  STATIC_ASSERT(kFastApiCallArguments == 5);
+  STATIC_ASSERT(kFastApiCallArguments == 6);
   __ lea(eax, Operand(esp, kFastApiCallArguments * kPointerSize));

const int kApiArgc = 1; // API function gets reference to the v8::Arguments.
@@ -1387,6 +1390,8 @@
     __ push(Immediate(Handle<Object>(callback->data(), isolate())));
   }
__ push(Immediate(isolate()->factory()->undefined_value())); // ReturnValue
+  // ReturnValue default value
+  __ push(Immediate(isolate()->factory()->undefined_value()));
   __ push(Immediate(reinterpret_cast<int>(isolate())));

   // Save a pointer to where we pushed the arguments pointer.  This will be
@@ -1420,7 +1425,7 @@
   __ CallApiFunctionAndReturn(getter_address,
                               kStackSpace,
                               returns_handle,
-                              5);
+                              6);
 }


=======================================
--- /branches/bleeding_edge/src/x64/stub-cache-x64.cc Wed Jun 5 01:43:25 2013 +++ /branches/bleeding_edge/src/x64/stub-cache-x64.cc Mon Jun 10 00:41:16 2013
@@ -449,12 +449,13 @@
   //                           (first fast api call extra argument)
   //  -- rsp[24]             : api call data
   //  -- rsp[32]             : isolate
-  //  -- rsp[40]             : ReturnValue
+  //  -- rsp[40]             : ReturnValue default value
+  //  -- rsp[48]             : ReturnValue
   //
-  //  -- rsp[48]             : last argument
+  //  -- rsp[56]             : last argument
   //  -- ...
-  //  -- rsp[(argc + 5) * 8] : first argument
-  //  -- rsp[(argc + 6) * 8] : receiver
+  //  -- rsp[(argc + 6) * 8] : first argument
+  //  -- rsp[(argc + 7) * 8] : receiver
   // -----------------------------------
   // Get the function and setup the context.
   Handle<JSFunction> function = optimization.constant_function();
@@ -477,9 +478,10 @@
   __ movq(Operand(rsp, 4 * kPointerSize), kScratchRegister);
   __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
   __ movq(Operand(rsp, 5 * kPointerSize), kScratchRegister);
+  __ movq(Operand(rsp, 6 * kPointerSize), kScratchRegister);

   // Prepare arguments.
-  STATIC_ASSERT(kFastApiCallArguments == 5);
+  STATIC_ASSERT(kFastApiCallArguments == 6);
   __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize));

   // Function address is a foreign pointer outside V8's heap.
@@ -1305,6 +1307,7 @@
   }
   __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
   __ push(kScratchRegister);  // return value
+  __ push(kScratchRegister);  // return value default
   __ PushAddress(ExternalReference::isolate_address(isolate()));
   __ push(name());  // name
   // Save a pointer to where we pushed the arguments pointer.  This will be
@@ -1337,8 +1340,8 @@
   const int kArgStackSpace = 1;

   __ PrepareCallApiFunction(kArgStackSpace, returns_handle);
-  STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 5);
-  __ lea(rax, Operand(name_arg, 5 * kPointerSize));
+  STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
+  __ lea(rax, Operand(name_arg, 6 * kPointerSize));

   // v8::AccessorInfo::args_.
   __ movq(StackSpaceOperand(0), rax);
@@ -1350,7 +1353,7 @@
   __ CallApiFunctionAndReturn(getter_address,
                               kStackSpace,
                               returns_handle,
-                              4);
+                              5);
 }


=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc     Mon Jun 10 00:34:58 2013
+++ /branches/bleeding_edge/test/cctest/test-api.cc     Mon Jun 10 00:41:16 2013
@@ -810,6 +810,13 @@
   CHECK_EQ(v8::Isolate::GetCurrent(), t.GetIsolate());
   CHECK_EQ(t.GetIsolate(), rv.GetIsolate());
   CHECK((*o)->IsTheHole() || (*o)->IsUndefined());
+  // Verify reset
+  bool is_runtime = (*o)->IsTheHole();
+  rv.Set(true);
+  CHECK(!(*o)->IsTheHole() && !(*o)->IsUndefined());
+  rv.Set(v8::Handle<v8::Object>());
+  CHECK((*o)->IsTheHole() || (*o)->IsUndefined());
+  CHECK_EQ(is_runtime, (*o)->IsTheHole());
 }

 static v8::Handle<Value> handle_call(const v8::Arguments& args) {

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to