[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:
parent
806e57f401
commit
9836c34dba
@ -135,15 +135,14 @@ class Genesis BASE_EMBEDDED {
|
||||
// Creates the empty function. Used for creating a context from scratch.
|
||||
Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
|
||||
// Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
|
||||
Handle<JSFunction> GetStrictPoisonFunction();
|
||||
// Poison for sloppy generator function arguments/callee.
|
||||
Handle<JSFunction> GetGeneratorPoisonFunction();
|
||||
Handle<JSFunction> GetRestrictedFunctionPropertiesThrower();
|
||||
Handle<JSFunction> GetStrictArgumentsPoisonFunction();
|
||||
|
||||
void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
|
||||
void CreateStrongModeFunctionMaps(Handle<JSFunction> empty);
|
||||
|
||||
// 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
|
||||
// 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> strict_function_map_writable_prototype_;
|
||||
Handle<JSFunction> strict_poison_function;
|
||||
Handle<JSFunction> generator_poison_function;
|
||||
Handle<JSFunction> restricted_function_properties_thrower;
|
||||
|
||||
BootstrapperActive active_;
|
||||
friend class Bootstrapper;
|
||||
@ -347,20 +346,25 @@ void Bootstrapper::DetachGlobal(Handle<Context> env) {
|
||||
|
||||
|
||||
static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
|
||||
const char* name,
|
||||
InstanceType type,
|
||||
const char* name, InstanceType type,
|
||||
int instance_size,
|
||||
MaybeHandle<JSObject> maybe_prototype,
|
||||
Builtins::Name call) {
|
||||
Builtins::Name call,
|
||||
bool strict_function_map = false) {
|
||||
Isolate* isolate = target->GetIsolate();
|
||||
Factory* factory = isolate->factory();
|
||||
Handle<String> internalized_name = factory->InternalizeUtf8String(name);
|
||||
Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call));
|
||||
Handle<JSObject> prototype;
|
||||
Handle<JSFunction> function = maybe_prototype.ToHandle(&prototype)
|
||||
? factory->NewFunction(internalized_name, call_code, prototype,
|
||||
type, instance_size)
|
||||
: factory->NewFunctionWithoutPrototype(internalized_name, call_code);
|
||||
static const bool kReadOnlyPrototype = false;
|
||||
static const bool kInstallConstructor = false;
|
||||
Handle<JSFunction> function =
|
||||
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;
|
||||
if (target->IsJSBuiltinsObject()) {
|
||||
attributes =
|
||||
@ -377,8 +381,8 @@ static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
|
||||
}
|
||||
|
||||
|
||||
void Genesis::SetFunctionInstanceDescriptor(
|
||||
Handle<Map> map, FunctionMode function_mode) {
|
||||
void Genesis::SetFunctionInstanceDescriptor(Handle<Map> map,
|
||||
FunctionMode function_mode) {
|
||||
int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4;
|
||||
Map::EnsureDescriptorSlack(map, size);
|
||||
|
||||
@ -460,7 +464,6 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
|
||||
// This map is installed in MakeFunctionInstancePrototypeWritable.
|
||||
sloppy_function_map_writable_prototype_ =
|
||||
CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE);
|
||||
|
||||
Factory* factory = isolate->factory();
|
||||
|
||||
Handle<String> object_name = factory->Object_string();
|
||||
@ -511,6 +514,7 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
|
||||
DCHECK(!empty_function_map->is_dictionary_map());
|
||||
empty_function_map->SetPrototype(object_function_prototype);
|
||||
empty_function_map->set_is_prototype_map(true);
|
||||
|
||||
empty_function->set_map(*empty_function_map);
|
||||
|
||||
// --- 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_without_prototype_map()->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;
|
||||
}
|
||||
|
||||
|
||||
void Genesis::SetStrictFunctionInstanceDescriptor(
|
||||
Handle<Map> map, FunctionMode function_mode) {
|
||||
void Genesis::SetStrictFunctionInstanceDescriptor(Handle<Map> map,
|
||||
FunctionMode function_mode) {
|
||||
int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4;
|
||||
Map::EnsureDescriptorSlack(map, size);
|
||||
|
||||
Handle<AccessorPair> arguments(factory()->NewAccessorPair());
|
||||
Handle<AccessorPair> caller(factory()->NewAccessorPair());
|
||||
PropertyAttributes rw_attribs =
|
||||
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
|
||||
PropertyAttributes ro_attribs =
|
||||
@ -567,16 +574,6 @@ void Genesis::SetStrictFunctionInstanceDescriptor(
|
||||
roc_attribs);
|
||||
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)) {
|
||||
// Add prototype.
|
||||
PropertyAttributes attribs =
|
||||
@ -615,12 +612,31 @@ void Genesis::SetStrongFunctionInstanceDescriptor(Handle<Map> map) {
|
||||
|
||||
|
||||
// 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()) {
|
||||
Handle<String> name = factory()->InternalizeOneByteString(
|
||||
STATIC_CHAR_VECTOR("ThrowTypeError"));
|
||||
Handle<Code> code(isolate()->builtins()->builtin(
|
||||
Builtins::kStrictModePoisonPill));
|
||||
Builtins::kRestrictedStrictArgumentsPropertiesThrower));
|
||||
strict_poison_function = factory()->NewFunctionWithoutPrototype(name, code);
|
||||
strict_poison_function->set_map(native_context()->sloppy_function_map());
|
||||
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(
|
||||
FunctionMode function_mode,
|
||||
Handle<JSFunction> empty_function) {
|
||||
FunctionMode function_mode, Handle<JSFunction> empty_function) {
|
||||
Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
|
||||
SetStrictFunctionInstanceDescriptor(map, 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.
|
||||
strict_function_map_writable_prototype_ =
|
||||
CreateStrictFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE, empty);
|
||||
|
||||
// Special map for bound functions.
|
||||
Handle<Map> bound_function_map =
|
||||
CreateStrictFunctionMap(BOUND_FUNCTION, empty);
|
||||
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,
|
||||
Handle<String> name,
|
||||
PropertyAttributes attributes,
|
||||
@ -734,9 +716,15 @@ static void ReplaceAccessors(Handle<Map> map,
|
||||
}
|
||||
|
||||
|
||||
void Genesis::PoisonArgumentsAndCaller(Handle<Map> map) {
|
||||
SetAccessors(map, factory()->arguments_string(), GetStrictPoisonFunction());
|
||||
SetAccessors(map, factory()->caller_string(), GetStrictPoisonFunction());
|
||||
void Genesis::AddRestrictedFunctionProperties(Handle<Map> map) {
|
||||
PropertyAttributes rw_attribs = static_cast<PropertyAttributes>(DONT_ENUM);
|
||||
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> caller = factory->NewAccessorPair();
|
||||
|
||||
Handle<JSFunction> poison = GetStrictPoisonFunction();
|
||||
Handle<JSFunction> poison = GetStrictArgumentsPoisonFunction();
|
||||
|
||||
// Install the ThrowTypeError functions.
|
||||
callee->set_getter(*poison);
|
||||
@ -2087,47 +2075,23 @@ bool Genesis::InstallNatives() {
|
||||
generator_object_prototype,
|
||||
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
|
||||
|
||||
static const bool kUseStrictFunctionMap = true;
|
||||
InstallFunction(builtins, "GeneratorFunction", JS_FUNCTION_TYPE,
|
||||
JSFunction::kSize, generator_function_prototype,
|
||||
Builtins::kIllegal);
|
||||
Builtins::kIllegal, kUseStrictFunctionMap);
|
||||
|
||||
// Create maps for generator functions and their prototypes. Store those
|
||||
// maps in the native context.
|
||||
Handle<Map> generator_function_map =
|
||||
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);
|
||||
|
||||
// maps in the native context. Generator functions do not have writable
|
||||
// prototypes, nor do they have "caller" or "arguments" accessors.
|
||||
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 =
|
||||
Map::Copy(strict_function_map, "StrictGeneratorFunction");
|
||||
// "arguments" and "caller" already poisoned.
|
||||
strict_generator_function_map->SetPrototype(generator_function_prototype);
|
||||
native_context()->set_strict_generator_function_map(
|
||||
*strict_generator_function_map);
|
||||
|
@ -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);
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
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)));
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
|
@ -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 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) {
|
||||
assertEquals({value: value, done: done}, result);
|
||||
}
|
||||
|
||||
function test(f) {
|
||||
var cdesc = Object.getOwnPropertyDescriptor(f, "caller");
|
||||
var adesc = Object.getOwnPropertyDescriptor(f, "arguments");
|
||||
|
||||
assertFalse(cdesc.enumerable);
|
||||
assertFalse(cdesc.configurable);
|
||||
(function testIteratorResultStrict() {
|
||||
function* generator() { "use strict"; }
|
||||
assertIteratorResult(undefined, true, generator().next());
|
||||
})();
|
||||
|
||||
assertFalse(adesc.enumerable);
|
||||
assertFalse(adesc.configurable);
|
||||
|
||||
assertSame(cdesc.get, cdesc.set);
|
||||
assertSame(cdesc.get, adesc.get);
|
||||
assertSame(cdesc.get, adesc.set);
|
||||
|
||||
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());
|
||||
(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}'");
|
||||
|
@ -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
|
||||
|
@ -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"');
|
@ -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
|
||||
|
@ -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;
|
Loading…
Reference in New Issue
Block a user