Implement poison pill for non-strict mode function.caller
when caller is strict mode function. Review URL: http://codereview.chromium.org/6713059/ git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7313 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
41c7632a41
commit
7346fbba81
@ -827,6 +827,19 @@ const AccessorDescriptor Accessors::FunctionArguments = {
|
||||
//
|
||||
|
||||
|
||||
static MaybeObject* CheckNonStrictCallerOrThrow(
|
||||
Isolate* isolate,
|
||||
JSFunction* caller) {
|
||||
DisableAssertNoAllocation enable_allocation;
|
||||
if (caller->shared()->strict_mode()) {
|
||||
return isolate->Throw(
|
||||
*isolate->factory()->NewTypeError("strict_caller",
|
||||
HandleVector<Object>(NULL, 0)));
|
||||
}
|
||||
return caller;
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* Accessors::FunctionGetCaller(Object* object, void*) {
|
||||
Isolate* isolate = Isolate::Current();
|
||||
HandleScope scope(isolate);
|
||||
@ -847,14 +860,14 @@ MaybeObject* Accessors::FunctionGetCaller(Object* object, void*) {
|
||||
// frames, e.g. frames for scripts not functions.
|
||||
if (i > 0) {
|
||||
ASSERT(!functions[i - 1]->shared()->is_toplevel());
|
||||
return functions[i - 1];
|
||||
return CheckNonStrictCallerOrThrow(isolate, functions[i - 1]);
|
||||
} else {
|
||||
for (it.Advance(); !it.done(); it.Advance()) {
|
||||
frame = it.frame();
|
||||
functions.Rewind(0);
|
||||
frame->GetFunctions(&functions);
|
||||
if (!functions.last()->shared()->is_toplevel()) {
|
||||
return functions.last();
|
||||
return CheckNonStrictCallerOrThrow(isolate, functions.last());
|
||||
}
|
||||
ASSERT(functions.length() == 1);
|
||||
}
|
||||
|
@ -234,6 +234,7 @@ function FormatMessage(message) {
|
||||
strict_arguments_caller: ["Cannot access property 'caller' of strict mode arguments"],
|
||||
strict_function_caller: ["Cannot access property 'caller' of a strict mode function"],
|
||||
strict_function_arguments: ["Cannot access property 'arguments' of a strict mode function"],
|
||||
strict_caller: ["Illegal access to a strict mode caller function."],
|
||||
};
|
||||
}
|
||||
var message_type = %MessageGetType(message);
|
||||
|
@ -1081,3 +1081,54 @@ function CheckPillDescriptor(func, name) {
|
||||
CheckPillDescriptor(args, "caller");
|
||||
CheckPillDescriptor(args, "callee");
|
||||
})();
|
||||
|
||||
|
||||
(function TestNonStrictFunctionCallerPillSimple() {
|
||||
function return_my_caller() {
|
||||
return return_my_caller.caller;
|
||||
}
|
||||
|
||||
function strict() {
|
||||
"use strict";
|
||||
return_my_caller();
|
||||
}
|
||||
assertThrows(strict, TypeError);
|
||||
|
||||
function non_strict() {
|
||||
return return_my_caller();
|
||||
}
|
||||
assertSame(non_strict(), non_strict);
|
||||
})();
|
||||
|
||||
|
||||
(function TestNonStrictFunctionCallerPill() {
|
||||
function strict(n) {
|
||||
"use strict";
|
||||
non_strict(n);
|
||||
}
|
||||
|
||||
function recurse(n, then) {
|
||||
if (n > 0) {
|
||||
recurse(n - 1);
|
||||
} else {
|
||||
return then();
|
||||
}
|
||||
}
|
||||
|
||||
function non_strict(n) {
|
||||
recurse(n, function() { non_strict.caller; });
|
||||
}
|
||||
|
||||
function test(n) {
|
||||
try {
|
||||
recurse(n, function() { strict(n); });
|
||||
} catch(e) {
|
||||
return e instanceof TypeError;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < 10; i ++) {
|
||||
assertEquals(test(i), true);
|
||||
}
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user