[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}
This commit is contained in:
caitpotter88 2015-04-09 15:40:16 -07:00 committed by Commit bot
parent 806e57f401
commit 9836c34dba
25 changed files with 427 additions and 514 deletions

View File

@ -135,15 +135,14 @@ class Genesis BASE_EMBEDDED {
// Creates the empty function. Used for creating a context from scratch. // Creates the empty function. Used for creating a context from scratch.
Handle<JSFunction> CreateEmptyFunction(Isolate* isolate); Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
// Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
Handle<JSFunction> GetStrictPoisonFunction(); Handle<JSFunction> GetRestrictedFunctionPropertiesThrower();
// Poison for sloppy generator function arguments/callee. Handle<JSFunction> GetStrictArgumentsPoisonFunction();
Handle<JSFunction> GetGeneratorPoisonFunction();
void CreateStrictModeFunctionMaps(Handle<JSFunction> empty); void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
void CreateStrongModeFunctionMaps(Handle<JSFunction> empty); void CreateStrongModeFunctionMaps(Handle<JSFunction> empty);
// Make the "arguments" and "caller" properties throw a TypeError on access. // Make the "arguments" and "caller" properties throw a TypeError on access.
void PoisonArgumentsAndCaller(Handle<Map> map); void AddRestrictedFunctionProperties(Handle<Map> map);
// Creates the global objects using the global proxy and the template passed // Creates the global objects using the global proxy and the template passed
// in through the API. We call this regardless of whether we are building a // in through the API. We call this regardless of whether we are building a
@ -297,7 +296,7 @@ class Genesis BASE_EMBEDDED {
Handle<Map> sloppy_function_map_writable_prototype_; Handle<Map> sloppy_function_map_writable_prototype_;
Handle<Map> strict_function_map_writable_prototype_; Handle<Map> strict_function_map_writable_prototype_;
Handle<JSFunction> strict_poison_function; Handle<JSFunction> strict_poison_function;
Handle<JSFunction> generator_poison_function; Handle<JSFunction> restricted_function_properties_thrower;
BootstrapperActive active_; BootstrapperActive active_;
friend class Bootstrapper; friend class Bootstrapper;
@ -347,20 +346,25 @@ void Bootstrapper::DetachGlobal(Handle<Context> env) {
static Handle<JSFunction> InstallFunction(Handle<JSObject> target, static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
const char* name, const char* name, InstanceType type,
InstanceType type,
int instance_size, int instance_size,
MaybeHandle<JSObject> maybe_prototype, MaybeHandle<JSObject> maybe_prototype,
Builtins::Name call) { Builtins::Name call,
bool strict_function_map = false) {
Isolate* isolate = target->GetIsolate(); Isolate* isolate = target->GetIsolate();
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
Handle<String> internalized_name = factory->InternalizeUtf8String(name); Handle<String> internalized_name = factory->InternalizeUtf8String(name);
Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call)); Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call));
Handle<JSObject> prototype; Handle<JSObject> prototype;
Handle<JSFunction> function = maybe_prototype.ToHandle(&prototype) static const bool kReadOnlyPrototype = false;
? factory->NewFunction(internalized_name, call_code, prototype, static const bool kInstallConstructor = false;
type, instance_size) Handle<JSFunction> function =
: factory->NewFunctionWithoutPrototype(internalized_name, call_code); maybe_prototype.ToHandle(&prototype)
? factory->NewFunction(internalized_name, call_code, prototype, type,
instance_size, kReadOnlyPrototype,
kInstallConstructor, strict_function_map)
: factory->NewFunctionWithoutPrototype(internalized_name, call_code,
strict_function_map);
PropertyAttributes attributes; PropertyAttributes attributes;
if (target->IsJSBuiltinsObject()) { if (target->IsJSBuiltinsObject()) {
attributes = attributes =
@ -377,8 +381,8 @@ static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
} }
void Genesis::SetFunctionInstanceDescriptor( void Genesis::SetFunctionInstanceDescriptor(Handle<Map> map,
Handle<Map> map, FunctionMode function_mode) { FunctionMode function_mode) {
int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4; int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4;
Map::EnsureDescriptorSlack(map, size); Map::EnsureDescriptorSlack(map, size);
@ -460,7 +464,6 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
// This map is installed in MakeFunctionInstancePrototypeWritable. // This map is installed in MakeFunctionInstancePrototypeWritable.
sloppy_function_map_writable_prototype_ = sloppy_function_map_writable_prototype_ =
CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE); CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE);
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
Handle<String> object_name = factory->Object_string(); Handle<String> object_name = factory->Object_string();
@ -511,6 +514,7 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
DCHECK(!empty_function_map->is_dictionary_map()); DCHECK(!empty_function_map->is_dictionary_map());
empty_function_map->SetPrototype(object_function_prototype); empty_function_map->SetPrototype(object_function_prototype);
empty_function_map->set_is_prototype_map(true); empty_function_map->set_is_prototype_map(true);
empty_function->set_map(*empty_function_map); empty_function->set_map(*empty_function_map);
// --- E m p t y --- // --- E m p t y ---
@ -526,18 +530,21 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
native_context()->sloppy_function_map()->SetPrototype(empty_function); native_context()->sloppy_function_map()->SetPrototype(empty_function);
native_context()->sloppy_function_without_prototype_map()->SetPrototype( native_context()->sloppy_function_without_prototype_map()->SetPrototype(
empty_function); empty_function);
sloppy_function_map_writable_prototype_->SetPrototype(empty_function); sloppy_function_map_writable_prototype_->SetPrototype(empty_function);
// ES6 draft 03-17-2015, section 8.2.2 step 12
AddRestrictedFunctionProperties(empty_function_map);
return empty_function; return empty_function;
} }
void Genesis::SetStrictFunctionInstanceDescriptor( void Genesis::SetStrictFunctionInstanceDescriptor(Handle<Map> map,
Handle<Map> map, FunctionMode function_mode) { FunctionMode function_mode) {
int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4; int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4;
Map::EnsureDescriptorSlack(map, size); Map::EnsureDescriptorSlack(map, size);
Handle<AccessorPair> arguments(factory()->NewAccessorPair());
Handle<AccessorPair> caller(factory()->NewAccessorPair());
PropertyAttributes rw_attribs = PropertyAttributes rw_attribs =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
PropertyAttributes ro_attribs = PropertyAttributes ro_attribs =
@ -567,16 +574,6 @@ void Genesis::SetStrictFunctionInstanceDescriptor(
roc_attribs); roc_attribs);
map->AppendDescriptor(&d); map->AppendDescriptor(&d);
} }
{ // Add arguments.
AccessorConstantDescriptor d(factory()->arguments_string(), arguments,
rw_attribs);
map->AppendDescriptor(&d);
}
{ // Add caller.
AccessorConstantDescriptor d(factory()->caller_string(), caller,
rw_attribs);
map->AppendDescriptor(&d);
}
if (IsFunctionModeWithPrototype(function_mode)) { if (IsFunctionModeWithPrototype(function_mode)) {
// Add prototype. // Add prototype.
PropertyAttributes attribs = PropertyAttributes attribs =
@ -615,12 +612,31 @@ void Genesis::SetStrongFunctionInstanceDescriptor(Handle<Map> map) {
// ECMAScript 5th Edition, 13.2.3 // ECMAScript 5th Edition, 13.2.3
Handle<JSFunction> Genesis::GetStrictPoisonFunction() { Handle<JSFunction> Genesis::GetRestrictedFunctionPropertiesThrower() {
if (restricted_function_properties_thrower.is_null()) {
Handle<String> name = factory()->InternalizeOneByteString(
STATIC_CHAR_VECTOR("ThrowTypeError"));
Handle<Code> code(isolate()->builtins()->builtin(
Builtins::kRestrictedFunctionPropertiesThrower));
restricted_function_properties_thrower =
factory()->NewFunctionWithoutPrototype(name, code);
restricted_function_properties_thrower->set_map(
native_context()->sloppy_function_map());
restricted_function_properties_thrower->shared()->DontAdaptArguments();
JSObject::PreventExtensions(restricted_function_properties_thrower)
.Assert();
}
return restricted_function_properties_thrower;
}
Handle<JSFunction> Genesis::GetStrictArgumentsPoisonFunction() {
if (strict_poison_function.is_null()) { if (strict_poison_function.is_null()) {
Handle<String> name = factory()->InternalizeOneByteString( Handle<String> name = factory()->InternalizeOneByteString(
STATIC_CHAR_VECTOR("ThrowTypeError")); STATIC_CHAR_VECTOR("ThrowTypeError"));
Handle<Code> code(isolate()->builtins()->builtin( Handle<Code> code(isolate()->builtins()->builtin(
Builtins::kStrictModePoisonPill)); Builtins::kRestrictedStrictArgumentsPropertiesThrower));
strict_poison_function = factory()->NewFunctionWithoutPrototype(name, code); strict_poison_function = factory()->NewFunctionWithoutPrototype(name, code);
strict_poison_function->set_map(native_context()->sloppy_function_map()); strict_poison_function->set_map(native_context()->sloppy_function_map());
strict_poison_function->shared()->DontAdaptArguments(); strict_poison_function->shared()->DontAdaptArguments();
@ -631,26 +647,8 @@ Handle<JSFunction> Genesis::GetStrictPoisonFunction() {
} }
Handle<JSFunction> Genesis::GetGeneratorPoisonFunction() {
if (generator_poison_function.is_null()) {
Handle<String> name = factory()->InternalizeOneByteString(
STATIC_CHAR_VECTOR("ThrowTypeError"));
Handle<Code> code(isolate()->builtins()->builtin(
Builtins::kGeneratorPoisonPill));
generator_poison_function = factory()->NewFunctionWithoutPrototype(
name, code);
generator_poison_function->set_map(native_context()->sloppy_function_map());
generator_poison_function->shared()->DontAdaptArguments();
JSObject::PreventExtensions(generator_poison_function).Assert();
}
return generator_poison_function;
}
Handle<Map> Genesis::CreateStrictFunctionMap( Handle<Map> Genesis::CreateStrictFunctionMap(
FunctionMode function_mode, FunctionMode function_mode, Handle<JSFunction> empty_function) {
Handle<JSFunction> empty_function) {
Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
SetStrictFunctionInstanceDescriptor(map, function_mode); SetStrictFunctionInstanceDescriptor(map, function_mode);
map->set_function_with_prototype(IsFunctionModeWithPrototype(function_mode)); map->set_function_with_prototype(IsFunctionModeWithPrototype(function_mode));
@ -689,16 +687,11 @@ void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
// This map is installed in MakeFunctionInstancePrototypeWritable. // This map is installed in MakeFunctionInstancePrototypeWritable.
strict_function_map_writable_prototype_ = strict_function_map_writable_prototype_ =
CreateStrictFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE, empty); CreateStrictFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE, empty);
// Special map for bound functions. // Special map for bound functions.
Handle<Map> bound_function_map = Handle<Map> bound_function_map =
CreateStrictFunctionMap(BOUND_FUNCTION, empty); CreateStrictFunctionMap(BOUND_FUNCTION, empty);
native_context()->set_bound_function_map(*bound_function_map); native_context()->set_bound_function_map(*bound_function_map);
// Complete the callbacks.
PoisonArgumentsAndCaller(strict_function_without_prototype_map);
PoisonArgumentsAndCaller(strict_function_map);
PoisonArgumentsAndCaller(strict_function_map_writable_prototype_);
PoisonArgumentsAndCaller(bound_function_map);
} }
@ -712,17 +705,6 @@ void Genesis::CreateStrongModeFunctionMaps(Handle<JSFunction> empty) {
} }
static void SetAccessors(Handle<Map> map,
Handle<String> name,
Handle<JSFunction> func) {
DescriptorArray* descs = map->instance_descriptors();
int number = descs->SearchWithCache(*name, *map);
AccessorPair* accessors = AccessorPair::cast(descs->GetValue(number));
accessors->set_getter(*func);
accessors->set_setter(*func);
}
static void ReplaceAccessors(Handle<Map> map, static void ReplaceAccessors(Handle<Map> map,
Handle<String> name, Handle<String> name,
PropertyAttributes attributes, PropertyAttributes attributes,
@ -734,9 +716,15 @@ static void ReplaceAccessors(Handle<Map> map,
} }
void Genesis::PoisonArgumentsAndCaller(Handle<Map> map) { void Genesis::AddRestrictedFunctionProperties(Handle<Map> map) {
SetAccessors(map, factory()->arguments_string(), GetStrictPoisonFunction()); PropertyAttributes rw_attribs = static_cast<PropertyAttributes>(DONT_ENUM);
SetAccessors(map, factory()->caller_string(), GetStrictPoisonFunction()); Handle<JSFunction> thrower = GetRestrictedFunctionPropertiesThrower();
Handle<AccessorPair> accessors = factory()->NewAccessorPair();
accessors->set_getter(*thrower);
accessors->set_setter(*thrower);
ReplaceAccessors(map, factory()->arguments_string(), rw_attribs, accessors);
ReplaceAccessors(map, factory()->caller_string(), rw_attribs, accessors);
} }
@ -1280,7 +1268,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
Handle<AccessorPair> callee = factory->NewAccessorPair(); Handle<AccessorPair> callee = factory->NewAccessorPair();
Handle<AccessorPair> caller = factory->NewAccessorPair(); Handle<AccessorPair> caller = factory->NewAccessorPair();
Handle<JSFunction> poison = GetStrictPoisonFunction(); Handle<JSFunction> poison = GetStrictArgumentsPoisonFunction();
// Install the ThrowTypeError functions. // Install the ThrowTypeError functions.
callee->set_getter(*poison); callee->set_getter(*poison);
@ -2087,47 +2075,23 @@ bool Genesis::InstallNatives() {
generator_object_prototype, generator_object_prototype,
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
static const bool kUseStrictFunctionMap = true;
InstallFunction(builtins, "GeneratorFunction", JS_FUNCTION_TYPE, InstallFunction(builtins, "GeneratorFunction", JS_FUNCTION_TYPE,
JSFunction::kSize, generator_function_prototype, JSFunction::kSize, generator_function_prototype,
Builtins::kIllegal); Builtins::kIllegal, kUseStrictFunctionMap);
// Create maps for generator functions and their prototypes. Store those // Create maps for generator functions and their prototypes. Store those
// maps in the native context. // maps in the native context. Generator functions do not have writable
Handle<Map> generator_function_map = // prototypes, nor do they have "caller" or "arguments" accessors.
Map::Copy(sloppy_function_map_writable_prototype_, "GeneratorFunction");
generator_function_map->SetPrototype(generator_function_prototype);
native_context()->set_sloppy_generator_function_map(
*generator_function_map);
// The "arguments" and "caller" instance properties aren't specified, so
// technically we could leave them out. They make even less sense for
// generators than for functions. Still, the same argument that it makes
// sense to keep them around but poisoned in strict mode applies to
// generators as well. With poisoned accessors, naive callers can still
// iterate over the properties without accessing them.
//
// We can't use PoisonArgumentsAndCaller because that mutates accessor pairs
// in place, and the initial state of the generator function map shares the
// accessor pair with sloppy functions. Also the error message should be
// different. Also unhappily, we can't use the API accessors to implement
// poisoning, because API accessors present themselves as data properties,
// not accessor properties, and so getOwnPropertyDescriptor raises an
// exception as it tries to get the values. Sadness.
Handle<AccessorPair> poison_pair(factory()->NewAccessorPair());
PropertyAttributes rw_attribs =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
Handle<JSFunction> poison_function = GetGeneratorPoisonFunction();
poison_pair->set_getter(*poison_function);
poison_pair->set_setter(*poison_function);
ReplaceAccessors(generator_function_map, factory()->arguments_string(),
rw_attribs, poison_pair);
ReplaceAccessors(generator_function_map, factory()->caller_string(),
rw_attribs, poison_pair);
Handle<Map> strict_function_map(native_context()->strict_function_map()); Handle<Map> strict_function_map(native_context()->strict_function_map());
Handle<Map> sloppy_generator_function_map =
Map::Copy(strict_function_map, "SloppyGeneratorFunction");
sloppy_generator_function_map->SetPrototype(generator_function_prototype);
native_context()->set_sloppy_generator_function_map(
*sloppy_generator_function_map);
Handle<Map> strict_generator_function_map = Handle<Map> strict_generator_function_map =
Map::Copy(strict_function_map, "StrictGeneratorFunction"); Map::Copy(strict_function_map, "StrictGeneratorFunction");
// "arguments" and "caller" already poisoned.
strict_generator_function_map->SetPrototype(generator_function_prototype); strict_generator_function_map->SetPrototype(generator_function_prototype);
native_context()->set_strict_generator_function_map( native_context()->set_strict_generator_function_map(
*strict_generator_function_map); *strict_generator_function_map);

View File

@ -1000,10 +1000,19 @@ 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("restricted_function_properties",
HandleVector<Object>(NULL, 0)));
}
BUILTIN(RestrictedStrictArgumentsPropertiesThrower) {
HandleScope scope(isolate); HandleScope scope(isolate);
THROW_NEW_ERROR_RETURN_FAILURE( THROW_NEW_ERROR_RETURN_FAILURE(
isolate, isolate,
@ -1011,14 +1020,6 @@ BUILTIN(StrictModePoisonPill) {
} }
BUILTIN(GeneratorPoisonPill) {
HandleScope scope(isolate);
THROW_NEW_ERROR_RETURN_FAILURE(
isolate,
NewTypeError("generator_poison_pill", HandleVector<Object>(NULL, 0)));
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// //

View File

@ -41,26 +41,26 @@ enum BuiltinExtraArguments {
// Define list of builtins implemented in C++. // Define list of builtins implemented in C++.
#define BUILTIN_LIST_C(V) \ #define BUILTIN_LIST_C(V) \
V(Illegal, NO_EXTRA_ARGUMENTS) \ V(Illegal, NO_EXTRA_ARGUMENTS) \
\ \
V(EmptyFunction, NO_EXTRA_ARGUMENTS) \ V(EmptyFunction, NO_EXTRA_ARGUMENTS) \
\ \
V(ArrayPush, NO_EXTRA_ARGUMENTS) \ V(ArrayPush, NO_EXTRA_ARGUMENTS) \
V(ArrayPop, NO_EXTRA_ARGUMENTS) \ V(ArrayPop, NO_EXTRA_ARGUMENTS) \
V(ArrayShift, NO_EXTRA_ARGUMENTS) \ V(ArrayShift, NO_EXTRA_ARGUMENTS) \
V(ArrayUnshift, NO_EXTRA_ARGUMENTS) \ V(ArrayUnshift, NO_EXTRA_ARGUMENTS) \
V(ArraySlice, NO_EXTRA_ARGUMENTS) \ V(ArraySlice, NO_EXTRA_ARGUMENTS) \
V(ArraySplice, NO_EXTRA_ARGUMENTS) \ V(ArraySplice, NO_EXTRA_ARGUMENTS) \
V(ArrayConcat, NO_EXTRA_ARGUMENTS) \ V(ArrayConcat, NO_EXTRA_ARGUMENTS) \
\ \
V(HandleApiCall, NEEDS_CALLED_FUNCTION) \ V(HandleApiCall, NEEDS_CALLED_FUNCTION) \
V(HandleApiCallConstruct, NEEDS_CALLED_FUNCTION) \ V(HandleApiCallConstruct, NEEDS_CALLED_FUNCTION) \
V(HandleApiCallAsFunction, NO_EXTRA_ARGUMENTS) \ V(HandleApiCallAsFunction, NO_EXTRA_ARGUMENTS) \
V(HandleApiCallAsConstructor, NO_EXTRA_ARGUMENTS) \ V(HandleApiCallAsConstructor, NO_EXTRA_ARGUMENTS) \
\ \
V(StrictModePoisonPill, NO_EXTRA_ARGUMENTS) \ V(RestrictedFunctionPropertiesThrower, NO_EXTRA_ARGUMENTS) \
V(GeneratorPoisonPill, NO_EXTRA_ARGUMENTS) V(RestrictedStrictArgumentsPropertiesThrower, NO_EXTRA_ARGUMENTS)
// Define list of builtins implemented in assembly. // Define list of builtins implemented in assembly.
#define BUILTIN_LIST_A(V) \ #define BUILTIN_LIST_A(V) \

View File

@ -582,17 +582,16 @@ class Context: public FixedArray {
} }
if (IsConstructor(kind)) { if (IsConstructor(kind)) {
return is_strong(language_mode) ? STRONG_CONSTRUCTOR_MAP_INDEX : // Use strict function map (no own "caller" / "arguments")
is_strict(language_mode) ? STRICT_FUNCTION_MAP_INDEX return is_strong(language_mode) ? STRONG_CONSTRUCTOR_MAP_INDEX
: SLOPPY_FUNCTION_MAP_INDEX; : STRICT_FUNCTION_MAP_INDEX;
} }
if (IsArrowFunction(kind) || IsConciseMethod(kind) || if (IsArrowFunction(kind) || IsConciseMethod(kind) ||
IsAccessorFunction(kind)) { IsAccessorFunction(kind)) {
return is_strong(language_mode) ? STRONG_FUNCTION_MAP_INDEX : return is_strong(language_mode)
is_strict(language_mode) ? ? STRONG_FUNCTION_MAP_INDEX
STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX : : STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX;
SLOPPY_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX;
} }
return is_strong(language_mode) ? STRONG_FUNCTION_MAP_INDEX : return is_strong(language_mode) ? STRONG_FUNCTION_MAP_INDEX :

View File

@ -6,6 +6,7 @@
#include "src/allocation-site-scopes.h" #include "src/allocation-site-scopes.h"
#include "src/base/bits.h" #include "src/base/bits.h"
#include "src/bootstrapper.h"
#include "src/conversions.h" #include "src/conversions.h"
#include "src/isolate-inl.h" #include "src/isolate-inl.h"
#include "src/macro-assembler.h" #include "src/macro-assembler.h"
@ -1280,7 +1281,8 @@ Handle<JSFunction> Factory::NewFunction(Handle<Map> map,
map.is_identical_to( map.is_identical_to(
isolate()->sloppy_function_without_prototype_map()) || isolate()->sloppy_function_without_prototype_map()) ||
map.is_identical_to( 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); return NewFunction(map, info, context);
} }
@ -1292,19 +1294,27 @@ Handle<JSFunction> Factory::NewFunction(Handle<String> name) {
Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name, Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name,
Handle<Code> code) { Handle<Code> code,
return NewFunction( bool is_strict) {
isolate()->sloppy_function_without_prototype_map(), name, code); 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<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code,
Handle<Code> code,
Handle<Object> prototype, Handle<Object> prototype,
bool read_only_prototype) { bool read_only_prototype,
Handle<Map> map = read_only_prototype bool is_strict) {
? isolate()->sloppy_function_with_readonly_prototype_map() // In strict mode, readonly strict map is only available during bootstrap
: isolate()->sloppy_function_map(); 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); Handle<JSFunction> result = NewFunction(map, name, code);
result->set_prototype_or_initial_map(*prototype); result->set_prototype_or_initial_map(*prototype);
return result; return result;
@ -1315,10 +1325,11 @@ Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code,
Handle<Object> prototype, Handle<Object> prototype,
InstanceType type, int instance_size, InstanceType type, int instance_size,
bool read_only_prototype, bool read_only_prototype,
bool install_constructor) { bool install_constructor,
bool is_strict) {
// Allocate the function // Allocate the function
Handle<JSFunction> function = NewFunction( Handle<JSFunction> function =
name, code, prototype, read_only_prototype); NewFunction(name, code, prototype, read_only_prototype, is_strict);
ElementsKind elements_kind = ElementsKind elements_kind =
type == JS_ARRAY_TYPE ? FAST_SMI_ELEMENTS : FAST_HOLEY_SMI_ELEMENTS; type == JS_ARRAY_TYPE ? FAST_SMI_ELEMENTS : FAST_HOLEY_SMI_ELEMENTS;

View File

@ -482,13 +482,14 @@ class Factory FINAL {
void BecomeJSObject(Handle<JSProxy> object); void BecomeJSObject(Handle<JSProxy> object);
void BecomeJSFunction(Handle<JSProxy> object); void BecomeJSFunction(Handle<JSProxy> object);
Handle<JSFunction> NewFunction(Handle<String> name, Handle<JSFunction> NewFunction(Handle<String> name, Handle<Code> code,
Handle<Code> code,
Handle<Object> prototype, 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> NewFunction(Handle<String> name);
Handle<JSFunction> NewFunctionWithoutPrototype(Handle<String> name, Handle<JSFunction> NewFunctionWithoutPrototype(Handle<String> name,
Handle<Code> code); Handle<Code> code,
bool is_strict = false);
Handle<JSFunction> NewFunctionFromSharedFunctionInfo( Handle<JSFunction> NewFunctionFromSharedFunctionInfo(
Handle<SharedFunctionInfo> function_info, Handle<SharedFunctionInfo> function_info,
@ -499,7 +500,8 @@ class Factory FINAL {
Handle<Object> prototype, InstanceType type, Handle<Object> prototype, InstanceType type,
int instance_size, int instance_size,
bool read_only_prototype = false, bool read_only_prototype = false,
bool install_constructor = false); bool install_constructor = false,
bool is_strict = false);
Handle<JSFunction> NewFunction(Handle<String> name, Handle<JSFunction> NewFunction(Handle<String> name,
Handle<Code> code, Handle<Code> code,
InstanceType type, InstanceType type,

View File

@ -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_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_read_only_property: ["Cannot assign to read only property '", "%0", "' of ", "%1"],
strict_cannot_assign: ["Cannot assign to read only '", "%0", "' in strict mode"], 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_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."], strict_caller: ["Illegal access to a strict mode caller function."],
strong_ellision: ["In strong mode, arrays with holes are deprecated, use maps instead"], 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"], 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"], 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"], 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"], 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"], redef_external_array_element: ["Cannot redefine a property of an object with external array elements"],
const_assign: ["Assignment to constant variable."], const_assign: ["Assignment to constant variable."],

View File

@ -2,39 +2,41 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
(function testRestrictedPropertiesStrict() {
function* generator() { "use strict"; }
assertFalse(generator.hasOwnProperty("arguments"));
assertThrows(function() { return generator.arguments; }, TypeError);
assertThrows(function() { return generator.arguments = {}; }, TypeError);
assertFalse(generator.hasOwnProperty("caller"));
assertThrows(function() { return generator.caller; }, TypeError);
assertThrows(function() { return generator.caller = {}; }, TypeError);
})();
(function testRestrictedPropertiesSloppy() {
function* generator() {}
assertFalse(generator.hasOwnProperty("arguments"));
assertThrows(function() { return generator.arguments; }, TypeError);
assertThrows(function() { return generator.arguments = {}; }, TypeError);
assertFalse(generator.hasOwnProperty("caller"));
assertThrows(function() { return generator.caller; }, TypeError);
assertThrows(function() { return generator.caller = {}; }, TypeError);
})();
function assertIteratorResult(value, done, result) { function assertIteratorResult(value, done, result) {
assertEquals({value: value, done: done}, result); assertEquals({value: value, done: done}, result);
} }
function test(f) {
var cdesc = Object.getOwnPropertyDescriptor(f, "caller");
var adesc = Object.getOwnPropertyDescriptor(f, "arguments");
assertFalse(cdesc.enumerable); (function testIteratorResultStrict() {
assertFalse(cdesc.configurable); function* generator() { "use strict"; }
assertIteratorResult(undefined, true, generator().next());
})();
assertFalse(adesc.enumerable);
assertFalse(adesc.configurable);
assertSame(cdesc.get, cdesc.set); (function testIteratorResultSloppy() {
assertSame(cdesc.get, adesc.get); function* generator() {}
assertSame(cdesc.get, adesc.set); assertIteratorResult(undefined, true, generator().next());
})();
assertTrue(cdesc.get instanceof Function);
assertEquals(0, cdesc.get.length);
assertThrows(cdesc.get, 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 *sloppy() { test(sloppy); }
function *strict() { "use strict"; test(strict); }
test(sloppy);
test(strict);
assertIteratorResult(undefined, true, sloppy().next());
assertIteratorResult(undefined, true, strict().next());

View File

@ -30,7 +30,7 @@
// See: // See:
// http://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorfunction-objects // http://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorfunction-objects
function f() { } function f() { "use strict"; }
function* g() { yield 1; } function* g() { yield 1; }
var GeneratorFunctionPrototype = Object.getPrototypeOf(g); var GeneratorFunctionPrototype = Object.getPrototypeOf(g);
var GeneratorFunction = GeneratorFunctionPrototype.constructor; var GeneratorFunction = GeneratorFunctionPrototype.constructor;
@ -51,18 +51,16 @@ function TestGeneratorFunctionInstance() {
var prop = f_own_property_names[i]; var prop = f_own_property_names[i];
var f_desc = Object.getOwnPropertyDescriptor(f, prop); var f_desc = Object.getOwnPropertyDescriptor(f, prop);
var g_desc = Object.getOwnPropertyDescriptor(g, prop); var g_desc = Object.getOwnPropertyDescriptor(g, prop);
assertEquals(f_desc.configurable, g_desc.configurable, prop); if (prop === "prototype") {
if (prop === 'arguments' || prop === 'caller') { // ES6 draft 03-17-2015 section 25.2.2.2
// Unlike sloppy functions, which have read-only data arguments and caller assertFalse(g_desc.writable, prop);
// properties, sloppy generators have a poison pill implemented via assertFalse(g_desc.enumerable, prop);
// accessors assertFalse(g_desc.configurable, prop);
assertFalse('writable' in g_desc, prop);
assertTrue(g_desc.get instanceof Function, prop);
assertEquals(g_desc.get, g_desc.set, prop);
} else { } else {
assertEquals(f_desc.configurable, g_desc.configurable, prop);
assertEquals(f_desc.writable, g_desc.writable, 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(); TestGeneratorFunctionInstance();

View File

@ -268,14 +268,18 @@ assertEquals([true, 0, undefined], s());
// Check that property descriptors are correct (unconfigurable, unenumerable, // Check that property descriptors are correct (unconfigurable, unenumerable,
// and both get and set is the ThrowTypeError function). // 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.enumerable);
assertFalse(cdesc.configurable); assertTrue(cdesc.configurable);
assertFalse(adesc.enumerable); assertFalse(adesc.enumerable);
assertFalse(adesc.configurable); assertTrue(adesc.configurable);
assertSame(cdesc.get, cdesc.set); assertSame(cdesc.get, cdesc.set);
assertSame(cdesc.get, adesc.get); assertSame(cdesc.get, adesc.get);

View File

@ -47,3 +47,26 @@ var fives = [];
if (v % 5 === 0) fives.push(v); if (v % 5 === 0) fives.push(v);
}); });
assertEquals([5, 10], fives); 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);
})();

View File

@ -875,3 +875,69 @@ function assertAccessorDescriptor(object, name) {
}; };
new C3(); 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(); } });
})();

View File

@ -83,9 +83,8 @@ function ID(x) {
// TODO(arv): It is not clear that we are adding the "standard" properties // 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 // in the right order. As far as I can tell the spec adds them in alphabetical
// order. // order.
assertArrayEquals(['length', 'name', 'arguments', 'caller', 'prototype', assertArrayEquals(['length', 'name', 'prototype', 'a', 'b', 'c', 'd'],
'a', 'b', 'c', 'd'], Object.getOwnPropertyNames(C));
Object.getOwnPropertyNames(C));
})(); })();
@ -102,8 +101,8 @@ function ID(x) {
assertEquals('D', C[2]()); assertEquals('D', C[2]());
// Array indexes first. // Array indexes first.
assertArrayEquals([], Object.keys(C)); assertArrayEquals([], Object.keys(C));
assertArrayEquals(['1', '2', 'length', 'name', 'arguments', 'caller', assertArrayEquals(['1', '2', 'length', 'name', 'prototype', 'a', 'c'],
'prototype', 'a', 'c'], Object.getOwnPropertyNames(C)); Object.getOwnPropertyNames(C));
})(); })();
@ -121,9 +120,8 @@ function ID(x) {
assertEquals('C', C.c()); assertEquals('C', C.c());
assertEquals('D', C[sym2]()); assertEquals('D', C[sym2]());
assertArrayEquals([], Object.keys(C)); assertArrayEquals([], Object.keys(C));
assertArrayEquals(['length', 'name', 'arguments', 'caller', 'prototype', assertArrayEquals(['length', 'name', 'prototype', 'a', 'c'],
'a', 'c'], Object.getOwnPropertyNames(C));
Object.getOwnPropertyNames(C));
assertArrayEquals([sym1, sym2], Object.getOwnPropertySymbols(C)); assertArrayEquals([sym1, sym2], Object.getOwnPropertySymbols(C));
})(); })();

