Check the return value of API calls on ia32 and x64.
This implies that the return value of native getters is checked. The nice part is that one can even see the name of the property in question in the abort output when the check failed. Under some circumstances even the return value of interceptors gets checked, but I'm not 100% sure about this, because the interceptor code is basically tuned to death. The change seems to have very low overhead, so it might be feasible to keep this check enabled unconditionally. Review URL: https://chromiumcodereview.appspot.com/10918071 Patch from Sven Panne <svenpanne@chromium.org>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12446 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
fe5ce826c8
commit
5330f5b24f
@ -1939,6 +1939,42 @@ void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
|
||||
cmp(Operand::StaticVariable(scheduled_exception_address),
|
||||
Immediate(isolate()->factory()->the_hole_value()));
|
||||
j(not_equal, &promote_scheduled_exception);
|
||||
|
||||
#if ENABLE_EXTRA_CHECKS
|
||||
// Check if the function returned a valid JavaScript value.
|
||||
Label ok;
|
||||
Register return_value = eax;
|
||||
Register map = ecx;
|
||||
|
||||
JumpIfSmi(return_value, &ok, Label::kNear);
|
||||
mov(map, FieldOperand(return_value, HeapObject::kMapOffset));
|
||||
|
||||
CmpInstanceType(map, FIRST_NONSTRING_TYPE);
|
||||
j(below, &ok, Label::kNear);
|
||||
|
||||
CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
|
||||
j(above_equal, &ok, Label::kNear);
|
||||
|
||||
cmp(map, isolate()->factory()->heap_number_map());
|
||||
j(equal, &ok, Label::kNear);
|
||||
|
||||
cmp(return_value, isolate()->factory()->undefined_value());
|
||||
j(equal, &ok, Label::kNear);
|
||||
|
||||
cmp(return_value, isolate()->factory()->true_value());
|
||||
j(equal, &ok, Label::kNear);
|
||||
|
||||
cmp(return_value, isolate()->factory()->false_value());
|
||||
j(equal, &ok, Label::kNear);
|
||||
|
||||
cmp(return_value, isolate()->factory()->null_value());
|
||||
j(equal, &ok, Label::kNear);
|
||||
|
||||
Abort("API call returned invalid object");
|
||||
|
||||
bind(&ok);
|
||||
#endif
|
||||
|
||||
LeaveApiExitFrame();
|
||||
ret(stack_space * kPointerSize);
|
||||
|
||||
|
@ -210,7 +210,20 @@ MaybeObject* JSObject::GetPropertyWithCallback(Object* receiver,
|
||||
if (result.IsEmpty()) {
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
return *v8::Utils::OpenHandle(*result);
|
||||
Object* return_value = *v8::Utils::OpenHandle(*result);
|
||||
#if ENABLE_EXTRA_CHECKS
|
||||
if (!(return_value->IsSmi() ||
|
||||
return_value->IsString() ||
|
||||
return_value->IsSpecObject() ||
|
||||
return_value->IsHeapNumber() ||
|
||||
return_value->IsUndefined() ||
|
||||
return_value->IsTrue() ||
|
||||
return_value->IsFalse() ||
|
||||
return_value->IsNull())) {
|
||||
FATAL("API call returned invalid object");
|
||||
}
|
||||
#endif
|
||||
return return_value;
|
||||
}
|
||||
|
||||
// __defineGetter__ callback
|
||||
|
@ -751,6 +751,41 @@ void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
|
||||
Cmp(Operand(rsi, 0), factory->the_hole_value());
|
||||
j(not_equal, &promote_scheduled_exception);
|
||||
|
||||
#if ENABLE_EXTRA_CHECKS
|
||||
// Check if the function returned a valid JavaScript value.
|
||||
Label ok;
|
||||
Register return_value = rax;
|
||||
Register map = rcx;
|
||||
|
||||
JumpIfSmi(return_value, &ok, Label::kNear);
|
||||
movq(map, FieldOperand(return_value, HeapObject::kMapOffset));
|
||||
|
||||
CmpInstanceType(map, FIRST_NONSTRING_TYPE);
|
||||
j(below, &ok, Label::kNear);
|
||||
|
||||
CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
|
||||
j(above_equal, &ok, Label::kNear);
|
||||
|
||||
CompareRoot(map, Heap::kHeapNumberMapRootIndex);
|
||||
j(equal, &ok, Label::kNear);
|
||||
|
||||
CompareRoot(return_value, Heap::kUndefinedValueRootIndex);
|
||||
j(equal, &ok, Label::kNear);
|
||||
|
||||
CompareRoot(return_value, Heap::kTrueValueRootIndex);
|
||||
j(equal, &ok, Label::kNear);
|
||||
|
||||
CompareRoot(return_value, Heap::kFalseValueRootIndex);
|
||||
j(equal, &ok, Label::kNear);
|
||||
|
||||
CompareRoot(return_value, Heap::kNullValueRootIndex);
|
||||
j(equal, &ok, Label::kNear);
|
||||
|
||||
Abort("API call returned invalid object");
|
||||
|
||||
bind(&ok);
|
||||
#endif
|
||||
|
||||
LeaveApiExitFrame();
|
||||
ret(stack_space * kPointerSize);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user