Ensure that bound functions does not have a prototype (fixes issue 794)

Review URL: http://codereview.chromium.org/7148014

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8293 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
ricow@chromium.org 2011-06-15 10:47:37 +00:00
parent 962c25bb49
commit 23d0aa614b
7 changed files with 64 additions and 5 deletions

View File

@ -3438,6 +3438,18 @@ void SharedFunctionInfo::set_native(bool value) {
}
bool SharedFunctionInfo::bound() {
return BooleanBit::get(compiler_hints(), kBoundFunction);
}
void SharedFunctionInfo::set_bound(bool value) {
set_compiler_hints(BooleanBit::set(compiler_hints(),
kBoundFunction,
value));
}
ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)

View File

@ -4597,6 +4597,11 @@ class SharedFunctionInfo: public HeapObject {
inline bool native();
inline void set_native(bool value);
// Indicates whether the function is a bound function created using
// the bind function.
inline bool bound();
inline void set_bound(bool value);
// Indicates whether or not the code in the shared function support
// deoptimization.
inline bool has_deoptimization_support();
@ -4783,6 +4788,7 @@ class SharedFunctionInfo: public HeapObject {
static const int kOptimizationDisabled = 6;
static const int kStrictModeFunction = 7;
static const int kNative = 8;
static const int kBoundFunction = 9;
private:
#if V8_HOST_ARCH_32_BIT

View File

@ -1855,6 +1855,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetName) {
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetBound) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_CHECKED(JSFunction, fun, args[0]);
fun->shared()->set_bound(true);
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionRemovePrototype) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
@ -7499,7 +7508,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) {
// If function should not have prototype, construction is not allowed. In this
// case generated code bailouts here, since function has no initial_map.
if (!function->should_have_prototype()) {
if (!function->should_have_prototype() && !function->shared()->bound()) {
Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
Handle<Object> type_error =
isolate->factory()->NewTypeError("not_constructor", arguments);

View File

@ -211,6 +211,7 @@ namespace internal {
F(FunctionSetPrototype, 2, 1) \
F(FunctionGetName, 1, 1) \
F(FunctionSetName, 2, 1) \
F(FunctionSetBound, 1, 1) \
F(FunctionRemovePrototype, 1, 1) \
F(FunctionGetSourceCode, 1, 1) \
F(FunctionGetScript, 1, 1) \

View File

@ -1358,7 +1358,8 @@ function FunctionBind(this_arg) { // Length is 1.
// Set the correct length.
var length = (this.length - argc_bound) > 0 ? this.length - argc_bound : 0;
%FunctionSetLength(result, length);
%FunctionRemovePrototype(result);
%FunctionSetBound(result);
return result;
}

View File

@ -62,7 +62,7 @@ var y = 44;
function f_bound_this(z) {
return z + this.y - this.x;
}
}
assertEquals(3, f_bound_this(1))
f = f_bound_this.bind(obj);
@ -75,7 +75,7 @@ assertEquals(0, f.length);
// Test chained binds.
// When only giving the thisArg, any number of binds should have
// When only giving the thisArg, any number of binds should have
// the same effect.
f = foo.bind(foo);
assertEquals(3, f(1, 1, 1));
@ -181,4 +181,3 @@ assertEquals(3, obj2.z);
// Test instanceof obj2 is bar, not f.
assertTrue(obj2 instanceof bar);
assertFalse(obj2 instanceof f);

View File

@ -0,0 +1,31 @@
// 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.
// Test the a bound function does not have a prototype.
function foo() {}
assertFalse("prototype" in foo.bind());