View File

@ -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() { (function TestToString() {
var object = { var object = {
method() { 42; } method() { 42; }

View File

@ -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) { function CheckPill(pill) {
assertEquals("function", typeof pill); assertEquals("function", typeof pill);
@ -1056,12 +1084,12 @@ function CheckPillDescriptor(func, name) {
assertThrows(function() { third.caller = 42; }, TypeError); assertThrows(function() { third.caller = 42; }, TypeError);
assertThrows(function() { third.arguments = 42; }, TypeError); assertThrows(function() { third.arguments = 42; }, TypeError);
CheckPillDescriptor(strict, "caller"); CheckFunctionPillDescriptor(strict, "caller");
CheckPillDescriptor(strict, "arguments"); CheckFunctionPillDescriptor(strict, "arguments");
CheckPillDescriptor(another, "caller"); CheckFunctionPillDescriptor(another, "caller");
CheckPillDescriptor(another, "arguments"); CheckFunctionPillDescriptor(another, "arguments");
CheckPillDescriptor(third, "caller"); CheckFunctionPillDescriptor(third, "caller");
CheckPillDescriptor(third, "arguments"); CheckFunctionPillDescriptor(third, "arguments");
})(); })();
@ -1093,15 +1121,15 @@ function CheckPillDescriptor(func, name) {
} }
var args = strict(); var args = strict();
CheckPillDescriptor(args, "caller"); CheckArgumentsPillDescriptor(args, "caller");
CheckPillDescriptor(args, "callee"); CheckArgumentsPillDescriptor(args, "callee");
args = strict(17, "value", strict); args = strict(17, "value", strict);
assertEquals(17, args[0]) assertEquals(17, args[0])
assertEquals("value", args[1]) assertEquals("value", args[1])
assertEquals(strict, args[2]); assertEquals(strict, args[2]);
CheckPillDescriptor(args, "caller"); CheckArgumentsPillDescriptor(args, "caller");
CheckPillDescriptor(args, "callee"); CheckArgumentsPillDescriptor(args, "callee");
function outer() { function outer() {
"use strict"; "use strict";
@ -1112,15 +1140,15 @@ function CheckPillDescriptor(func, name) {
} }
var args = outer()(); var args = outer()();
CheckPillDescriptor(args, "caller"); CheckArgumentsPillDescriptor(args, "caller");
CheckPillDescriptor(args, "callee"); CheckArgumentsPillDescriptor(args, "callee");
args = outer()(17, "value", strict); args = outer()(17, "value", strict);
assertEquals(17, args[0]) assertEquals(17, args[0])
assertEquals("value", args[1]) assertEquals("value", args[1])
assertEquals(strict, args[2]); assertEquals(strict, args[2]);
CheckPillDescriptor(args, "caller"); CheckArgumentsPillDescriptor(args, "caller");
CheckPillDescriptor(args, "callee"); CheckArgumentsPillDescriptor(args, "callee");
})(); })();

