Skip to content

Commit

Permalink
Accessor functions should have no prototype property
Browse files Browse the repository at this point in the history
This also removes some convenience functions that were not used.

BUG=v8:3700
LOG=N
R=adamk@chromium.org, adamk

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

Cr-Commit-Position: refs/heads/master@{#26472}
  • Loading branch information
arv committed Feb 5, 2015
1 parent 308d913 commit b67b3c5
Show file tree
Hide file tree
Showing 19 changed files with 94 additions and 43 deletions.
2 changes: 1 addition & 1 deletion src/arm/full-codegen-arm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ void FullCodeGenerator::Generate() {
{ Comment cmnt(masm_, "[ Allocate locals");
int locals_count = info->scope()->num_stack_slots();
// Generators allocate locals, if any, in context slots.
DCHECK(!info->function()->is_generator() || locals_count == 0);
DCHECK(!IsGeneratorFunction(info->function()->kind()) || locals_count == 0);
if (locals_count > 0) {
if (locals_count >= 128) {
Label ok;
Expand Down
2 changes: 1 addition & 1 deletion src/arm64/full-codegen-arm64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ void FullCodeGenerator::Generate() {
{ Comment cmnt(masm_, "[ Allocate locals");
int locals_count = info->scope()->num_stack_slots();
// Generators allocate locals, if any, in context slots.
DCHECK(!info->function()->is_generator() || locals_count == 0);
DCHECK(!IsGeneratorFunction(info->function()->kind()) || locals_count == 0);

if (locals_count > 0) {
if (locals_count >= 128) {
Expand Down
14 changes: 1 addition & 13 deletions src/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -2548,18 +2548,6 @@ class FunctionLiteral FINAL : public Expression {
}

FunctionKind kind() { return FunctionKindBits::decode(bitfield_); }
bool is_arrow() {
return IsArrowFunction(FunctionKindBits::decode(bitfield_));
}
bool is_generator() {
return IsGeneratorFunction(FunctionKindBits::decode(bitfield_));
}
bool is_concise_method() {
return IsConciseMethod(FunctionKindBits::decode(bitfield_));
}
bool is_default_constructor() {
return IsDefaultConstructor(FunctionKindBits::decode(bitfield_));
}

int ast_node_count() { return ast_properties_.node_count(); }
AstProperties::Flags* flags() { return ast_properties_.flags(); }
Expand Down Expand Up @@ -2630,7 +2618,7 @@ class FunctionLiteral FINAL : public Expression {
class HasDuplicateParameters : public BitField<ParameterFlag, 3, 1> {};
class IsFunction : public BitField<IsFunctionFlag, 4, 1> {};
class IsParenthesized : public BitField<IsParenthesizedFlag, 5, 1> {};
class FunctionKindBits : public BitField<FunctionKind, 6, 5> {};
class FunctionKindBits : public BitField<FunctionKind, 6, 6> {};
};


Expand Down
6 changes: 1 addition & 5 deletions src/code-stubs.h
Original file line number Diff line number Diff line change
Expand Up @@ -587,15 +587,11 @@ class FastNewClosureStub : public HydrogenCodeStub {
FunctionKind kind() const {
return FunctionKindBits::decode(sub_minor_key());
}
bool is_arrow() const { return IsArrowFunction(kind()); }
bool is_generator() const { return IsGeneratorFunction(kind()); }
bool is_concise_method() const { return IsConciseMethod(kind()); }
bool is_default_constructor() const { return IsDefaultConstructor(kind()); }

private:
STATIC_ASSERT(LANGUAGE_END == 3);
class LanguageModeBits : public BitField<LanguageMode, 0, 2> {};
class FunctionKindBits : public BitField<FunctionKind, 2, 4> {};
class FunctionKindBits : public BitField<FunctionKind, 2, 6> {};

DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewClosure);
DEFINE_HYDROGEN_CODE_STUB(FastNewClosure, HydrogenCodeStub);
Expand Down
2 changes: 1 addition & 1 deletion src/compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,7 @@ static bool CheckSuperConstructorCall(CompilationInfo* info) {
FunctionLiteral* function = info->function();
if (FLAG_experimental_classes) return true;
if (!function->uses_super_constructor_call()) return true;
if (function->is_default_constructor()) return true;
if (IsDefaultConstructor(function->kind())) return true;

ZoneList<Statement*>* body = function->body();
CHECK(body->length() > 0);
Expand Down
3 changes: 2 additions & 1 deletion src/contexts.h
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,8 @@ class Context: public FixedArray {
: SLOPPY_GENERATOR_FUNCTION_MAP_INDEX;
}

if (IsArrowFunction(kind) || IsConciseMethod(kind)) {
if (IsArrowFunction(kind) || IsConciseMethod(kind) ||
IsAccessorFunction(kind)) {
return is_strict(language_mode)
? STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX
: SLOPPY_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX;
Expand Down
19 changes: 14 additions & 5 deletions src/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -814,12 +814,13 @@ enum Signedness { kSigned, kUnsigned };

enum FunctionKind {
kNormalFunction = 0,
kArrowFunction = 1,
kGeneratorFunction = 2,
kConciseMethod = 4,
kArrowFunction = 1 << 0,
kGeneratorFunction = 1 << 1,
kConciseMethod = 1 << 2,
kConciseGeneratorMethod = kGeneratorFunction | kConciseMethod,
kDefaultConstructor = 8,
kSubclassConstructor = 16
kAccessorFunction = 1 << 3,
kDefaultConstructor = 1 << 4,
kSubclassConstructor = 1 << 5
};


Expand All @@ -829,6 +830,7 @@ inline bool IsValidFunctionKind(FunctionKind kind) {
kind == FunctionKind::kGeneratorFunction ||
kind == FunctionKind::kConciseMethod ||
kind == FunctionKind::kConciseGeneratorMethod ||
kind == FunctionKind::kAccessorFunction ||
kind == FunctionKind::kDefaultConstructor ||
kind == FunctionKind::kSubclassConstructor;
}
Expand All @@ -852,11 +854,18 @@ inline bool IsConciseMethod(FunctionKind kind) {
}


inline bool IsAccessorFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return kind & FunctionKind::kAccessorFunction;
}


inline bool IsDefaultConstructor(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return kind & FunctionKind::kDefaultConstructor;
}


inline bool IsSubclassConstructor(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return kind & FunctionKind::kSubclassConstructor;
Expand Down
12 changes: 4 additions & 8 deletions src/hydrogen-instructions.h
Original file line number Diff line number Diff line change
Expand Up @@ -7591,10 +7591,6 @@ class HFunctionLiteral FINAL : public HTemplateInstruction<1> {
bool has_no_literals() const {
return HasNoLiteralsField::decode(bit_field_);
}
bool is_arrow() const { return IsArrowFunction(kind()); }
bool is_generator() const { return IsGeneratorFunction(kind()); }
bool is_concise_method() const { return IsConciseMethod(kind()); }
bool is_default_constructor() const { return IsDefaultConstructor(kind()); }
FunctionKind kind() const { return FunctionKindField::decode(bit_field_); }
LanguageMode language_mode() const {
return LanguageModeField::decode(bit_field_);
Expand All @@ -7616,11 +7612,11 @@ class HFunctionLiteral FINAL : public HTemplateInstruction<1> {

bool IsDeletable() const OVERRIDE { return true; }

class FunctionKindField : public BitField<FunctionKind, 0, 4> {};
class PretenureField : public BitField<bool, 5, 1> {};
class HasNoLiteralsField : public BitField<bool, 6, 1> {};
class FunctionKindField : public BitField<FunctionKind, 0, 6> {};
class PretenureField : public BitField<bool, 6, 1> {};
class HasNoLiteralsField : public BitField<bool, 7, 1> {};
STATIC_ASSERT(LANGUAGE_END == 3);
class LanguageModeField : public BitField<LanguageMode, 7, 2> {};
class LanguageModeField : public BitField<LanguageMode, 8, 2> {};

Handle<SharedFunctionInfo> shared_info_;
uint32_t bit_field_;
Expand Down
2 changes: 1 addition & 1 deletion src/ia32/full-codegen-ia32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ void FullCodeGenerator::Generate() {
{ Comment cmnt(masm_, "[ Allocate locals");
int locals_count = info->scope()->num_stack_slots();
// Generators allocate locals, if any, in context slots.
DCHECK(!info->function()->is_generator() || locals_count == 0);
DCHECK(!IsGeneratorFunction(info->function()->kind()) || locals_count == 0);
if (locals_count == 1) {
__ push(Immediate(isolate()->factory()->undefined_value()));
} else if (locals_count > 1) {
Expand Down
2 changes: 1 addition & 1 deletion src/mips/full-codegen-mips.cc
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ void FullCodeGenerator::Generate() {
{ Comment cmnt(masm_, "[ Allocate locals");
int locals_count = info->scope()->num_stack_slots();
// Generators allocate locals, if any, in context slots.
DCHECK(!info->function()->is_generator() || locals_count == 0);
DCHECK(!IsGeneratorFunction(info->function()->kind()) || locals_count == 0);
if (locals_count > 0) {
if (locals_count >= 128) {
Label ok;
Expand Down
2 changes: 1 addition & 1 deletion src/mips64/full-codegen-mips64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ void FullCodeGenerator::Generate() {
{ Comment cmnt(masm_, "[ Allocate locals");
int locals_count = info->scope()->num_stack_slots();
// Generators allocate locals, if any, in context slots.
DCHECK(!info->function()->is_generator() || locals_count == 0);
DCHECK(!IsGeneratorFunction(info->function()->kind()) || locals_count == 0);
if (locals_count > 0) {
if (locals_count >= 128) {
Label ok;
Expand Down
2 changes: 2 additions & 0 deletions src/objects-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -5871,6 +5871,8 @@ BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_arrow, kIsArrow)
BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_generator, kIsGenerator)
BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_concise_method,
kIsConciseMethod)
BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_accessor_function,
kIsAccessorFunction)
BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_default_constructor,
kIsDefaultConstructor)

Expand Down
6 changes: 5 additions & 1 deletion src/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -6940,6 +6940,9 @@ class SharedFunctionInfo: public HeapObject {
// Indicates that this function is a concise method.
DECL_BOOLEAN_ACCESSORS(is_concise_method)

// Indicates that this function is an accessor (getter or setter).
DECL_BOOLEAN_ACCESSORS(is_accessor_function)

// Indicates that this function is a default constructor.
DECL_BOOLEAN_ACCESSORS(is_default_constructor)

Expand Down Expand Up @@ -7190,6 +7193,7 @@ class SharedFunctionInfo: public HeapObject {
kIsArrow,
kIsGenerator,
kIsConciseMethod,
kIsAccessorFunction,
kIsDefaultConstructor,
kIsSubclassConstructor,
kIsAsmFunction,
Expand All @@ -7199,7 +7203,7 @@ class SharedFunctionInfo: public HeapObject {
// Add hints for other modes when they're added.
STATIC_ASSERT(LANGUAGE_END == 3);

class FunctionKindBits : public BitField<FunctionKind, kIsArrow, 5> {};
class FunctionKindBits : public BitField<FunctionKind, kIsArrow, 6> {};

class DeoptCountBits : public BitField<int, 0, 4> {};
class OptReenableTriesBits : public BitField<int, 4, 18> {};
Expand Down
2 changes: 1 addition & 1 deletion src/ppc/full-codegen-ppc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ void FullCodeGenerator::Generate() {
Comment cmnt(masm_, "[ Allocate locals");
int locals_count = info->scope()->num_stack_slots();
// Generators allocate locals, if any, in context slots.
DCHECK(!info->function()->is_generator() || locals_count == 0);
DCHECK(!IsGeneratorFunction(info->function()->kind()) || locals_count == 0);
if (locals_count > 0) {
if (locals_count >= 128) {
Label ok;
Expand Down
2 changes: 1 addition & 1 deletion src/preparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -2194,7 +2194,7 @@ ParserBase<Traits>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker,
typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
name, scanner()->location(),
false, // reserved words are allowed here
FunctionKind::kNormalFunction, RelocInfo::kNoPosition,
FunctionKind::kAccessorFunction, RelocInfo::kNoPosition,
FunctionLiteral::ANONYMOUS_EXPRESSION,
is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY,
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
Expand Down
2 changes: 1 addition & 1 deletion src/x64/full-codegen-x64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ void FullCodeGenerator::Generate() {
{ Comment cmnt(masm_, "[ Allocate locals");
int locals_count = info->scope()->num_stack_slots();
// Generators allocate locals, if any, in context slots.
DCHECK(!info->function()->is_generator() || locals_count == 0);
DCHECK(!IsGeneratorFunction(info->function()->kind()) || locals_count == 0);
if (locals_count == 1) {
__ PushRoot(Heap::kUndefinedValueRootIndex);
} else if (locals_count > 1) {
Expand Down
2 changes: 1 addition & 1 deletion src/x87/full-codegen-x87.cc
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ void FullCodeGenerator::Generate() {
{ Comment cmnt(masm_, "[ Allocate locals");
int locals_count = info->scope()->num_stack_slots();
// Generators allocate locals, if any, in context slots.
DCHECK(!info->function()->is_generator() || locals_count == 0);
DCHECK(!IsGeneratorFunction(info->function()->kind()) || locals_count == 0);
if (locals_count == 1) {
__ push(Immediate(isolate()->factory()->undefined_value()));
} else if (locals_count > 1) {
Expand Down
51 changes: 51 additions & 0 deletions test/mjsunit/accessors-no-prototype.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2014 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.


(function TestGetter() {
var o = {
get x() {}
};
var desc = Object.getOwnPropertyDescriptor(o, 'x');
assertEquals('function', typeof desc.get);
assertFalse('prototype' in desc.get);

assertThrows(function() {
new desc.get();
}, TypeError);
})();


(function TestSetter() {
var o = {
set x(_) {}
};
var desc = Object.getOwnPropertyDescriptor(o, 'x');
assertEquals('function', typeof desc.set);
assertFalse('prototype' in desc.set);

assertThrows(function() {
new desc.set();
}, TypeError);
})();


(function TestBoth() {
var o = {
get x() {},
set x(_) {}
};
var desc = Object.getOwnPropertyDescriptor(o, 'x');
assertEquals('function', typeof desc.get);
assertEquals('function', typeof desc.set);
assertFalse('prototype' in desc.get);
assertFalse('prototype' in desc.set);

assertThrows(function() {
new desc.get();
}, TypeError);
assertThrows(function() {
new desc.set();
}, TypeError);
})();
4 changes: 4 additions & 0 deletions test/mjsunit/harmony/classes.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ function assertGetterDescriptor(object, name) {
assertTrue(descr.configurable);
assertFalse(descr.enumerable);
assertEquals('function', typeof descr.get);
assertFalse('prototype' in descr.get);
assertEquals(undefined, descr.set);
}

Expand All @@ -208,6 +209,7 @@ function assertSetterDescriptor(object, name) {
assertFalse(descr.enumerable);
assertEquals(undefined, descr.get);
assertEquals('function', typeof descr.set);
assertFalse('prototype' in descr.set);
}


Expand All @@ -217,6 +219,8 @@ function assertAccessorDescriptor(object, name) {
assertFalse(descr.enumerable);
assertEquals('function', typeof descr.get);
assertEquals('function', typeof descr.set);
assertFalse('prototype' in descr.get);
assertFalse('prototype' in descr.set);
}


Expand Down

0 comments on commit b67b3c5

Please sign in to comment.