[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.
|
// 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);
|
||||||
|
@ -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)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -59,8 +59,8 @@ enum BuiltinExtraArguments {
|
|||||||
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) \
|
||||||
|
@ -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 :
|
||||||
|
@ -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,17 +1294,25 @@ 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) {
|
||||||
|
// 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_with_readonly_prototype_map()
|
||||||
: isolate()->sloppy_function_map();
|
: isolate()->sloppy_function_map();
|
||||||
Handle<JSFunction> result = NewFunction(map, name, code);
|
Handle<JSFunction> result = NewFunction(map, name, code);
|
||||||
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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."],
|
||||||
|
@ -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());
|
|
||||||
|
@ -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,19 +51,17 @@ 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();
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
})();
|
||||||
|
@ -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(); } });
|
||||||
|
})();
|
||||||
|
@ -83,8 +83,7 @@ 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,8 +120,7 @@ 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));
|
||||||
})();
|
})();
|
||||||
|
@ -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; }
|
||||||
|
@ -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");
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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']
|
||||||
|
@ -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']",
|
||||||
|
@ -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
|
||||||
|
@ -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}'");
|
||||||
|
@ -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