Add FINAL and OVERRIDE macros for C++11 final/override.
We also use new the constant naming scheme for Yield::Kind values to avoid clash with the FINAL macro. R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/23098004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16222 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
a04490517a
commit
254482e4a3
@ -1986,12 +1986,12 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
VisitForStackValue(expr->expression());
|
||||
|
||||
switch (expr->yield_kind()) {
|
||||
case Yield::SUSPEND:
|
||||
case Yield::kSuspend:
|
||||
// Pop value from top-of-stack slot; box result into result register.
|
||||
EmitCreateIteratorResult(false);
|
||||
__ push(result_register());
|
||||
// Fall through.
|
||||
case Yield::INITIAL: {
|
||||
case Yield::kInitial: {
|
||||
Label suspend, continuation, post_runtime, resume;
|
||||
|
||||
__ jmp(&suspend);
|
||||
@ -2023,7 +2023,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
break;
|
||||
}
|
||||
|
||||
case Yield::FINAL: {
|
||||
case Yield::kFinal: {
|
||||
VisitForAccumulatorValue(expr->generator_object());
|
||||
__ mov(r1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed)));
|
||||
__ str(r1, FieldMemOperand(result_register(),
|
||||
@ -2035,7 +2035,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
break;
|
||||
}
|
||||
|
||||
case Yield::DELEGATING: {
|
||||
case Yield::kDelegating: {
|
||||
VisitForStackValue(expr->generator_object());
|
||||
|
||||
// Initial stack layout is as follows:
|
||||
|
12
src/ast.h
12
src/ast.h
@ -2144,10 +2144,10 @@ class Yield: public Expression {
|
||||
DECLARE_NODE_TYPE(Yield)
|
||||
|
||||
enum Kind {
|
||||
INITIAL, // The initial yield that returns the unboxed generator object.
|
||||
SUSPEND, // A normal yield: { value: EXPRESSION, done: false }
|
||||
DELEGATING, // A yield*.
|
||||
FINAL // A return: { value: EXPRESSION, done: true }
|
||||
kInitial, // The initial yield that returns the unboxed generator object
|
||||
kSuspend, // A normal yield: { value: EXPRESSION, done: false }
|
||||
kDelegating, // A yield*.
|
||||
kFinal // A return: { value: EXPRESSION, done: true }
|
||||
};
|
||||
|
||||
Expression* generator_object() const { return generator_object_; }
|
||||
@ -2159,11 +2159,11 @@ class Yield: public Expression {
|
||||
// locates the catch handler in the handler table, and is equivalent to
|
||||
// TryCatchStatement::index().
|
||||
int index() const {
|
||||
ASSERT(yield_kind() == DELEGATING);
|
||||
ASSERT(yield_kind() == kDelegating);
|
||||
return index_;
|
||||
}
|
||||
void set_index(int index) {
|
||||
ASSERT(yield_kind() == DELEGATING);
|
||||
ASSERT(yield_kind() == kDelegating);
|
||||
index_ = index;
|
||||
}
|
||||
|
||||
|
@ -330,6 +330,50 @@ F FUNCTION_CAST(Address addr) {
|
||||
}
|
||||
|
||||
|
||||
// Compiler feature detection.
|
||||
#if defined(__clang__)
|
||||
|
||||
// Compatibility with older clang versions.
|
||||
# ifndef __has_extension
|
||||
# define __has_extension __has_feature
|
||||
# endif
|
||||
|
||||
# if __has_extension(cxx_override_control)
|
||||
# define V8_HAVE_CXX11_FINAL
|
||||
# define V8_HAVE_CXX11_OVERRIDE
|
||||
# endif
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
// g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality
|
||||
// without warnings (functionality used by the macros below). These modes
|
||||
// are detectable by checking whether __GXX_EXPERIMENTAL_CXX0X__ is defined or,
|
||||
// more standardly, by checking whether __cplusplus has a C++11 or greater
|
||||
// value. Current versions of g++ do not correctly set __cplusplus, so we check
|
||||
// both for forward compatibility.
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
|
||||
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
|
||||
# define V8_HAVE_CXX11_OVERRIDE
|
||||
# define V8_HAVE_CXX11_FINAL
|
||||
# endif
|
||||
# else
|
||||
// '__final' is a non-C++11 GCC synonym for 'final', per GCC r176655.
|
||||
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
|
||||
# define V8_HAVE_GXX_FINAL
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
# if _MSC_VER >= 1400
|
||||
# define V8_HAVE_CXX11_OVERRIDE
|
||||
// MSVC currently spells "final" as "sealed".
|
||||
# define V8_HAVE_MSVC_SEALED
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#define DISALLOW_BY_DELETE = delete
|
||||
#else
|
||||
@ -375,6 +419,33 @@ F FUNCTION_CAST(Address addr) {
|
||||
#endif
|
||||
|
||||
|
||||
// Annotate a virtual method indicating it must be overriding a virtual
|
||||
// method in the parent class.
|
||||
// Use like:
|
||||
// virtual void bar() OVERRIDE;
|
||||
#if defined(V8_HAVE_CXX11_OVERRIDE)
|
||||
#define OVERRIDE override
|
||||
#else
|
||||
#define OVERRIDE
|
||||
#endif
|
||||
|
||||
|
||||
// Annotate a virtual method indicating that subclasses must not override it,
|
||||
// or annotate a class to indicate that it cannot be subclassed.
|
||||
// Use like:
|
||||
// class B FINAL : public A {};
|
||||
// virtual void bar() FINAL;
|
||||
#if defined(V8_HAVE_CXX11_FINAL)
|
||||
#define FINAL final
|
||||
#elif defined(V8_HAVE_GXX_FINAL)
|
||||
#define FINAL __final
|
||||
#elif defined(V8_HAVE_MSVC_SEALED)
|
||||
#define FINAL sealed
|
||||
#else
|
||||
#define FINAL
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 4
|
||||
#define MUST_USE_RESULT __attribute__ ((warn_unused_result))
|
||||
#else
|
||||
|
@ -1945,12 +1945,12 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
VisitForStackValue(expr->expression());
|
||||
|
||||
switch (expr->yield_kind()) {
|
||||
case Yield::SUSPEND:
|
||||
case Yield::kSuspend:
|
||||
// Pop value from top-of-stack slot; box result into result register.
|
||||
EmitCreateIteratorResult(false);
|
||||
__ push(result_register());
|
||||
// Fall through.
|
||||
case Yield::INITIAL: {
|
||||
case Yield::kInitial: {
|
||||
Label suspend, continuation, post_runtime, resume;
|
||||
|
||||
__ jmp(&suspend);
|
||||
@ -1983,7 +1983,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
break;
|
||||
}
|
||||
|
||||
case Yield::FINAL: {
|
||||
case Yield::kFinal: {
|
||||
VisitForAccumulatorValue(expr->generator_object());
|
||||
__ mov(FieldOperand(result_register(),
|
||||
JSGeneratorObject::kContinuationOffset),
|
||||
@ -1995,7 +1995,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
break;
|
||||
}
|
||||
|
||||
case Yield::DELEGATING: {
|
||||
case Yield::kDelegating: {
|
||||
VisitForStackValue(expr->generator_object());
|
||||
|
||||
// Initial stack layout is as follows:
|
||||
|
@ -1993,12 +1993,12 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
VisitForStackValue(expr->expression());
|
||||
|
||||
switch (expr->yield_kind()) {
|
||||
case Yield::SUSPEND:
|
||||
case Yield::kSuspend:
|
||||
// Pop value from top-of-stack slot; box result into result register.
|
||||
EmitCreateIteratorResult(false);
|
||||
__ push(result_register());
|
||||
// Fall through.
|
||||
case Yield::INITIAL: {
|
||||
case Yield::kInitial: {
|
||||
Label suspend, continuation, post_runtime, resume;
|
||||
|
||||
__ jmp(&suspend);
|
||||
@ -2029,7 +2029,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
break;
|
||||
}
|
||||
|
||||
case Yield::FINAL: {
|
||||
case Yield::kFinal: {
|
||||
VisitForAccumulatorValue(expr->generator_object());
|
||||
__ li(a1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed)));
|
||||
__ sw(a1, FieldMemOperand(result_register(),
|
||||
@ -2041,7 +2041,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
break;
|
||||
}
|
||||
|
||||
case Yield::DELEGATING: {
|
||||
case Yield::kDelegating: {
|
||||
VisitForStackValue(expr->generator_object());
|
||||
|
||||
// Initial stack layout is as follows:
|
||||
|
@ -2319,7 +2319,7 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
|
||||
Expression* generator = factory()->NewVariableProxy(
|
||||
current_function_state_->generator_object_variable());
|
||||
Expression* yield = factory()->NewYield(
|
||||
generator, return_value, Yield::FINAL, RelocInfo::kNoPosition);
|
||||
generator, return_value, Yield::kFinal, RelocInfo::kNoPosition);
|
||||
result = factory()->NewExpressionStatement(yield);
|
||||
} else {
|
||||
result = factory()->NewReturnStatement(return_value);
|
||||
@ -2997,13 +2997,13 @@ Expression* Parser::ParseYieldExpression(bool* ok) {
|
||||
int position = scanner().peek_location().beg_pos;
|
||||
Expect(Token::YIELD, CHECK_OK);
|
||||
Yield::Kind kind =
|
||||
Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND;
|
||||
Check(Token::MUL) ? Yield::kDelegating : Yield::kSuspend;
|
||||
Expression* generator_object = factory()->NewVariableProxy(
|
||||
current_function_state_->generator_object_variable());
|
||||
Expression* expression = ParseAssignmentExpression(false, CHECK_OK);
|
||||
Yield* yield =
|
||||
factory()->NewYield(generator_object, expression, kind, position);
|
||||
if (kind == Yield::DELEGATING) {
|
||||
if (kind == Yield::kDelegating) {
|
||||
yield->set_index(current_function_state_->NextHandlerIndex());
|
||||
}
|
||||
return yield;
|
||||
@ -4484,7 +4484,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
||||
VariableProxy* get_proxy = factory()->NewVariableProxy(
|
||||
current_function_state_->generator_object_variable());
|
||||
Yield* yield = factory()->NewYield(
|
||||
get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition);
|
||||
get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition);
|
||||
body->Add(factory()->NewExpressionStatement(yield), zone());
|
||||
}
|
||||
|
||||
@ -4496,7 +4496,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
||||
Expression *undefined = factory()->NewLiteral(
|
||||
isolate()->factory()->undefined_value());
|
||||
Yield* yield = factory()->NewYield(
|
||||
get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition);
|
||||
get_proxy, undefined, Yield::kFinal, RelocInfo::kNoPosition);
|
||||
body->Add(factory()->NewExpressionStatement(yield), zone());
|
||||
}
|
||||
|
||||
|
@ -1967,12 +1967,12 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
VisitForStackValue(expr->expression());
|
||||
|
||||
switch (expr->yield_kind()) {
|
||||
case Yield::SUSPEND:
|
||||
case Yield::kSuspend:
|
||||
// Pop value from top-of-stack slot; box result into result register.
|
||||
EmitCreateIteratorResult(false);
|
||||
__ push(result_register());
|
||||
// Fall through.
|
||||
case Yield::INITIAL: {
|
||||
case Yield::kInitial: {
|
||||
Label suspend, continuation, post_runtime, resume;
|
||||
|
||||
__ jmp(&suspend);
|
||||
@ -2006,7 +2006,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
break;
|
||||
}
|
||||
|
||||
case Yield::FINAL: {
|
||||
case Yield::kFinal: {
|
||||
VisitForAccumulatorValue(expr->generator_object());
|
||||
__ Move(FieldOperand(result_register(),
|
||||
JSGeneratorObject::kContinuationOffset),
|
||||
@ -2018,7 +2018,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
break;
|
||||
}
|
||||
|
||||
case Yield::DELEGATING: {
|
||||
case Yield::kDelegating: {
|
||||
VisitForStackValue(expr->generator_object());
|
||||
|
||||
// Initial stack layout is as follows:
|
||||
|
Loading…
Reference in New Issue
Block a user