v8/test/mjsunit/compiler/receiver-conversion.js
mstarzinger 37f5e23b5c [turbofan] Fix receiver binding for inlined callees.
This introduces a JSConvertReceiver operator to model the implicit
conversion of receiver values for sloppy callees. It is used by the
JSInliner for now, but can also be used to model direction function
calls that bypass call stubs.

Also note that a hint is passed to said operator whenever the source
structure constrains the receiver value type. This hint allows for
optimizations in the lowering of the operator.

The underlying specification in ES6, section 9.2.1.2 is the basis for
this implementation.

R=bmeurer@chromium.org
TEST=mjsunit/compiler/receiver-conversion
BUG=v8:4493, v8:4470
LOG=n

Review URL: https://codereview.chromium.org/1412223015

Cr-Commit-Position: refs/heads/master@{#31598}
2015-10-27 12:13:49 +00:00

129 lines
3.0 KiB
JavaScript

// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
// This test suite checks that the receiver value (i.e. the 'this' binding) is
// correctly converted even when the callee function is inlined. This behavior
// is specified by ES6, section 9.2.1.2 "OrdinaryCallBindThis".
var global = this;
function test(outer, inner, check) {
check(outer());
check(outer());
%OptimizeFunctionOnNextCall(outer);
check(outer());
}
// -----------------------------------------------------------------------------
// Test undefined in sloppy mode.
(function UndefinedSloppy() {
function check(x) {
assertEquals("object", typeof x);
assertSame(global, x);
}
function inner(x) {
return this;
}
function outer() {
return sloppy();
}
global.sloppy = inner;
test(outer, inner, check);
})();
// -----------------------------------------------------------------------------
// Test undefined in strict mode.
(function UndefinedStrict() {
function check(x) {
assertEquals("undefined", typeof x);
assertSame(undefined, x);
}
function inner(x) {
"use strict";
return this;
}
function outer() {
return strict();
}
global.strict = inner;
test(outer, inner, check);
})();
// -----------------------------------------------------------------------------
// Test primitive number in sloppy mode.
(function NumberSloppy() {
function check(x) {
assertEquals("object", typeof x);
assertInstanceof(x, Number);
}
function inner(x) {
return this;
}
function outer() {
return (0).sloppy();
}
Number.prototype.sloppy = inner;
test(outer, inner, check);
})();
// -----------------------------------------------------------------------------
// Test primitive number in strict mode.
(function NumberStrict() {
function check(x) {
assertEquals("number", typeof x);
assertSame(0, x);
}
function inner(x) {
"use strict";
return this;
}
function outer() {
return (0).strict();
}
Number.prototype.strict = inner;
test(outer, inner, check);
})();
// -----------------------------------------------------------------------------
// Test primitive string in sloppy mode.
(function StringSloppy() {
function check(x) {
assertEquals("object", typeof x);
assertInstanceof(x, String);
}
function inner(x) {
return this;
}
function outer() {
return ("s").sloppy();
}
String.prototype.sloppy = inner;
test(outer, inner, check);
})();
// -----------------------------------------------------------------------------
// Test primitive string in strict mode.
(function StringStrict() {
function check(x) {
assertEquals("string", typeof x);
assertSame("s", x);
}
function inner(x) {
"use strict";
return this;
}
function outer() {
return ("s").strict();
}
String.prototype.strict = inner;
test(outer, inner, check);
})();