View File

@ -595,6 +595,25 @@
# 'es6/String.prototype.contains/String.prototype.contains_Success' : [FAIL_OK], # 'es6/String.prototype.contains/String.prototype.contains_Success' : [FAIL_OK],
# 'es6/String.prototype.contains/String.prototype.contains_SuccessNoLocation' : [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 ############################# ############################ SKIPPED TESTS #############################
# These tests take a looong time to run in debug mode. # These tests take a looong time to run in debug mode.

View File

@ -263,6 +263,24 @@
'S15.7.4.5_A1.1_T01': [FAIL], 'S15.7.4.5_A1.1_T01': [FAIL],
'S15.7.4_A1': [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 ########################### ######################## NEEDS INVESTIGATION ###########################
# These test failures are specific to the intl402 suite and need investigation # These test failures are specific to the intl402 suite and need investigation

View File

@ -38,12 +38,12 @@ PASS getSortedOwnPropertyNames(parseInt) is ['arguments', 'caller', 'length', 'n
PASS getSortedOwnPropertyNames(parseFloat) is ['arguments', 'caller', 'length', 'name'] PASS getSortedOwnPropertyNames(parseFloat) is ['arguments', 'caller', 'length', 'name']
PASS getSortedOwnPropertyNames(isNaN) is ['arguments', 'caller', 'length', 'name'] PASS getSortedOwnPropertyNames(isNaN) is ['arguments', 'caller', 'length', 'name']
PASS getSortedOwnPropertyNames(isFinite) is ['arguments', 'caller', 'length', 'name'] PASS getSortedOwnPropertyNames(isFinite) is ['arguments', 'caller', 'length', 'name']
PASS getSortedOwnPropertyNames(escape) is ['arguments', 'caller', 'length', 'name'] PASS getSortedOwnPropertyNames(escape) is ['length', 'name']
PASS getSortedOwnPropertyNames(unescape) is ['arguments', 'caller', 'length', 'name'] PASS getSortedOwnPropertyNames(unescape) is ['length', 'name']
PASS getSortedOwnPropertyNames(decodeURI) is ['arguments', 'caller', 'length', 'name'] PASS getSortedOwnPropertyNames(decodeURI) is ['length', 'name']
PASS getSortedOwnPropertyNames(decodeURIComponent) is ['arguments', 'caller', 'length', 'name'] PASS getSortedOwnPropertyNames(decodeURIComponent) is ['length', 'name']
PASS getSortedOwnPropertyNames(encodeURI) is ['arguments', 'caller', 'length', 'name'] PASS getSortedOwnPropertyNames(encodeURI) is ['length', 'name']
PASS getSortedOwnPropertyNames(encodeURIComponent) is ['arguments', 'caller', '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) 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(Object.prototype) is ['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']
PASS getSortedOwnPropertyNames(Function) is ['arguments', 'caller', 'length', 'name', 'prototype'] PASS getSortedOwnPropertyNames(Function) is ['arguments', 'caller', 'length', 'name', 'prototype']

View File

@ -64,12 +64,12 @@ var expectedPropertyNamesSet = {
"parseFloat": "['arguments', 'caller', 'length', 'name']", "parseFloat": "['arguments', 'caller', 'length', 'name']",
"isNaN": "['arguments', 'caller', 'length', 'name']", "isNaN": "['arguments', 'caller', 'length', 'name']",
"isFinite": "['arguments', 'caller', 'length', 'name']", "isFinite": "['arguments', 'caller', 'length', 'name']",
"escape": "['arguments', 'caller', 'length', 'name']", "escape": "['length', 'name']",
"unescape": "['arguments', 'caller', 'length', 'name']", "unescape": "['length', 'name']",
"decodeURI": "['arguments', 'caller', 'length', 'name']", "decodeURI": "['length', 'name']",
"decodeURIComponent": "['arguments', 'caller', 'length', 'name']", "decodeURIComponent": "['length', 'name']",
"encodeURI": "['arguments', 'caller', 'length', 'name']", "encodeURI": "['length', 'name']",
"encodeURIComponent": "['arguments', 'caller', 'length', 'name']", "encodeURIComponent": "['length', 'name']",
// Built-in ECMA objects // 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": "['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']", "Object.prototype": "['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']",

View File

@ -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(){(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.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 (){'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.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', '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' 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', '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' 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', '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' 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.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 (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.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', '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' 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', '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' 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', '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' and 'arguments' are restricted function properties and cannot be accessed in this context..
PASS "caller" in function(){"use strict"} is true 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 "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 '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 (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.. 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 (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 '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 (){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.__proto__, '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__, '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, 'callee').value; })() is undefined.
PASS (function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(arguments, 'caller').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, '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(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.__proto__, '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__, 'arguments'); return descriptor.get === descriptor.set; })() is true
PASS 'use strict'; (function f() { for(var i in this); })(); true; 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 'use strict'̻ threw exception SyntaxError: Unexpected token ILLEGAL.
PASS (function(){'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 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
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] [native code]
}. Was function ThrowTypeError() { [native code] }. }. Was function ThrowTypeError() { [native code] }.
PASS successfullyParsed is true PASS successfullyParsed is true

View File

@ -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.arguments=5; })()");
shouldThrow("(function f(arg){'use strict'; f.caller=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('"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('"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 (){with(1){};})");
shouldBeSyntaxError("'use strict'; (function (){var a; delete a;})"); 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("'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; })()"); 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.__proto__, '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__, 'caller').value; })()");
shouldBeUndefined("(function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(arguments, 'callee').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; })()"); 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, '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(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.__proto__, '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__, 'arguments'); return descriptor.get === descriptor.set; })()");
shouldBeTrue("'use strict'; (function f() { for(var i in this); })(); true;") shouldBeTrue("'use strict'; (function f() { for(var i in this); })(); true;")
shouldBeSyntaxError("'use strict'\u033b"); shouldBeSyntaxError("'use strict'\u033b");
@ -228,4 +230,4 @@ aGlobal = false;
shouldBeTrue("(function () {try { throw 1; } catch (e) { aGlobal = true; }})(); aGlobal;"); shouldBeTrue("(function () {try { throw 1; } catch (e) { aGlobal = true; }})(); aGlobal;");
// Make sure this doesn't crash! // 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}'");

View File

@ -1,51 +0,0 @@
# 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

View File

@ -1,85 +0,0 @@
// 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"');

View File

@ -1,43 +0,0 @@
# 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

View File

@ -1,73 +0,0 @@
// 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;