Revert "Pass undefined to JS builtins when called with implicit receiver."
Presubmit and failing test. TBR=lrn@chromium.org BUG= TEST= Review URL: http://codereview.chromium.org/7071009 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8075 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
f8b01f369e
commit
c832c467a4
@ -1255,7 +1255,8 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
|
||||
__ b(ne, &shift_arguments);
|
||||
|
||||
// Do not transform the receiver for native (Compilerhints already in r3).
|
||||
__ tst(r3, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
|
||||
__ tst(r3, Operand(1 << (SharedFunctionInfo::kES5Native +
|
||||
kSmiTagSize)));
|
||||
__ b(ne, &shift_arguments);
|
||||
|
||||
// Compute the receiver in non-strict mode.
|
||||
@ -1439,7 +1440,8 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
|
||||
__ b(ne, &push_receiver);
|
||||
|
||||
// Do not transform the receiver for strict mode functions.
|
||||
__ tst(r2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
|
||||
__ tst(r2, Operand(1 << (SharedFunctionInfo::kES5Native +
|
||||
kSmiTagSize)));
|
||||
__ b(ne, &push_receiver);
|
||||
|
||||
// Compute the receiver in non-strict mode.
|
||||
|
@ -139,11 +139,11 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Strict mode functions and builtins need to replace the receiver
|
||||
// with undefined when called as functions (without an explicit
|
||||
// receiver object). r5 is zero for method calls and non-zero for
|
||||
// function calls.
|
||||
if (info->is_strict_mode() || info->is_native()) {
|
||||
// Strict mode functions need to replace the receiver with undefined
|
||||
// when called as functions (without an explicit receiver
|
||||
// object). r5 is zero for method calls and non-zero for function
|
||||
// calls.
|
||||
if (info->is_strict_mode()) {
|
||||
Label ok;
|
||||
__ cmp(r5, Operand(0));
|
||||
__ b(eq, &ok);
|
||||
|
@ -146,11 +146,11 @@ bool LCodeGen::GeneratePrologue() {
|
||||
// fp: Caller's frame pointer.
|
||||
// lr: Caller's pc.
|
||||
|
||||
// Strict mode functions and builtins need to replace the receiver
|
||||
// with undefined when called as functions (without an explicit
|
||||
// receiver object). r5 is zero for method calls and non-zero for
|
||||
// function calls.
|
||||
if (info_->is_strict_mode() || info_->is_native()) {
|
||||
// Strict mode functions need to replace the receiver with undefined
|
||||
// when called as functions (without an explicit receiver
|
||||
// object). r5 is zero for method calls and non-zero for function
|
||||
// calls.
|
||||
if (info_->is_strict_mode()) {
|
||||
Label ok;
|
||||
__ cmp(r5, Operand(0));
|
||||
__ b(eq, &ok);
|
||||
|
@ -508,10 +508,7 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
|
||||
info.MarkAsGlobal();
|
||||
info.SetExtension(extension);
|
||||
info.SetPreParseData(pre_data);
|
||||
if (natives == NATIVES_CODE) {
|
||||
info.MarkAsAllowingNativesSyntax();
|
||||
info.MarkAsNative();
|
||||
}
|
||||
if (natives == NATIVES_CODE) info.MarkAsAllowingNativesSyntax();
|
||||
result = MakeFunctionInfo(&info);
|
||||
if (extension == NULL && !result.is_null()) {
|
||||
compilation_cache->PutScript(source, result);
|
||||
@ -680,7 +677,6 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
|
||||
info.SetFunction(literal);
|
||||
info.SetScope(literal->scope());
|
||||
if (literal->scope()->is_strict_mode()) info.MarkAsStrictMode();
|
||||
if (script->type()->value() == Script::TYPE_NATIVE) info.MarkAsNative();
|
||||
|
||||
LiveEditFunctionTracker live_edit_tracker(info.isolate(), literal);
|
||||
// Determine if the function can be lazily compiled. This is necessary to
|
||||
|
@ -89,12 +89,6 @@ class CompilationInfo BASE_EMBEDDED {
|
||||
bool allows_natives_syntax() const {
|
||||
return IsNativesSyntaxAllowed::decode(flags_);
|
||||
}
|
||||
void MarkAsNative() {
|
||||
flags_ |= IsNative::encode(true);
|
||||
}
|
||||
bool is_native() const {
|
||||
return IsNative::decode(flags_);
|
||||
}
|
||||
void SetFunction(FunctionLiteral* literal) {
|
||||
ASSERT(function_ == NULL);
|
||||
function_ = literal;
|
||||
@ -173,11 +167,9 @@ class CompilationInfo BASE_EMBEDDED {
|
||||
|
||||
void Initialize(Mode mode) {
|
||||
mode_ = V8::UseCrankshaft() ? mode : NONOPT;
|
||||
if (!shared_info_.is_null()) {
|
||||
if (shared_info_->strict_mode()) MarkAsStrictMode();
|
||||
if (shared_info_->native()) MarkAsNative();
|
||||
if (!shared_info_.is_null() && shared_info_->strict_mode()) {
|
||||
MarkAsStrictMode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SetMode(Mode mode) {
|
||||
@ -199,9 +191,6 @@ class CompilationInfo BASE_EMBEDDED {
|
||||
class IsStrictMode: public BitField<bool, 4, 1> {};
|
||||
// Native syntax (%-stuff) allowed?
|
||||
class IsNativesSyntaxAllowed: public BitField<bool, 5, 1> {};
|
||||
// Is this a function from our natives.
|
||||
class IsNative: public BitField<bool, 6, 1> {};
|
||||
|
||||
|
||||
unsigned flags_;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
||||
// Copyright 2009 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
|
@ -2388,7 +2388,7 @@ MaybeObject* Heap::AllocateSharedFunctionInfo(Object* name) {
|
||||
share->set_num_literals(0);
|
||||
share->set_end_position(0);
|
||||
share->set_function_token_position(0);
|
||||
share->set_native(false);
|
||||
share->set_es5_native(false);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -5906,11 +5906,10 @@ HEnvironment* HEnvironment::CopyForInlining(
|
||||
inner->SetValueAt(i, push);
|
||||
}
|
||||
}
|
||||
// If the function we are inlining is a strict mode function or a
|
||||
// builtin function, pass undefined as the receiver for function
|
||||
// calls (instead of the global receiver).
|
||||
if ((target->shared()->native() || function->strict_mode()) &&
|
||||
call_kind == CALL_AS_FUNCTION) {
|
||||
// If the function we are inlining is a strict mode function, pass
|
||||
// undefined as the receiver for function calls (instead of the
|
||||
// global receiver).
|
||||
if (function->strict_mode() && call_kind == CALL_AS_FUNCTION) {
|
||||
inner->SetValueAt(0, undefined);
|
||||
}
|
||||
inner->SetValueAt(arity + 1, outer->LookupContext());
|
||||
|
@ -613,8 +613,8 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
|
||||
__ j(not_equal, &shift_arguments);
|
||||
|
||||
// Do not transform the receiver for natives (shared already in ebx).
|
||||
__ test_b(FieldOperand(ebx, SharedFunctionInfo::kNativeByteOffset),
|
||||
1 << SharedFunctionInfo::kNativeBitWithinByte);
|
||||
__ test_b(FieldOperand(ebx, SharedFunctionInfo::kES5NativeByteOffset),
|
||||
1 << SharedFunctionInfo::kES5NativeBitWithinByte);
|
||||
__ j(not_equal, &shift_arguments);
|
||||
|
||||
// Compute the receiver in non-strict mode.
|
||||
@ -777,8 +777,8 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
|
||||
Factory* factory = masm->isolate()->factory();
|
||||
|
||||
// Do not transform the receiver for natives (shared already in ecx).
|
||||
__ test_b(FieldOperand(ecx, SharedFunctionInfo::kNativeByteOffset),
|
||||
1 << SharedFunctionInfo::kNativeBitWithinByte);
|
||||
__ test_b(FieldOperand(ecx, SharedFunctionInfo::kES5NativeByteOffset),
|
||||
1 << SharedFunctionInfo::kES5NativeBitWithinByte);
|
||||
__ j(not_equal, &push_receiver);
|
||||
|
||||
// Compute the receiver in non-strict mode.
|
||||
|
@ -131,11 +131,11 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Strict mode functions and builtins need to replace the receiver
|
||||
// with undefined when called as functions (without an explicit
|
||||
// receiver object). ecx is zero for method calls and non-zero for
|
||||
// function calls.
|
||||
if (info->is_strict_mode() || info->is_native()) {
|
||||
// Strict mode functions need to replace the receiver with undefined
|
||||
// when called as functions (without an explicit receiver
|
||||
// object). ecx is zero for method calls and non-zero for function
|
||||
// calls.
|
||||
if (info->is_strict_mode()) {
|
||||
Label ok;
|
||||
__ test(ecx, Operand(ecx));
|
||||
__ j(zero, &ok, Label::kNear);
|
||||
|
@ -128,11 +128,11 @@ bool LCodeGen::GeneratePrologue() {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Strict mode functions and builtins need to replace the receiver
|
||||
// with undefined when called as functions (without an explicit
|
||||
// receiver object). ecx is zero for method calls and non-zero for
|
||||
// function calls.
|
||||
if (info_->is_strict_mode() || info_->is_native()) {
|
||||
// Strict mode functions need to replace the receiver with undefined
|
||||
// when called as functions (without an explicit receiver
|
||||
// object). ecx is zero for method calls and non-zero for function
|
||||
// calls.
|
||||
if (info_->is_strict_mode()) {
|
||||
Label ok;
|
||||
__ test(ecx, Operand(ecx));
|
||||
__ j(zero, &ok, Label::kNear);
|
||||
|
@ -1214,7 +1214,8 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
|
||||
__ Branch(&shift_arguments, ne, t0, Operand(zero_reg));
|
||||
|
||||
// Do not transform the receiver for native (Compilerhints already in a3).
|
||||
__ And(t0, a3, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
|
||||
__ And(t0, a3, Operand(1 << (SharedFunctionInfo::kES5Native +
|
||||
kSmiTagSize)));
|
||||
__ Branch(&shift_arguments, ne, t0, Operand(zero_reg));
|
||||
|
||||
// Compute the receiver in non-strict mode.
|
||||
@ -1400,7 +1401,8 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
|
||||
__ Branch(&push_receiver, ne, t0, Operand(zero_reg));
|
||||
|
||||
// Do not transform the receiver for native (Compilerhints already in a2).
|
||||
__ And(t0, a2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
|
||||
__ And(t0, a2, Operand(1 << (SharedFunctionInfo::kES5Native +
|
||||
kSmiTagSize)));
|
||||
__ Branch(&push_receiver, ne, t0, Operand(zero_reg));
|
||||
|
||||
// Compute the receiver in non-strict mode.
|
||||
|
@ -3309,14 +3309,14 @@ void SharedFunctionInfo::set_strict_mode(bool value) {
|
||||
}
|
||||
|
||||
|
||||
bool SharedFunctionInfo::native() {
|
||||
return BooleanBit::get(compiler_hints(), kNative);
|
||||
bool SharedFunctionInfo::es5_native() {
|
||||
return BooleanBit::get(compiler_hints(), kES5Native);
|
||||
}
|
||||
|
||||
|
||||
void SharedFunctionInfo::set_native(bool value) {
|
||||
void SharedFunctionInfo::set_es5_native(bool value) {
|
||||
set_compiler_hints(BooleanBit::set(compiler_hints(),
|
||||
kNative,
|
||||
kES5Native,
|
||||
value));
|
||||
}
|
||||
|
||||
|
@ -4406,12 +4406,12 @@ class SharedFunctionInfo: public HeapObject {
|
||||
inline bool strict_mode();
|
||||
inline void set_strict_mode(bool value);
|
||||
|
||||
// Indicates whether the function is a native function.
|
||||
// Indicates whether the function is a native ES5 function.
|
||||
// These needs special threatment in .call and .apply since
|
||||
// null passed as the receiver should not be translated to the
|
||||
// global object.
|
||||
inline bool native();
|
||||
inline void set_native(bool value);
|
||||
inline bool es5_native();
|
||||
inline void set_es5_native(bool value);
|
||||
|
||||
// Indicates whether or not the code in the shared function support
|
||||
// deoptimization.
|
||||
@ -4598,7 +4598,7 @@ class SharedFunctionInfo: public HeapObject {
|
||||
static const int kCodeAgeMask = 0x7;
|
||||
static const int kOptimizationDisabled = 6;
|
||||
static const int kStrictModeFunction = 7;
|
||||
static const int kNative = 8;
|
||||
static const int kES5Native = 8;
|
||||
|
||||
private:
|
||||
#if V8_HOST_ARCH_32_BIT
|
||||
@ -4613,26 +4613,26 @@ class SharedFunctionInfo: public HeapObject {
|
||||
|
||||
public:
|
||||
// Constants for optimizing codegen for strict mode function and
|
||||
// native tests.
|
||||
// es5 native tests.
|
||||
// Allows to use byte-widgh instructions.
|
||||
static const int kStrictModeBitWithinByte =
|
||||
(kStrictModeFunction + kCompilerHintsSmiTagSize) % kBitsPerByte;
|
||||
|
||||
static const int kNativeBitWithinByte =
|
||||
(kNative + kCompilerHintsSmiTagSize) % kBitsPerByte;
|
||||
static const int kES5NativeBitWithinByte =
|
||||
(kES5Native + kCompilerHintsSmiTagSize) % kBitsPerByte;
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
static const int kStrictModeByteOffset = kCompilerHintsOffset +
|
||||
(kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte;
|
||||
static const int kNativeByteOffset = kCompilerHintsOffset +
|
||||
(kNative + kCompilerHintsSmiTagSize) / kBitsPerByte;
|
||||
static const int kES5NativeByteOffset = kCompilerHintsOffset +
|
||||
(kES5Native + kCompilerHintsSmiTagSize) / kBitsPerByte;
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
static const int kStrictModeByteOffset = kCompilerHintsOffset +
|
||||
(kCompilerHintsSize - 1) -
|
||||
((kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte);
|
||||
static const int kNativeByteOffset = kCompilerHintsOffset +
|
||||
static const int kES5NativeByteOffset = kCompilerHintsOffset +
|
||||
(kCompilerHintsSize - 1) -
|
||||
((kNative + kCompilerHintsSmiTagSize) / kBitsPerByte);
|
||||
((kES5Native + kCompilerHintsSmiTagSize) / kBitsPerByte);
|
||||
#else
|
||||
#error Unknown byte ordering
|
||||
#endif
|
||||
|
@ -4120,10 +4120,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) {
|
||||
}
|
||||
|
||||
|
||||
// Set the native flag on the function.
|
||||
// Set the ES5 native flag on the function.
|
||||
// This is used to decide if we should transform null and undefined
|
||||
// into the global object when doing call and apply.
|
||||
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) {
|
||||
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetES5Flag) {
|
||||
NoHandleAllocation ha;
|
||||
RUNTIME_ASSERT(args.length() == 1);
|
||||
|
||||
@ -4131,7 +4131,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) {
|
||||
|
||||
if (object->IsJSFunction()) {
|
||||
JSFunction* func = JSFunction::cast(*object);
|
||||
func->shared()->set_native(true);
|
||||
func->shared()->set_es5_native(true);
|
||||
}
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
||||
// Copyright 2010 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
@ -92,7 +92,7 @@ namespace internal {
|
||||
F(CompileForOnStackReplacement, 1, 1) \
|
||||
F(SetNewFunctionAttributes, 1, 1) \
|
||||
F(AllocateInNewSpace, 1, 1) \
|
||||
F(SetNativeFlag, 1, 1) \
|
||||
F(SetES5Flag, 1, 1) \
|
||||
\
|
||||
/* Array join support */ \
|
||||
F(PushIfAbsent, 2, 1) \
|
||||
|
@ -56,7 +56,7 @@ function InstallFunctions(object, attributes, functions) {
|
||||
%FunctionSetName(f, key);
|
||||
%FunctionRemovePrototype(f);
|
||||
%SetProperty(object, key, f, attributes);
|
||||
%SetNativeFlag(f);
|
||||
%SetES5Flag(f);
|
||||
}
|
||||
%ToFastProperties(object);
|
||||
}
|
||||
@ -132,19 +132,10 @@ function GlobalParseFloat(string) {
|
||||
function GlobalEval(x) {
|
||||
if (!IS_STRING(x)) return x;
|
||||
|
||||
var receiver = this;
|
||||
var global_receiver = %GlobalReceiver(global);
|
||||
|
||||
if (receiver == null && !IS_UNDETECTABLE(receiver)) {
|
||||
receiver = global_receiver;
|
||||
}
|
||||
|
||||
var this_is_global_receiver = (receiver === global_receiver);
|
||||
var this_is_global_receiver = (this === global_receiver);
|
||||
var global_is_detached = (global === global_receiver);
|
||||
|
||||
// For consistency with JSC we require the global object passed to
|
||||
// eval to be the global object from which 'eval' originated. This
|
||||
// is not mandated by the spec.
|
||||
if (!this_is_global_receiver || global_is_detached) {
|
||||
throw new $EvalError('The "this" object passed to eval must ' +
|
||||
'be the global object from which eval originated');
|
||||
@ -153,7 +144,7 @@ function GlobalEval(x) {
|
||||
var f = %CompileString(x);
|
||||
if (!IS_FUNCTION(f)) return f;
|
||||
|
||||
return %_CallFunction(receiver, f);
|
||||
return %_CallFunction(this, f);
|
||||
}
|
||||
|
||||
|
||||
@ -255,9 +246,8 @@ function ObjectPropertyIsEnumerable(V) {
|
||||
|
||||
// Extensions for providing property getters and setters.
|
||||
function ObjectDefineGetter(name, fun) {
|
||||
var receiver = this;
|
||||
if (receiver == null && !IS_UNDETECTABLE(receiver)) {
|
||||
receiver = %GlobalReceiver(global);
|
||||
if (this == null && !IS_UNDETECTABLE(this)) {
|
||||
throw new $TypeError('Object.prototype.__defineGetter__: this is Null');
|
||||
}
|
||||
if (!IS_FUNCTION(fun)) {
|
||||
throw new $TypeError('Object.prototype.__defineGetter__: Expecting function');
|
||||
@ -266,23 +256,21 @@ function ObjectDefineGetter(name, fun) {
|
||||
desc.setGet(fun);
|
||||
desc.setEnumerable(true);
|
||||
desc.setConfigurable(true);
|
||||
DefineOwnProperty(ToObject(receiver), ToString(name), desc, false);
|
||||
DefineOwnProperty(ToObject(this), ToString(name), desc, false);
|
||||
}
|
||||
|
||||
|
||||
function ObjectLookupGetter(name) {
|
||||
var receiver = this;
|
||||
if (receiver == null && !IS_UNDETECTABLE(receiver)) {
|
||||
receiver = %GlobalReceiver(global);
|
||||
if (this == null && !IS_UNDETECTABLE(this)) {
|
||||
throw new $TypeError('Object.prototype.__lookupGetter__: this is Null');
|
||||
}
|
||||
return %LookupAccessor(ToObject(receiver), ToString(name), GETTER);
|
||||
return %LookupAccessor(ToObject(this), ToString(name), GETTER);
|
||||
}
|
||||
|
||||
|
||||
function ObjectDefineSetter(name, fun) {
|
||||
var receiver = this;
|
||||
if (receiver == null && !IS_UNDETECTABLE(receiver)) {
|
||||
receiver = %GlobalReceiver(global);
|
||||
if (this == null && !IS_UNDETECTABLE(this)) {
|
||||
throw new $TypeError('Object.prototype.__defineSetter__: this is Null');
|
||||
}
|
||||
if (!IS_FUNCTION(fun)) {
|
||||
throw new $TypeError(
|
||||
@ -292,16 +280,15 @@ function ObjectDefineSetter(name, fun) {
|
||||
desc.setSet(fun);
|
||||
desc.setEnumerable(true);
|
||||
desc.setConfigurable(true);
|
||||
DefineOwnProperty(ToObject(receiver), ToString(name), desc, false);
|
||||
DefineOwnProperty(ToObject(this), ToString(name), desc, false);
|
||||
}
|
||||
|
||||
|
||||
function ObjectLookupSetter(name) {
|
||||
var receiver = this;
|
||||
if (receiver == null && !IS_UNDETECTABLE(receiver)) {
|
||||
receiver = %GlobalReceiver(global);
|
||||
if (this == null && !IS_UNDETECTABLE(this)) {
|
||||
throw new $TypeError('Object.prototype.__lookupSetter__: this is Null');
|
||||
}
|
||||
return %LookupAccessor(ToObject(receiver), ToString(name), SETTER);
|
||||
return %LookupAccessor(ToObject(this), ToString(name), SETTER);
|
||||
}
|
||||
|
||||
|
||||
|
@ -673,8 +673,8 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
|
||||
|
||||
// Do not transform the receiver for natives.
|
||||
// SharedFunctionInfo is already loaded into rbx.
|
||||
__ testb(FieldOperand(rbx, SharedFunctionInfo::kNativeByteOffset),
|
||||
Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte));
|
||||
__ testb(FieldOperand(rbx, SharedFunctionInfo::kES5NativeByteOffset),
|
||||
Immediate(1 << SharedFunctionInfo::kES5NativeBitWithinByte));
|
||||
__ j(not_zero, &shift_arguments);
|
||||
|
||||
// Compute the receiver in non-strict mode.
|
||||
@ -844,8 +844,8 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
|
||||
__ j(not_equal, &push_receiver);
|
||||
|
||||
// Do not transform the receiver for natives.
|
||||
__ testb(FieldOperand(rdx, SharedFunctionInfo::kNativeByteOffset),
|
||||
Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte));
|
||||
__ testb(FieldOperand(rdx, SharedFunctionInfo::kES5NativeByteOffset),
|
||||
Immediate(1 << SharedFunctionInfo::kES5NativeBitWithinByte));
|
||||
__ j(not_zero, &push_receiver);
|
||||
|
||||
// Compute the receiver in non-strict mode.
|
||||
|
@ -131,11 +131,11 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Strict mode functions and builtins need to replace the receiver
|
||||
// with undefined when called as functions (without an explicit
|
||||
// receiver object). rcx is zero for method calls and non-zero for
|
||||
// function calls.
|
||||
if (info->is_strict_mode() || info->is_native()) {
|
||||
// Strict mode functions need to replace the receiver with undefined
|
||||
// when called as functions (without an explicit receiver
|
||||
// object). rcx is zero for method calls and non-zero for function
|
||||
// calls.
|
||||
if (info->is_strict_mode()) {
|
||||
Label ok;
|
||||
__ testq(rcx, rcx);
|
||||
__ j(zero, &ok, Label::kNear);
|
||||
|
@ -144,7 +144,7 @@ bool LCodeGen::GeneratePrologue() {
|
||||
// when called as functions (without an explicit receiver
|
||||
// object). rcx is zero for method calls and non-zero for function
|
||||
// calls.
|
||||
if (info_->is_strict_mode() || info_->is_native()) {
|
||||
if (info_->is_strict_mode()) {
|
||||
Label ok;
|
||||
__ testq(rcx, rcx);
|
||||
__ j(zero, &ok, Label::kNear);
|
||||
|
@ -6664,7 +6664,7 @@ THREADED_TEST(ShadowObject) {
|
||||
context->Global()->Set(v8_str("__proto__"), o);
|
||||
|
||||
Local<Value> value =
|
||||
Script::Compile(v8_str("this.propertyIsEnumerable(0)"))->Run();
|
||||
Script::Compile(v8_str("propertyIsEnumerable(0)"))->Run();
|
||||
CHECK(value->IsBoolean());
|
||||
CHECK(!value->BooleanValue());
|
||||
|
||||
|
@ -30,18 +30,18 @@ var setter_value = 0;
|
||||
__proto__.__defineSetter__("a", function(v) { setter_value = v; });
|
||||
eval("var a = 1");
|
||||
assertEquals(1, setter_value);
|
||||
assertFalse(this.hasOwnProperty("a"));
|
||||
assertFalse(hasOwnProperty("a"));
|
||||
|
||||
eval("with({}) { eval('var a = 2') }");
|
||||
assertEquals(2, setter_value);
|
||||
assertFalse(this.hasOwnProperty("a"));
|
||||
assertFalse(hasOwnProperty("a"));
|
||||
|
||||
// Function declarations are treated specially to match Safari. We do
|
||||
// not call setters for them.
|
||||
eval("function a() {}");
|
||||
assertTrue(this.hasOwnProperty("a"));
|
||||
assertTrue(hasOwnProperty("a"));
|
||||
|
||||
__proto__.__defineSetter__("b", function(v) { assertUnreachable(); });
|
||||
__proto__.__defineSetter__("b", function(v) { assertUnreachable(); });
|
||||
try {
|
||||
eval("const b = 23");
|
||||
assertUnreachable();
|
||||
@ -61,5 +61,6 @@ try {
|
||||
assertUnreachable();
|
||||
} catch(e) {
|
||||
assertEquals(42, e);
|
||||
assertFalse(this.hasOwnProperty("c"));
|
||||
assertFalse(hasOwnProperty("c"));
|
||||
}
|
||||
|
||||
|
@ -26,13 +26,13 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
assertEquals("[object global]", this.toString());
|
||||
assertEquals("[object Undefined]", toString());
|
||||
assertEquals("[object global]", toString());
|
||||
|
||||
assertEquals("[object global]", eval("this.toString()"));
|
||||
assertEquals("[object Undefined]", eval("toString()"));
|
||||
assertEquals("[object global]", eval("toString()"));
|
||||
|
||||
assertEquals("[object global]", eval("var f; this.toString()"));
|
||||
assertEquals("[object Undefined]", eval("var f; toString()"));
|
||||
assertEquals("[object global]", eval("var f; toString()"));
|
||||
|
||||
|
||||
function F(f) {
|
||||
@ -45,7 +45,7 @@ function F(f) {
|
||||
assertEquals("[object global]", eval("var f; this.toString()"));
|
||||
assertEquals("[object global]", eval("var f; toString()"));
|
||||
|
||||
assertEquals("[object Undefined]", eval("f()"));
|
||||
assertEquals("[object global]", eval("f()"));
|
||||
|
||||
// Receiver should be the arguments object here.
|
||||
assertEquals("[object Arguments]", eval("arguments[0]()"));
|
||||
|
@ -1,65 +0,0 @@
|
||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * 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.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
|
||||
// OWNER OR 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.
|
||||
|
||||
// See: http://code.google.com/p/v8/issues/detail?id=1365
|
||||
|
||||
// Check that builtin methods are passed undefined as the receiver
|
||||
// when called as functions through variables.
|
||||
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
// Global variable.
|
||||
var valueOf = Object.prototype.valueOf;
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
function callGlobalValueOf() { valueOf(); }
|
||||
function callGlobalHasOwnProperty() { valueOf(); }
|
||||
|
||||
assertEquals(Object.prototype, Object.prototype.valueOf());
|
||||
assertThrows(callGlobalValueOf);
|
||||
assertThrows(callGlobalHasOwnProperty);
|
||||
|
||||
%OptimizeFunctionOnNextCall(Object.prototype.valueOf);
|
||||
Object.prototype.valueOf();
|
||||
|
||||
assertEquals(Object.prototype, Object.prototype.valueOf());
|
||||
assertThrows(callGlobalValueOf);
|
||||
assertThrows(callGlobalHasOwnProperty);
|
||||
|
||||
function CheckExceptionCallLocal() {
|
||||
var valueOf = Object.prototype.valueOf;
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
try { valueOf(); assertUnreachable(); } catch(e) { }
|
||||
try { hasOwnProperty(); assertUnreachable(); } catch(e) { }
|
||||
}
|
||||
CheckExceptionCallLocal();
|
||||
|
||||
function CheckExceptionCallParameter(f) {
|
||||
try { f(); assertUnreachable(); } catch(e) { }
|
||||
}
|
||||
CheckExceptionCallParameter(Object.prototype.valueOf);
|
||||
CheckExceptionCallParameter(Object.prototype.hasOwnProperty);
|
@ -34,6 +34,11 @@ var global = this;
|
||||
var global2 = (function(){return this;})();
|
||||
assertEquals(global, global2, "direct call to local function returns global");
|
||||
|
||||
var builtin = Object.prototype.valueOf; // Builtin function that returns this.
|
||||
|
||||
assertEquals(global, builtin(), "Direct call to builtin");
|
||||
|
||||
|
||||
// Builtin that depends on value of this to compute result.
|
||||
var builtin2 = Object.prototype.toString;
|
||||
|
||||
|
@ -206,10 +206,6 @@ ecma_3/RegExp/regress-85721: PASS || FAIL if $mode == debug
|
||||
# This section is for tests that fail in both V8 and JSC. Thus they
|
||||
# have been determined to be incompatible between Mozilla and V8/JSC.
|
||||
|
||||
# Fail because it calls builtins as functions and do not expect the
|
||||
# builtin to have undefined as the receiver.
|
||||
ecma/String/15.5.4.6-2: FAIL_OK
|
||||
|
||||
# Fail because of toLowerCase and toUpperCase conversion.
|
||||
ecma/String/15.5.4.11-2: FAIL_OK
|
||||
ecma/String/15.5.4.11-5: FAIL_OK
|
||||
|
@ -175,23 +175,6 @@ S11.1.5_A4.2: FAIL_OK
|
||||
S9.9_A1: FAIL_OK
|
||||
S9.9_A2: FAIL_OK
|
||||
|
||||
# Calls builtins without an explicit receiver which means that
|
||||
# undefined is passed to the builtin. The tests expect the global
|
||||
# object to be passed which was true in ES3 but not in ES5.
|
||||
S11.1.1_A2: FAIL_OK
|
||||
S15.5.4.4_A1_T3: FAIL_OK
|
||||
S15.5.4.5_A1_T3: FAIL_OK
|
||||
S15.5.4.6_A1_T3: FAIL_OK
|
||||
S15.5.4.7_A1_T3: FAIL_OK
|
||||
S15.5.4.8_A1_T3: FAIL_OK
|
||||
S15.5.4.9_A1_T3: FAIL_OK
|
||||
S15.5.4.10_A1_T3: FAIL_OK
|
||||
S15.5.4.11_A1_T3: FAIL_OK
|
||||
S15.5.4.12_A1_T3: FAIL_OK
|
||||
S15.5.4.13_A1_T3: FAIL_OK
|
||||
S15.5.4.14_A1_T3: FAIL_OK
|
||||
S15.5.4.15_A1_T3: FAIL_OK
|
||||
|
||||
##################### SKIPPED TESTS #####################
|
||||
|
||||
# These tests take a looong time to run in debug mode.
|
||||
|
Loading…
Reference in New Issue
Block a user