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.