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:
ager@chromium.org 2011-05-26 11:22:29 +00:00
parent f8b01f369e
commit c832c467a4
27 changed files with 102 additions and 207 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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_;

View File

@ -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:

View File

@ -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;
}

View File

@ -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());

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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.

View File

@ -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));
}

View File

@ -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

View File

@ -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();
}

View File

@ -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) \

View File

@ -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);
}

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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());

View File

@ -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"));
}

View File

@ -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]()"));

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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.