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, 7> {};
+ class FunctionKindBits : public BitField<FunctionKind, 6, 8> {};
};
private:
STATIC_ASSERT(LANGUAGE_END == 3);
class LanguageModeBits : public BitField<LanguageMode, 0, 2> {};
- class FunctionKindBits : public BitField<FunctionKind, 2, 7> {};
+ class FunctionKindBits : public BitField<FunctionKind, 2, 8> {};
DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewClosure);
DEFINE_HYDROGEN_CODE_STUB(FastNewClosure, HydrogenCodeStub);
kDefaultConstructor = 1 << 4,
kSubclassConstructor = 1 << 5,
kBaseConstructor = 1 << 6,
+ kInObjectLiteral = 1 << 7,
kDefaultBaseConstructor = kDefaultConstructor | kBaseConstructor,
- kDefaultSubclassConstructor = kDefaultConstructor | kSubclassConstructor
+ kDefaultSubclassConstructor = kDefaultConstructor | kSubclassConstructor,
+ kConciseMethodInObjectLiteral = kConciseMethod | kInObjectLiteral,
+ kConciseGeneratorMethodInObjectLiteral =
+ kConciseGeneratorMethod | kInObjectLiteral,
+ kAccessorFunctionInObjectLiteral = kAccessorFunction | kInObjectLiteral,
};
kind == FunctionKind::kDefaultBaseConstructor ||
kind == FunctionKind::kDefaultSubclassConstructor ||
kind == FunctionKind::kBaseConstructor ||
- kind == FunctionKind::kSubclassConstructor;
+ kind == FunctionKind::kSubclassConstructor ||
+ kind == FunctionKind::kConciseMethodInObjectLiteral ||
+ kind == FunctionKind::kConciseGeneratorMethodInObjectLiteral ||
+ kind == FunctionKind::kAccessorFunctionInObjectLiteral;
}
(FunctionKind::kBaseConstructor | FunctionKind::kSubclassConstructor |
FunctionKind::kDefaultConstructor);
}
+
+
+inline bool IsInObjectLiteral(FunctionKind kind) {
+ DCHECK(IsValidFunctionKind(kind));
+ return kind & FunctionKind::kInObjectLiteral;
+}
+
+
+inline FunctionKind WithObjectLiteralBit(FunctionKind kind) {
+ kind = static_cast<FunctionKind>(kind | FunctionKind::kInObjectLiteral);
+ DCHECK(IsValidFunctionKind(kind));
+ return kind;
+}
} } // namespace v8::internal
namespace i = v8::internal;
bool IsDeletable() const OVERRIDE { return true; }
- class FunctionKindField : public BitField<FunctionKind, 0, 6> {};
- class PretenureField : public BitField<bool, 6, 1> {};
- class HasNoLiteralsField : public BitField<bool, 7, 1> {};
+ class FunctionKindField : public BitField<FunctionKind, 0, 8> {};
+ class PretenureField : public BitField<bool, 8, 1> {};
+ class HasNoLiteralsField : public BitField<bool, 9, 1> {};
STATIC_ASSERT(LANGUAGE_END == 3);
- class LanguageModeField : public BitField<LanguageMode, 8, 2> {};
+ class LanguageModeField : public BitField<LanguageMode, 10, 2> {};
Handle<SharedFunctionInfo> shared_info_;
uint32_t bit_field_;
class BlockScopeIsClassScopeField
: public BitField<bool, IsSimpleParameterListField::kNext, 1> {};
class FunctionKindField
- : public BitField<FunctionKind, BlockScopeIsClassScopeField::kNext, 7> {};
+ : public BitField<FunctionKind, BlockScopeIsClassScopeField::kNext, 8> {};
// BitFields representing the encoded information for context locals in the
// ContextLocalInfoEntries part.
kIsDefaultConstructor,
kIsSubclassConstructor,
kIsBaseConstructor,
+ kInClassLiteral,
kIsAsmFunction,
kDeserialized,
kCompilerHintsCount // Pseudo entry
// Add hints for other modes when they're added.
STATIC_ASSERT(LANGUAGE_END == 3);
- class FunctionKindBits : public BitField<FunctionKind, kIsArrow, 7> {};
+ class FunctionKindBits : public BitField<FunctionKind, kIsArrow, 8> {};
class DeoptCountBits : public BitField<int, 0, 4> {};
class OptReenableTriesBits : public BitField<int, 4, 18> {};
: FunctionKind::kBaseConstructor;
}
+ if (!in_class) kind = WithObjectLiteralBit(kind);
+
value = this->ParseFunctionLiteral(
name, scanner()->location(),
false, // reserved words are allowed here
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
}
+ FunctionKind kind = FunctionKind::kAccessorFunction;
+ if (!in_class) kind = WithObjectLiteralBit(kind);
typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
name, scanner()->location(),
false, // reserved words are allowed here
- FunctionKind::kAccessorFunction, RelocInfo::kNoPosition,
- FunctionLiteral::ANONYMOUS_EXPRESSION,
+ kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY,
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
Variable* Scope::ClassVariableForMethod() const {
if (!is_function_scope()) return nullptr;
+ if (IsInObjectLiteral(function_kind_)) return nullptr;
if (!IsConciseMethod(function_kind_) && !IsConstructor(function_kind_) &&
!IsAccessorFunction(function_kind_)) {
return nullptr;
"'use strong'; if (false) { let C = class C2 { method() { C; } } }",
ReferenceError);
+ assertThrowsHelper(
+ "'use strong'; if (false) { " +
+ "let C = class C2 { *generator_method() { C; } } }",
+ ReferenceError);
+
assertThrowsHelper(
"'use strong'; if (false) { let C = class C2 { " +
"static a() { return 'A'; } [C.a()]() { return 'B'; } }; }",
"{ return 'B'; } } }",
ReferenceError);
- // Methods inside object literals are not sufficiently distinguished from
- // methods inside classes.
- // https://code.google.com/p/v8/issues/detail?id=3948
- // assertThrowsHelper(
- // "'use strong'; if (false) { let C = class C2 { " +
- // "[({m() { C2; return 'A'; }}).m()]() " +
- // "{ return 'B'; } } }",
- // ReferenceError);
+ assertThrowsHelper(
+ "'use strong'; if (false) { let C = class C2 { " +
+ "[({m() { C2; return 'A'; }}).m()]() " +
+ "{ return 'B'; } } }",
+ ReferenceError);
assertThrowsHelper(
"'use strong'; if (false) { let C = class C2 { " +
"{ return 'B'; } } }",
ReferenceError);
- // assertThrowsHelper(
- // "'use strong';\n" +
- // "if (false) {\n" +
- // " class COuter {\n" +
- // " m() {\n" +
- // " class CInner {\n" +
- // " [({ m() { CInner; return 'A'; } }).m()]() {\n" +
- // " return 'B';\n" +
- // " }\n" +
- // " }\n" +
- // " }\n" +
- // " }\n" +
- // "}",
- // ReferenceError);
+ assertThrowsHelper(
+ "'use strong';\n" +
+ "if (false) {\n" +
+ " class COuter {\n" +
+ " m() {\n" +
+ " class CInner {\n" +
+ " [({ m() { CInner; return 'A'; } }).m()]() {\n" +
+ " return 'B';\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}",
+ ReferenceError);
})();
class C1 { constructor() { C1; } }; new C1();
let C2 = class C3 { constructor() { C3; } }; new C2();
- class C4 { method() { C4; } }; new C4();
- let C5 = class C6 { method() { C6; } }; new C5();
+ class C4 { method() { C4; } *generator_method() { C4; } }; new C4();
+ let C5 = class C6 { method() { C6; } *generator_method() { C6; } }; new C5();
class C7 { static method() { C7; } }; new C7();
let C8 = class C9 { static method() { C9; } }; new C8();
let C11 = class C12 { get x() { C12; } }; new C11();
// Regression test for unnamed classes.
- let C12 = class { m() { var1; } };
+ let C13 = class { m() { var1; } };
class COuter {
m() {
}
}
(new COuter()).m().n();
+
+ // Making sure the check which is supposed to prevent "object literal inside
+ // computed property name references the class name" is not too generic:
+ class C14 { m() { let obj = { n() { C14 } }; obj.n(); } }; (new C14()).m();
})();