From 5593b956b27de2b7a2ac29389ac691cf0b4cfdd3 Mon Sep 17 00:00:00 2001 From: "rossberg@chromium.org" Date: Fri, 23 Nov 2012 15:47:58 +0000 Subject: [PATCH] Censor .caller if it is a strict function instead of throwing. For details, see: http://www.mail-archive.com/es-discuss@mozilla.org/msg19322.html https://bugs.ecmascript.org/show_bug.cgi?id=310 R=mstarzinger@chromium.org BUG= Review URL: https://codereview.chromium.org/11417140 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13049 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/accessors.cc | 22 ++++++++------------- test/mjsunit/strict-mode.js | 47 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 44 insertions(+), 25 deletions(-) diff --git a/src/accessors.cc b/src/accessors.cc index 855ddb2..a30bfd5 100644 --- a/src/accessors.cc +++ b/src/accessors.cc @@ -649,19 +649,6 @@ const AccessorDescriptor Accessors::FunctionArguments = { // -static MaybeObject* CheckNonStrictCallerOrThrow( - Isolate* isolate, - JSFunction* caller) { - DisableAssertNoAllocation enable_allocation; - if (!caller->shared()->is_classic_mode()) { - return isolate->Throw( - *isolate->factory()->NewTypeError("strict_caller", - HandleVector(NULL, 0))); - } - return caller; -} - - class FrameFunctionIterator { public: FrameFunctionIterator(Isolate* isolate, const AssertNoAllocation& promise) @@ -748,7 +735,14 @@ MaybeObject* Accessors::FunctionGetCaller(Object* object, void*) { if (caller->shared()->bound()) { return isolate->heap()->null_value(); } - return CheckNonStrictCallerOrThrow(isolate, caller); + // Censor if the caller is not a classic mode function. + // Change from ES5, which used to throw, see: + // https://bugs.ecmascript.org/show_bug.cgi?id=310 + if (!caller->shared()->is_classic_mode()) { + return isolate->heap()->null_value(); + } + + return caller; } diff --git a/test/mjsunit/strict-mode.js b/test/mjsunit/strict-mode.js index e13ada4..5fb404a 100644 --- a/test/mjsunit/strict-mode.js +++ b/test/mjsunit/strict-mode.js @@ -1141,9 +1141,9 @@ function CheckPillDescriptor(func, name) { function strict() { "use strict"; - return_my_caller(); + return return_my_caller(); } - assertThrows(strict, TypeError); + assertSame(null, strict()); function non_strict() { return return_my_caller(); @@ -1155,32 +1155,57 @@ function CheckPillDescriptor(func, name) { (function TestNonStrictFunctionCallerPill() { function strict(n) { "use strict"; - non_strict(n); + return non_strict(n); } function recurse(n, then) { if (n > 0) { - recurse(n - 1, then); + return recurse(n - 1, then); } else { return then(); } } function non_strict(n) { - recurse(n, function() { non_strict.caller; }); + return recurse(n, function() { return non_strict.caller; }); } function test(n) { - try { - recurse(n, function() { strict(n); }); - } catch(e) { - return e instanceof TypeError; + return recurse(n, function() { return strict(n); }); + } + + for (var i = 0; i < 10; i ++) { + assertSame(null, test(i)); + } +})(); + + +(function TestNonStrictFunctionCallerDescriptorPill() { + function strict(n) { + "use strict"; + return non_strict(n); + } + + function recurse(n, then) { + if (n > 0) { + return recurse(n - 1, then); + } else { + return then(); } - return false; + } + + function non_strict(n) { + return recurse(n, function() { + return Object.getOwnPropertyDescriptor(non_strict, "caller").value; + }); + } + + function test(n) { + return recurse(n, function() { return strict(n); }); } for (var i = 0; i < 10; i ++) { - assertEquals(test(i), true); + assertSame(null, test(i)); } })(); -- 2.7.4