Commit 9836c34d authored by caitpotter88's avatar caitpotter88 Committed by Commit bot

[es6] do not add caller/arguments to ES6 function definitions

BUG=v8:3946, v8:3982
CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_chromium_rel_ng;tryserver.blink:linux_blink_rel
LOG=N
R=arv@chromium.org, rossberg@chromium.org

Review URL: https://codereview.chromium.org/1027283004

Cr-Commit-Position: refs/heads/master@{#27729}
parent 806e57f4
This diff is collapsed.
......@@ -1000,22 +1000,23 @@ BUILTIN(ArrayConcat) {
// -----------------------------------------------------------------------------
// Generator and strict mode poison pills
// Throwers for restricted function properties and strict arguments object
// properties
BUILTIN(StrictModePoisonPill) {
BUILTIN(RestrictedFunctionPropertiesThrower) {
HandleScope scope(isolate);
THROW_NEW_ERROR_RETURN_FAILURE(
isolate,
NewTypeError("strict_poison_pill", HandleVector<Object>(NULL, 0)));
THROW_NEW_ERROR_RETURN_FAILURE(isolate,
NewTypeError("restricted_function_properties",
HandleVector<Object>(NULL, 0)));
}
BUILTIN(GeneratorPoisonPill) {
BUILTIN(RestrictedStrictArgumentsPropertiesThrower) {
HandleScope scope(isolate);
THROW_NEW_ERROR_RETURN_FAILURE(
isolate,
NewTypeError("generator_poison_pill", HandleVector<Object>(NULL, 0)));
NewTypeError("strict_poison_pill", HandleVector<Object>(NULL, 0)));
}
......
......@@ -41,26 +41,26 @@ enum BuiltinExtraArguments {
// Define list of builtins implemented in C++.
#define BUILTIN_LIST_C(V) \
V(Illegal, NO_EXTRA_ARGUMENTS) \
\
V(EmptyFunction, NO_EXTRA_ARGUMENTS) \
\
V(ArrayPush, NO_EXTRA_ARGUMENTS) \
V(ArrayPop, NO_EXTRA_ARGUMENTS) \
V(ArrayShift, NO_EXTRA_ARGUMENTS) \
V(ArrayUnshift, NO_EXTRA_ARGUMENTS) \
V(ArraySlice, NO_EXTRA_ARGUMENTS) \
V(ArraySplice, NO_EXTRA_ARGUMENTS) \
V(ArrayConcat, NO_EXTRA_ARGUMENTS) \
\
V(HandleApiCall, NEEDS_CALLED_FUNCTION) \
V(HandleApiCallConstruct, NEEDS_CALLED_FUNCTION) \
V(HandleApiCallAsFunction, NO_EXTRA_ARGUMENTS) \
V(HandleApiCallAsConstructor, NO_EXTRA_ARGUMENTS) \
\
V(StrictModePoisonPill, NO_EXTRA_ARGUMENTS) \
V(GeneratorPoisonPill, NO_EXTRA_ARGUMENTS)
#define BUILTIN_LIST_C(V) \
V(Illegal, NO_EXTRA_ARGUMENTS) \
\
V(EmptyFunction, NO_EXTRA_ARGUMENTS) \
\
V(ArrayPush, NO_EXTRA_ARGUMENTS) \
V(ArrayPop, NO_EXTRA_ARGUMENTS) \
V(ArrayShift, NO_EXTRA_ARGUMENTS) \
V(ArrayUnshift, NO_EXTRA_ARGUMENTS) \
V(ArraySlice, NO_EXTRA_ARGUMENTS) \
V(ArraySplice, NO_EXTRA_ARGUMENTS) \
V(ArrayConcat, NO_EXTRA_ARGUMENTS) \
\
V(HandleApiCall, NEEDS_CALLED_FUNCTION) \
V(HandleApiCallConstruct, NEEDS_CALLED_FUNCTION) \
V(HandleApiCallAsFunction, NO_EXTRA_ARGUMENTS) \
V(HandleApiCallAsConstructor, NO_EXTRA_ARGUMENTS) \
\
V(RestrictedFunctionPropertiesThrower, NO_EXTRA_ARGUMENTS) \
V(RestrictedStrictArgumentsPropertiesThrower, NO_EXTRA_ARGUMENTS)
// Define list of builtins implemented in assembly.
#define BUILTIN_LIST_A(V) \
......
......@@ -582,17 +582,16 @@ class Context: public FixedArray {
}
if (IsConstructor(kind)) {
return is_strong(language_mode) ? STRONG_CONSTRUCTOR_MAP_INDEX :
is_strict(language_mode) ? STRICT_FUNCTION_MAP_INDEX
: SLOPPY_FUNCTION_MAP_INDEX;
// Use strict function map (no own "caller" / "arguments")
return is_strong(language_mode) ? STRONG_CONSTRUCTOR_MAP_INDEX
: STRICT_FUNCTION_MAP_INDEX;
}
if (IsArrowFunction(kind) || IsConciseMethod(kind) ||
IsAccessorFunction(kind)) {
return is_strong(language_mode) ? STRONG_FUNCTION_MAP_INDEX :
is_strict(language_mode) ?
STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX :
SLOPPY_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX;
return is_strong(language_mode)
? STRONG_FUNCTION_MAP_INDEX
: STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX;
}
return is_strong(language_mode) ? STRONG_FUNCTION_MAP_INDEX :
......
......@@ -6,6 +6,7 @@
#include "src/allocation-site-scopes.h"
#include "src/base/bits.h"
#include "src/bootstrapper.h"
#include "src/conversions.h"
#include "src/isolate-inl.h"
#include "src/macro-assembler.h"
......@@ -1280,7 +1281,8 @@ Handle<JSFunction> Factory::NewFunction(Handle<Map> map,
map.is_identical_to(
isolate()->sloppy_function_without_prototype_map()) ||
map.is_identical_to(
isolate()->sloppy_function_with_readonly_prototype_map())));
isolate()->sloppy_function_with_readonly_prototype_map()) ||
map.is_identical_to(isolate()->strict_function_map())));
return NewFunction(map, info, context);
}
......@@ -1292,19 +1294,27 @@ Handle<JSFunction> Factory::NewFunction(Handle<String> name) {
Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name,
Handle<Code> code) {
return NewFunction(
isolate()->sloppy_function_without_prototype_map(), name, code);
Handle<Code> code,
bool is_strict) {
Handle<Map> map = is_strict
? isolate()->strict_function_without_prototype_map()
: isolate()->sloppy_function_without_prototype_map();
return NewFunction(map, name, code);
}
Handle<JSFunction> Factory::NewFunction(Handle<String> name,
Handle<Code> code,
Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code,
Handle<Object> prototype,
bool read_only_prototype) {
Handle<Map> map = read_only_prototype
? isolate()->sloppy_function_with_readonly_prototype_map()
: isolate()->sloppy_function_map();
bool read_only_prototype,
bool is_strict) {
// In strict mode, readonly strict map is only available during bootstrap
DCHECK(!is_strict || !read_only_prototype ||
isolate()->bootstrapper()->IsActive());
Handle<Map> map =
is_strict ? isolate()->strict_function_map()
: read_only_prototype
? isolate()->sloppy_function_with_readonly_prototype_map()
: isolate()->sloppy_function_map();
Handle<JSFunction> result = NewFunction(map, name, code);
result->set_prototype_or_initial_map(*prototype);
return result;
......@@ -1315,10 +1325,11 @@ Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code,
Handle<Object> prototype,
InstanceType type, int instance_size,
bool read_only_prototype,
bool install_constructor) {
bool install_constructor,
bool is_strict) {
// Allocate the function
Handle<JSFunction> function = NewFunction(
name, code, prototype, read_only_prototype);
Handle<JSFunction> function =
NewFunction(name, code, prototype, read_only_prototype, is_strict);
ElementsKind elements_kind =
type == JS_ARRAY_TYPE ? FAST_SMI_ELEMENTS : FAST_HOLEY_SMI_ELEMENTS;
......
......@@ -482,13 +482,14 @@ class Factory FINAL {
void BecomeJSObject(Handle<JSProxy> object);
void BecomeJSFunction(Handle<JSProxy> object);
Handle<JSFunction> NewFunction(Handle<String> name,
Handle<Code> code,
Handle<JSFunction> NewFunction(Handle<String> name, Handle<Code> code,
Handle<Object> prototype,
bool read_only_prototype = false);
bool read_only_prototype = false,
bool is_strict = false);
Handle<JSFunction> NewFunction(Handle<String> name);
Handle<JSFunction> NewFunctionWithoutPrototype(Handle<String> name,
Handle<Code> code);
Handle<Code> code,
bool is_strict = false);
Handle<JSFunction> NewFunctionFromSharedFunctionInfo(
Handle<SharedFunctionInfo> function_info,
......@@ -499,7 +500,8 @@ class Factory FINAL {
Handle<Object> prototype, InstanceType type,
int instance_size,
bool read_only_prototype = false,
bool install_constructor = false);
bool install_constructor = false,
bool is_strict = false);
Handle<JSFunction> NewFunction(Handle<String> name,
Handle<Code> code,
InstanceType type,
......
......@@ -162,6 +162,7 @@ var kMessages = {
strict_function: ["In strict mode code, functions can only be declared at top level or immediately within another function." ],
strict_read_only_property: ["Cannot assign to read only property '", "%0", "' of ", "%1"],
strict_cannot_assign: ["Cannot assign to read only '", "%0", "' in strict mode"],
restricted_function_properties: ["'caller' and 'arguments' are restricted function properties and cannot be accessed in this context."],
strict_poison_pill: ["'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them"],
strict_caller: ["Illegal access to a strict mode caller function."],
strong_ellision: ["In strong mode, arrays with holes are deprecated, use maps instead"],
......@@ -180,7 +181,6 @@ var kMessages = {
strong_constructor_return_misplaced: ["In strong mode, returning from a constructor before its super constructor invocation is deprecated"],
sloppy_lexical: ["Block-scoped declarations (let, const, function, class) not yet supported outside strict mode"],
malformed_arrow_function_parameter_list: ["Malformed arrow function parameter list"],
generator_poison_pill: ["'caller' and 'arguments' properties may not be accessed on generator functions."],
cant_prevent_ext_external_array_elements: ["Cannot prevent extension of an object with external array elements"],
redef_external_array_element: ["Cannot redefine a property of an object with external array elements"],
const_assign: ["Assignment to constant variable."],
......
......@@ -2,39 +2,41 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function assertIteratorResult(value, done, result) {
assertEquals({value: value, done: done}, result);
}
function test(f) {
var cdesc = Object.getOwnPropertyDescriptor(f, "caller");
var adesc = Object.getOwnPropertyDescriptor(f, "arguments");
(function testRestrictedPropertiesStrict() {
function* generator() { "use strict"; }
assertFalse(generator.hasOwnProperty("arguments"));
assertThrows(function() { return generator.arguments; }, TypeError);
assertThrows(function() { return generator.arguments = {}; }, TypeError);
assertFalse(cdesc.enumerable);
assertFalse(cdesc.configurable);
assertFalse(generator.hasOwnProperty("caller"));
assertThrows(function() { return generator.caller; }, TypeError);
assertThrows(function() { return generator.caller = {}; }, TypeError);
})();
assertFalse(adesc.enumerable);
assertFalse(adesc.configurable);
assertSame(cdesc.get, cdesc.set);
assertSame(cdesc.get, adesc.get);
assertSame(cdesc.get, adesc.set);
(function testRestrictedPropertiesSloppy() {
function* generator() {}
assertFalse(generator.hasOwnProperty("arguments"));
assertThrows(function() { return generator.arguments; }, TypeError);
assertThrows(function() { return generator.arguments = {}; }, TypeError);
assertTrue(cdesc.get instanceof Function);
assertEquals(0, cdesc.get.length);
assertThrows(cdesc.get, TypeError);
assertFalse(generator.hasOwnProperty("caller"));
assertThrows(function() { return generator.caller; }, TypeError);
assertThrows(function() { return generator.caller = {}; }, TypeError);
})();
assertThrows(function() { return f.caller; }, TypeError);
assertThrows(function() { f.caller = 42; }, TypeError);
assertThrows(function() { return f.arguments; }, TypeError);
assertThrows(function() { f.arguments = 42; }, TypeError);
function assertIteratorResult(value, done, result) {
assertEquals({value: value, done: done}, result);
}
function *sloppy() { test(sloppy); }
function *strict() { "use strict"; test(strict); }
test(sloppy);
test(strict);
(function testIteratorResultStrict() {
function* generator() { "use strict"; }
assertIteratorResult(undefined, true, generator().next());
})();
assertIteratorResult(undefined, true, sloppy().next());
assertIteratorResult(undefined, true, strict().next());
(function testIteratorResultSloppy() {
function* generator() {}
assertIteratorResult(undefined, true, generator().next());
})();
......@@ -30,7 +30,7 @@
// See:
// http://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorfunction-objects
function f() { }
function f() { "use strict"; }
function* g() { yield 1; }
var GeneratorFunctionPrototype = Object.getPrototypeOf(g);
var GeneratorFunction = GeneratorFunctionPrototype.constructor;
......@@ -51,18 +51,16 @@ function TestGeneratorFunctionInstance() {
var prop = f_own_property_names[i];
var f_desc = Object.getOwnPropertyDescriptor(f, prop);
var g_desc = Object.getOwnPropertyDescriptor(g, prop);
assertEquals(f_desc.configurable, g_desc.configurable, prop);
if (prop === 'arguments' || prop === 'caller') {
// Unlike sloppy functions, which have read-only data arguments and caller
// properties, sloppy generators have a poison pill implemented via
// accessors
assertFalse('writable' in g_desc, prop);
assertTrue(g_desc.get instanceof Function, prop);
assertEquals(g_desc.get, g_desc.set, prop);
if (prop === "prototype") {
// ES6 draft 03-17-2015 section 25.2.2.2
assertFalse(g_desc.writable, prop);
assertFalse(g_desc.enumerable, prop);
assertFalse(g_desc.configurable, prop);
} else {
assertEquals(f_desc.configurable, g_desc.configurable, prop);
assertEquals(f_desc.writable, g_desc.writable, prop);
assertEquals(f_desc.enumerable, g_desc.enumerable, prop);
}
assertEquals(f_desc.enumerable, g_desc.enumerable, prop);
}
}
TestGeneratorFunctionInstance();
......
......@@ -268,14 +268,18 @@ assertEquals([true, 0, undefined], s());
// Check that property descriptors are correct (unconfigurable, unenumerable,
// and both get and set is the ThrowTypeError function).
var cdesc = Object.getOwnPropertyDescriptor(f, "caller");
var adesc = Object.getOwnPropertyDescriptor(f, "arguments");
//
// Poisoned accessors are no longer own properties --- get them from the
// prototype
var f_proto = Object.getPrototypeOf(f);
var cdesc = Object.getOwnPropertyDescriptor(f_proto, "caller");
var adesc = Object.getOwnPropertyDescriptor(f_proto, "arguments");
assertFalse(cdesc.enumerable);
assertFalse(cdesc.configurable);
assertTrue(cdesc.configurable);
assertFalse(adesc.enumerable);
assertFalse(adesc.configurable);
assertTrue(adesc.configurable);
assertSame(cdesc.get, cdesc.set);
assertSame(cdesc.get, adesc.get);
......
......@@ -47,3 +47,26 @@ var fives = [];
if (v % 5 === 0) fives.push(v);
});
assertEquals([5, 10], fives);
(function testRestrictedFunctionPropertiesStrict() {
var arrowFn = () => { "use strict"; };
assertFalse(arrowFn.hasOwnProperty("arguments"));
assertThrows(function() { return arrowFn.arguments; }, TypeError);
assertThrows(function() { arrowFn.arguments = {}; }, TypeError);
assertFalse(arrowFn.hasOwnProperty("caller"));
assertThrows(function() { return arrowFn.caller; }, TypeError);
assertThrows(function() { arrowFn.caller = {}; }, TypeError);
})();
(function testRestrictedFunctionPropertiesSloppy() {
var arrowFn = () => {};
assertFalse(arrowFn.hasOwnProperty("arguments"));
assertThrows(function() { return arrowFn.arguments; }, TypeError);
assertThrows(function() { arrowFn.arguments = {}; }, TypeError);
assertFalse(arrowFn.hasOwnProperty("caller"));
assertThrows(function() { return arrowFn.caller; }, TypeError);
assertThrows(function() { arrowFn.caller = {}; }, TypeError);
})();
......@@ -875,3 +875,69 @@ function assertAccessorDescriptor(object, name) {
};
new C3();
}());
function testClassRestrictedProperties(C) {
assertEquals(false, C.hasOwnProperty("arguments"));
assertThrows(function() { return C.arguments; }, TypeError);
assertThrows(function() { C.arguments = {}; }, TypeError);
assertEquals(false, C.hasOwnProperty("caller"));
assertThrows(function() { return C.caller; }, TypeError);
assertThrows(function() { C.caller = {}; }, TypeError);
assertEquals(false, (new C).method.hasOwnProperty("arguments"));
assertThrows(function() { return new C().method.arguments; }, TypeError);
assertThrows(function() { new C().method.arguments = {}; }, TypeError);
assertEquals(false, (new C).method.hasOwnProperty("caller"));
assertThrows(function() { return new C().method.caller; }, TypeError);
assertThrows(function() { new C().method.caller = {}; }, TypeError);
}
(function testRestrictedPropertiesStrict() {
"use strict";
class ClassWithDefaultConstructor {
method() {}
}
class Class {
constructor() {}
method() {}
}
class DerivedClassWithDefaultConstructor extends Class {}
class DerivedClass extends Class { constructor() { super(); } }
testClassRestrictedProperties(ClassWithDefaultConstructor);
testClassRestrictedProperties(Class);
testClassRestrictedProperties(DerivedClassWithDefaultConstructor);
testClassRestrictedProperties(DerivedClass);
testClassRestrictedProperties(class { method() {} });
testClassRestrictedProperties(class { constructor() {} method() {} });
testClassRestrictedProperties(class extends Class { });
testClassRestrictedProperties(
class extends Class { constructor() { super(); } });
})();
(function testRestrictedPropertiesSloppy() {
class ClassWithDefaultConstructor {
method() {}
}
class Class {
constructor() {}
method() {}
}
class DerivedClassWithDefaultConstructor extends Class {}
class DerivedClass extends Class { constructor() { super(); } }
testClassRestrictedProperties(ClassWithDefaultConstructor);
testClassRestrictedProperties(Class);
testClassRestrictedProperties(DerivedClassWithDefaultConstructor);
testClassRestrictedProperties(DerivedClass);
testClassRestrictedProperties(class { method() {} });
testClassRestrictedProperties(class { constructor() {} method() {} });
testClassRestrictedProperties(class extends Class { });
testClassRestrictedProperties(
class extends Class { constructor() { super(); } });
})();
......@@ -83,9 +83,8 @@ function ID(x) {
// TODO(arv): It is not clear that we are adding the "standard" properties
// in the right order. As far as I can tell the spec adds them in alphabetical
// order.
assertArrayEquals(['length', 'name', 'arguments', 'caller', 'prototype',
'a', 'b', 'c', 'd'],
Object.getOwnPropertyNames(C));
assertArrayEquals(['length', 'name', 'prototype', 'a', 'b', 'c', 'd'],
Object.getOwnPropertyNames(C));
})();
......@@ -102,8 +101,8 @@ function ID(x) {
assertEquals('D', C[2]());
// Array indexes first.
assertArrayEquals([], Object.keys(C));
assertArrayEquals(['1', '2', 'length', 'name', 'arguments', 'caller',
'prototype', 'a', 'c'], Object.getOwnPropertyNames(C));
assertArrayEquals(['1', '2', 'length', 'name', 'prototype', 'a', 'c'],
Object.getOwnPropertyNames(C));
})();
......@@ -121,9 +120,8 @@ function ID(x) {
assertEquals('C', C.c());
assertEquals('D', C[sym2]());
assertArrayEquals([], Object.keys(C));
assertArrayEquals(['length', 'name', 'arguments', 'caller', 'prototype',
'a', 'c'],
Object.getOwnPropertyNames(C));
assertArrayEquals(['length', 'name', 'prototype', 'a', 'c'],
Object.getOwnPropertyNames(C));
assertArrayEquals([sym1, sym2], Object.getOwnPropertySymbols(C));
})();
......
......@@ -104,6 +104,34 @@
})();
(function TestNoRestrictedPropertiesStrict() {
var obj = {
method() { "use strict"; }
};
assertFalse(obj.method.hasOwnProperty("arguments"));
assertThrows(function() { return obj.method.arguments; }, TypeError);
assertThrows(function() { obj.method.arguments = {}; }, TypeError);
assertFalse(obj.method.hasOwnProperty("caller"));
assertThrows(function() { return obj.method.caller; }, TypeError);
assertThrows(function() { obj.method.caller = {}; }, TypeError);
})();
(function TestNoRestrictedPropertiesSloppy() {
var obj = {
method() {}
};
assertFalse(obj.method.hasOwnProperty("arguments"));
assertThrows(function() { return obj.method.arguments; }, TypeError);
assertThrows(function() { obj.method.arguments = {}; }, TypeError);
assertFalse(obj.method.hasOwnProperty("caller"));
assertThrows(function() { return obj.method.caller; }, TypeError);
assertThrows(function() { obj.method.caller = {}; }, TypeError);
})();
(function TestToString() {
var object = {
method() { 42; }
......
......@@ -1010,7 +1010,35 @@ repeat(10, function() {
})();
function CheckPillDescriptor(func, name) {
function CheckFunctionPillDescriptor(func, name) {
function CheckPill(pill) {
assertEquals("function", typeof pill);
assertInstanceof(pill, Function);
pill.property = "value";
assertEquals(pill.value, undefined);
assertThrows(function() { 'use strict'; pill.property = "value"; },
TypeError);
assertThrows(pill, TypeError);
assertEquals(pill.prototype, (function(){}).prototype);
var d = Object.getOwnPropertyDescriptor(pill, "prototype");
assertFalse(d.writable);
assertFalse(d.configurable);
assertFalse(d.enumerable);
}
// Poisoned accessors are no longer own properties
func = Object.getPrototypeOf(func);
var descriptor = Object.getOwnPropertyDescriptor(func, name);
CheckPill(descriptor.get)
CheckPill(descriptor.set);
assertFalse(descriptor.enumerable);
// In ES6, restricted function properties are configurable
assertTrue(descriptor.configurable);
}
function CheckArgumentsPillDescriptor(func, name) {
function CheckPill(pill) {
assertEquals("function", typeof pill);
......@@ -1056,12 +1084,12 @@ function CheckPillDescriptor(func, name) {
assertThrows(function() { third.caller = 42; }, TypeError);
assertThrows(function() { third.arguments = 42; }, TypeError);
CheckPillDescriptor(strict, "caller");
CheckPillDescriptor(strict, "arguments");
CheckPillDescriptor(another, "caller");
CheckPillDescriptor(another, "arguments");
CheckPillDescriptor(third, "caller");
CheckPillDescriptor(third, "arguments");
CheckFunctionPillDescriptor(strict, "caller");
CheckFunctionPillDescriptor(strict, "arguments");
CheckFunctionPillDescriptor(another, "caller");
CheckFunctionPillDescriptor(another, "arguments");
CheckFunctionPillDescriptor(third, "caller");
CheckFunctionPillDescriptor(third, "arguments");
})();
......@@ -1093,15 +1121,15 @@ function CheckPillDescriptor(func, name) {
}
var args = strict();
CheckPillDescriptor(args, "caller");
CheckPillDescriptor(args, "callee");
CheckArgumentsPillDescriptor(args, "caller");
CheckArgumentsPillDescriptor(args, "callee");
args = strict(17, "value", strict);
assertEquals(17, args[0])
assertEquals("value", args[1])
assertEquals(strict, args[2]);
CheckPillDescriptor(args, "caller");
CheckPillDescriptor(args, "callee");
CheckArgumentsPillDescriptor(args, "caller");
CheckArgumentsPillDescriptor(args, "callee");
function outer() {
"use strict";
......@@ -1112,15 +1140,15 @@ function CheckPillDescriptor(func, name) {
}
var args = outer()();
CheckPillDescriptor(args, "caller");
CheckPillDescriptor(args, "callee");
CheckArgumentsPillDescriptor(args, "caller");
CheckArgumentsPillDescriptor(args, "callee");
args = outer()(17, "value", strict);
assertEquals(17, args[0])
assertEquals("value", args[1])
assertEquals(strict, args[2]);
CheckPillDescriptor(args, "caller");
CheckPillDescriptor(args, "callee");
CheckArgumentsPillDescriptor(args, "caller");
CheckArgumentsPillDescriptor(args, "callee");
})();
......
......@@ -595,6 +595,25 @@
# 'es6/String.prototype.contains/String.prototype.contains_Success' : [FAIL_OK],
# 'es6/String.prototype.contains/String.prototype.contains_SuccessNoLocation' : [FAIL_OK],
# Function restricted "caller" and "arguments" properties are defined only on
# the intrinsic %FunctionPrototype% (and sloppy functions) in ES6
'language/statements/function/13.2-29-s': [FAIL_OK],
'language/statements/function/13.2-30-s': [FAIL_OK],
'language/statements/function/13.2-31-s': [FAIL_OK],
'language/statements/function/13.2-32-s': [FAIL_OK],
'language/statements/function/13.2-33-s': [FAIL_OK],
'language/statements/function/13.2-34-s': [FAIL_OK],
'language/statements/function/13.2-35-s': [FAIL_OK],
'language/statements/function/13.2-36-s': [FAIL_OK],
'language/statements/function/S13.2.3_A1': [FAIL_OK],
'built-ins/Function/prototype/bind/15.3.4.5-20-1': [FAIL_OK],
'built-ins/Function/prototype/bind/15.3.4.5-20-4': [FAIL_OK],
'built-ins/Function/prototype/bind/15.3.4.5-20-5': [FAIL_OK],
'built-ins/Function/prototype/bind/15.3.4.5-21-1': [FAIL_OK],
'built-ins/Function/prototype/bind/15.3.4.5-21-4': [FAIL_OK],
'built-ins/Function/prototype/bind/15.3.4.5-21-5': [FAIL_OK],
############################ SKIPPED TESTS #############################
# These tests take a looong time to run in debug mode.
......
......@@ -263,6 +263,24 @@
'S15.7.4.5_A1.1_T01': [FAIL],
'S15.7.4_A1': [FAIL],
# Function restricted "caller" and "arguments" properties are defined only on
# the intrinsic %FunctionPrototype% (and sloppy functions) in ES6
'13.2-29-s': [FAIL],
'13.2-30-s': [FAIL],
'13.2-31-s': [FAIL],
'13.2-32-s': [FAIL],
'13.2-33-s': [FAIL],
'13.2-34-s': [FAIL],
'13.2-35-s': [FAIL],
'13.2-36-s': [FAIL],
'S13.2.3_A1': [FAIL],
'15.3.4.5-20-1': [FAIL],
'15.3.4.5-20-4': [FAIL],
'15.3.4.5-20-5': [FAIL],
'15.3.4.5-21-1': [FAIL],
'15.3.4.5-21-4': [FAIL],
'15.3.4.5-21-5': [FAIL],
######################## NEEDS INVESTIGATION ###########################
# These test failures are specific to the intl402 suite and need investigation
......
......@@ -38,12 +38,12 @@ PASS getSortedOwnPropertyNames(parseInt) is ['arguments', 'caller', 'length', 'n
PASS getSortedOwnPropertyNames(parseFloat) is ['arguments', 'caller', 'length', 'name']
PASS getSortedOwnPropertyNames(isNaN) is ['arguments', 'caller', 'length', 'name']
PASS getSortedOwnPropertyNames(isFinite) is ['arguments', 'caller', 'length', 'name']
PASS getSortedOwnPropertyNames(escape) is ['arguments', 'caller', 'length', 'name']
PASS getSortedOwnPropertyNames(unescape) is ['arguments', 'caller', 'length', 'name']
PASS getSortedOwnPropertyNames(decodeURI) is ['arguments', 'caller', 'length', 'name']
PASS getSortedOwnPropertyNames(decodeURIComponent) is ['arguments', 'caller', 'length', 'name']
PASS getSortedOwnPropertyNames(encodeURI) is ['arguments', 'caller', 'length', 'name']
PASS getSortedOwnPropertyNames(encodeURIComponent) is ['arguments', 'caller', 'length', 'name']
PASS getSortedOwnPropertyNames(escape) is ['length', 'name']
PASS getSortedOwnPropertyNames(unescape) is ['length', 'name']
PASS getSortedOwnPropertyNames(decodeURI) is ['length', 'name']
PASS getSortedOwnPropertyNames(decodeURIComponent) is ['length', 'name']
PASS getSortedOwnPropertyNames(encodeURI) is ['length', 'name']
PASS getSortedOwnPropertyNames(encodeURIComponent) is ['length', 'name']
PASS getSortedOwnPropertyNames(Object) is ['arguments', 'caller', 'create', 'defineProperties', 'defineProperty', 'deliverChangeRecords', 'freeze', 'getNotifier', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'getOwnPropertySymbols', 'getPrototypeOf', 'is', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'observe', 'preventExtensions', 'prototype', 'seal', 'setPrototypeOf', 'unobserve']
PASS getSortedOwnPropertyNames(Object.prototype) is ['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']
PASS getSortedOwnPropertyNames(Function) is ['arguments', 'caller', 'length', 'name', 'prototype']
......
......@@ -64,12 +64,12 @@ var expectedPropertyNamesSet = {
"parseFloat": "['arguments', 'caller', 'length', 'name']",
"isNaN": "['arguments', 'caller', 'length', 'name']",
"isFinite": "['arguments', 'caller', 'length', 'name']",
"escape": "['arguments', 'caller', 'length', 'name']",
"unescape": "['arguments', 'caller', 'length', 'name']",
"decodeURI": "['arguments', 'caller', 'length', 'name']",
"decodeURIComponent": "['arguments', 'caller', 'length', 'name']",
"encodeURI": "['arguments', 'caller', 'length', 'name']",
"encodeURIComponent": "['arguments', 'caller', 'length', 'name']",
"escape": "['length', 'name']",
"unescape": "['length', 'name']",
"decodeURI": "['length', 'name']",
"decodeURIComponent": "['length', 'name']",
"encodeURI": "['length', 'name']",
"encodeURIComponent": "['length', 'name']",
// Built-in ECMA objects
"Object": "['arguments', 'caller', 'create', 'defineProperties', 'defineProperty', 'deliverChangeRecords', 'freeze', 'getNotifier', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'getOwnPropertySymbols', 'getPrototypeOf', 'is', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'observe', 'preventExtensions', 'prototype', 'seal', 'setPrototypeOf', 'unobserve']",
"Object.prototype": "['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']",
......
......@@ -81,20 +81,22 @@ PASS (function (){'use strict'; with(1){};}) threw exception SyntaxError: Strict
PASS (function(){(function (){'use strict'; with(1){};})}) threw exception SyntaxError: Strict mode code may not include a with statement.
PASS (function (){'use strict'; arguments.callee; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function (){'use strict'; arguments.caller; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function f(){'use strict'; f.arguments; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function f(){'use strict'; f.caller; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function f(){'use strict'; f.arguments=5; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function f(){'use strict'; f.caller=5; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function f(){'use strict'; f.arguments; })() threw exception TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context..
PASS (function f(){'use strict'; f.caller; })() threw exception TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context..
PASS (function f(){'use strict'; f.arguments=5; })() threw exception TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context..
PASS (function f(){'use strict'; f.caller=5; })() threw exception TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context..
PASS (function (arg){'use strict'; arguments.callee; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function (arg){'use strict'; arguments.caller; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function f(arg){'use strict'; f.arguments; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function f(arg){'use strict'; f.caller; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function f(arg){'use strict'; f.arguments=5; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function f(arg){'use strict'; f.caller=5; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function f(arg){'use strict'; f.arguments; })() threw exception TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context..
PASS (function f(arg){'use strict'; f.caller; })() threw exception TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context..
PASS (function f(arg){'use strict'; f.arguments=5; })() threw exception TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context..
PASS (function f(arg){'use strict'; f.caller=5; })() threw exception TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context..
PASS "caller" in function(){"use strict"} is true
PASS (function(){"use strict";}).hasOwnProperty("caller") is true
PASS (function(){"use strict";}).hasOwnProperty("caller") is false
PASS (function(){"use strict";}).__proto__.hasOwnProperty("caller") is true
PASS "arguments" in function(){"use strict"} is true
PASS (function(){"use strict";}).hasOwnProperty("arguments") is true
PASS (function(){"use strict";}).hasOwnProperty("arguments") is false
PASS (function(){"use strict";}).__proto__.hasOwnProperty("arguments") is true
PASS 'use strict'; (function (){with(1){};}) threw exception SyntaxError: Strict mode code may not include a with statement.
PASS (function(){'use strict'; (function (){with(1){};})}) threw exception SyntaxError: Strict mode code may not include a with statement.
PASS 'use strict'; (function (){var a; delete a;}) threw exception SyntaxError: Delete of an unqualified identifier in strict mode..
......@@ -195,14 +197,14 @@ PASS (function (a){'use strict'; var local; (function (){local;})(); arguments[0
PASS (function (){'use strict'; var local; (function (){local;})(); arguments[0]=true; return arguments; })()[0] is true
PASS 'use strict'; (function (){var a = true; eval('var a = false'); return a; })() is true
PASS (function (){var a = true; eval('"use strict"; var a = false'); return a; })() is true
PASS (function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(f, 'arguments').value; })() is undefined.
PASS (function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(f, 'caller').value; })() is undefined.
PASS (function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(f.__proto__, 'arguments').value; })() is undefined.
PASS (function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(f.__proto__, 'caller').value; })() is undefined.
PASS (function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(arguments, 'callee').value; })() is undefined.
PASS (function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(arguments, 'caller').value; })() is undefined.
PASS (function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(arguments, 'caller'); return descriptor.get === descriptor.set; })() is true
PASS (function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(arguments, 'callee'); return descriptor.get === descriptor.set; })() is true
PASS (function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f, 'caller'); return descriptor.get === descriptor.set; })() is true
PASS (function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f, 'arguments'); return descriptor.get === descriptor.set; })() is true
PASS (function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f.__proto__, 'caller'); return descriptor.get === descriptor.set; })() is true
PASS (function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f.__proto__, 'arguments'); return descriptor.get === descriptor.set; })() is true
PASS 'use strict'; (function f() { for(var i in this); })(); true; is true
PASS 'use strict'̻ threw exception SyntaxError: Unexpected token ILLEGAL.
PASS (function(){'use strict'̻}) threw exception SyntaxError: Unexpected token ILLEGAL.
......@@ -228,7 +230,7 @@ PASS (function () {'use strict'; try { throw 1; } catch (e) { aGlobal = true; }
PASS try { throw 1; } catch (e) { aGlobal = true; } is true
PASS (function () { try { throw 1; } catch (e) { aGlobal = true; }})(); aGlobal; is true
PASS (function () {try { throw 1; } catch (e) { aGlobal = true; }})(); aGlobal; is true
FAIL String(Object.getOwnPropertyDescriptor(function() { "use strict"; }, "caller").get) should be function () {
FAIL String(Object.getOwnPropertyDescriptor((function() { "use strict"; }).__proto__, "caller").get) should be function () {
[native code]
}. Was function ThrowTypeError() { [native code] }.
PASS successfullyParsed is true
......
......@@ -109,11 +109,13 @@ shouldThrow("(function f(arg){'use strict'; f.caller; })()");
shouldThrow("(function f(arg){'use strict'; f.arguments=5; })()");
shouldThrow("(function f(arg){'use strict'; f.caller=5; })()");
// arguments/caller poisoning should be visible but not throw with 'in' & 'hasOwnProperty'.
// arguments/caller poisoning should be visible on the intrinsic %FunctionPrototype%, but not throw with 'in' & 'hasOwnProperty'.
shouldBeTrue('"caller" in function(){"use strict"}');
shouldBeTrue('(function(){"use strict";}).hasOwnProperty("caller")');
shouldBeFalse('(function(){"use strict";}).hasOwnProperty("caller")');
shouldBeTrue('(function(){"use strict";}).__proto__.hasOwnProperty("caller")');
shouldBeTrue('"arguments" in function(){"use strict"}');
shouldBeTrue('(function(){"use strict";}).hasOwnProperty("arguments")');
shouldBeFalse('(function(){"use strict";}).hasOwnProperty("arguments")');
shouldBeTrue('(function(){"use strict";}).__proto__.hasOwnProperty("arguments")');
shouldBeSyntaxError("'use strict'; (function (){with(1){};})");
shouldBeSyntaxError("'use strict'; (function (){var a; delete a;})");
......@@ -194,14 +196,14 @@ shouldBeTrue("(function (){'use strict'; var local; (function (){local;})(); ar
shouldBeTrue("'use strict'; (function (){var a = true; eval('var a = false'); return a; })()");
shouldBeTrue("(function (){var a = true; eval('\"use strict\"; var a = false'); return a; })()");
shouldBeUndefined("(function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(f, 'arguments').value; })()");
shouldBeUndefined("(function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(f, 'caller').value; })()");
shouldBeUndefined("(function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(f.__proto__, 'arguments').value; })()");
shouldBeUndefined("(function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(f.__proto__, 'caller').value; })()");
shouldBeUndefined("(function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(arguments, 'callee').value; })()");
shouldBeUndefined("(function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(arguments, 'caller').value; })()");
shouldBeTrue("(function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(arguments, 'caller'); return descriptor.get === descriptor.set; })()");
shouldBeTrue("(function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(arguments, 'callee'); return descriptor.get === descriptor.set; })()");
shouldBeTrue("(function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f, 'caller'); return descriptor.get === descriptor.set; })()");
shouldBeTrue("(function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f, 'arguments'); return descriptor.get === descriptor.set; })()");
shouldBeTrue("(function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f.__proto__, 'caller'); return descriptor.get === descriptor.set; })()");
shouldBeTrue("(function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f.__proto__, 'arguments'); return descriptor.get === descriptor.set; })()");
shouldBeTrue("'use strict'; (function f() { for(var i in this); })(); true;")
shouldBeSyntaxError("'use strict'\u033b");
......@@ -228,4 +230,4 @@ aGlobal = false;
shouldBeTrue("(function () {try { throw 1; } catch (e) { aGlobal = true; }})(); aGlobal;");
// Make sure this doesn't crash!
shouldBe('String(Object.getOwnPropertyDescriptor(function() { "use strict"; }, "caller").get)', "'function () {\\n [native code]\\n}'");
shouldBe('String(Object.getOwnPropertyDescriptor((function() { "use strict"; }).__proto__, "caller").get)', "'function () {\\n [native code]\\n}'");
# Copyright 2013 the V8 project authors. All rights reserved.
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This tests for caller property in functions. Only functions that are called from inside of other functions and have a parent should have this property set. Tests return true when caller is found and false when the caller is null.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS childHasCallerWhenExecutingGlobalCode is false
PASS childHasCallerWhenCalledWithoutParent is false
PASS childHasCallerWhenCalledFromWithinParent is true
PASS nonStrictCaller(nonStrictCallee) is nonStrictCaller
FAIL nonStrictCaller(strictCallee) should throw TypeError: Type error. Threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
FAIL strictCaller(nonStrictCallee) should throw TypeError: Function.caller used to retrieve strict caller. Was null.
FAIL strictCaller(strictCallee) should throw TypeError: Type error. Threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS nonStrictCaller(boundNonStrictCallee) is nonStrictCaller
FAIL nonStrictCaller(boundStrictCallee) should throw TypeError: Type error. Threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
FAIL strictCaller(boundNonStrictCallee) should throw TypeError: Function.caller used to retrieve strict caller. Was null.
FAIL strictCaller(boundStrictCallee) should throw TypeError: Type error. Threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS nonStrictGetter(nonStrictAccessor) is nonStrictGetter
PASS nonStrictSetter(nonStrictAccessor) is true
FAIL nonStrictGetter(strictAccessor) should throw TypeError: Type error. Threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
FAIL nonStrictSetter(strictAccessor) should throw TypeError: Type error. Threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
FAIL strictGetter(nonStrictAccessor) should throw TypeError: Function.caller used to retrieve strict caller. Was null.
FAIL strictSetter(nonStrictAccessor) should throw TypeError: Function.caller used to retrieve strict caller. Was undefined.
FAIL strictGetter(strictAccessor) should throw TypeError: Type error. Threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
FAIL strictSetter(strictAccessor) should throw TypeError: Type error. Threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS successfullyParsed is true
TEST COMPLETE
// Copyright 2013 the V8 project authors. All rights reserved.
// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
description(
'This tests for caller property in functions. Only functions that are called from inside of other functions and have a parent should have this property set. Tests return true when caller is found and false when the caller is null.'
)
function child()
{
return (child.caller !== null);
}
function parent()
{
return child();
}
var childHasCallerWhenExecutingGlobalCode = (child.caller !== null);
var childHasCallerWhenCalledWithoutParent = child();
var childHasCallerWhenCalledFromWithinParent = parent();
shouldBe('childHasCallerWhenExecutingGlobalCode', 'false');
shouldBe('childHasCallerWhenCalledWithoutParent', 'false');
shouldBe('childHasCallerWhenCalledFromWithinParent', 'true')
// The caller property should throw in strict mode, and a non-strict function cannot use caller to reach a strict caller (see ES5.1 15.3.5.4).
function nonStrictCallee() { return nonStrictCallee.caller; }
function strictCallee() { "use strict"; return strictCallee.caller; }
function nonStrictCaller(x) { return x(); }
function strictCaller(x) { "use strict"; return x(); }
shouldBe("nonStrictCaller(nonStrictCallee)", "nonStrictCaller");
shouldThrow("nonStrictCaller(strictCallee)", '"TypeError: Type error"');
shouldThrow("strictCaller(nonStrictCallee)", '"TypeError: Function.caller used to retrieve strict caller"');
shouldThrow("strictCaller(strictCallee)", '"TypeError: Type error"');
// .caller within a bound function reaches the caller, ignoring the binding.
var boundNonStrictCallee = nonStrictCallee.bind();
var boundStrictCallee = strictCallee.bind();
shouldBe("nonStrictCaller(boundNonStrictCallee)", "nonStrictCaller");
shouldThrow("nonStrictCaller(boundStrictCallee)", '"TypeError: Type error"');
shouldThrow("strictCaller(boundNonStrictCallee)", '"TypeError: Function.caller used to retrieve strict caller"');
shouldThrow("strictCaller(boundStrictCallee)", '"TypeError: Type error"');
// Check that .caller works (or throws) as expected, over an accessor call.
function getFooGetter(x) { return Object.getOwnPropertyDescriptor(x, 'foo').get; }
function getFooSetter(x) { return Object.getOwnPropertyDescriptor(x, 'foo').set; }
var nonStrictAccessor = {
get foo() { return getFooGetter(nonStrictAccessor).caller; },
set foo(x) { if (getFooSetter(nonStrictAccessor).caller !==x) throw false; }
};
var strictAccessor = {
get foo() { "use strict"; return getFooGetter(strictAccessor).caller; },
set foo(x) { "use strict"; if (getFooSetter(strictAccessor).caller !==x) throw false; }
};
function nonStrictGetter(x) { return x.foo; }
function nonStrictSetter(x) { x.foo = nonStrictSetter; return true; }
function strictGetter(x) { "use strict"; return x.foo; }
function strictSetter(x) { "use strict"; x.foo = nonStrictSetter; return true; }
shouldBe("nonStrictGetter(nonStrictAccessor)", "nonStrictGetter");
shouldBeTrue("nonStrictSetter(nonStrictAccessor)");
shouldThrow("nonStrictGetter(strictAccessor)", '"TypeError: Type error"');
shouldThrow("nonStrictSetter(strictAccessor)", '"TypeError: Type error"');
shouldThrow("strictGetter(nonStrictAccessor)", '"TypeError: Function.caller used to retrieve strict caller"');
shouldThrow("strictSetter(nonStrictAccessor)", '"TypeError: Function.caller used to retrieve strict caller"');
shouldThrow("strictGetter(strictAccessor)", '"TypeError: Type error"');
shouldThrow("strictSetter(strictAccessor)", '"TypeError: Type error"');
# Copyright 2013 the V8 project authors. All rights reserved.
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ThrowTypeError is a singleton object
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS functionCaller1 === functionCaller2 is true
PASS functionCaller1 === functionArguments1 is true
PASS functionCaller1 === argumentsCaller1 is true
PASS functionCaller1 === argumentsCallee1 is true
PASS functionCaller1 === boundCaller1 is true
PASS functionCaller1 === boundArguments1 is true
PASS functionCaller2 === functionArguments2 is true
PASS functionCaller2 === argumentsCaller2 is true
PASS functionCaller2 === argumentsCallee2 is true
PASS functionCaller2 === boundCaller2 is true
PASS functionCaller2 === boundArguments2 is true
PASS successfullyParsed is true
TEST COMPLETE
// Copyright 2013 the V8 project authors. All rights reserved.
// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
description("ThrowTypeError is a singleton object");
function getter(object, name)
{
Object.getOwnPropertyDescriptor(object, name).get;
}
function strictArgumentsFunction1()
{
"use strict";
return arguments;
}
var strictArguments1 = strictArgumentsFunction1();
var boundFunction1 = strictArgumentsFunction1.bind();
var functionCaller1 = getter(strictArgumentsFunction1, "caller");
var functionArguments1 = getter(strictArgumentsFunction1, "arguments");
var argumentsCaller1 = getter(strictArguments1, "caller");
var argumentsCallee1 = getter(strictArguments1, "callee");
var boundCaller1 = getter(boundFunction1, "caller");
var boundArguments1 = getter(boundFunction1, "arguments");
function strictArgumentsFunction2()
{
"use strict";
return arguments;
}
var strictArguments2 = strictArgumentsFunction2();
var boundFunction2 = strictArgumentsFunction2.bind();
var functionCaller2 = getter(strictArgumentsFunction2, "caller");
var functionArguments2 = getter(strictArgumentsFunction2, "arguments");
var argumentsCaller2 = getter(strictArguments2, "caller");
var argumentsCallee2 = getter(strictArguments2, "callee");
var boundCaller2 = getter(boundFunction2, "caller");
var boundArguments2 = getter(boundFunction2, "arguments");
shouldBeTrue('functionCaller1 === functionCaller2');
shouldBeTrue('functionCaller1 === functionArguments1');
shouldBeTrue('functionCaller1 === argumentsCaller1');
shouldBeTrue('functionCaller1 === argumentsCallee1');
shouldBeTrue('functionCaller1 === boundCaller1');
shouldBeTrue('functionCaller1 === boundArguments1');
shouldBeTrue('functionCaller2 === functionArguments2');
shouldBeTrue('functionCaller2 === argumentsCaller2');
shouldBeTrue('functionCaller2 === argumentsCallee2');
shouldBeTrue('functionCaller2 === boundCaller2');
shouldBeTrue('functionCaller2 === boundArguments2');
successfullyParsed = true;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment