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);
break;
}
- case Yield::FINAL: {
+ case Yield::kFinal: {
VisitForAccumulatorValue(expr->generator_object());
__ mov(r1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed)));
__ str(r1, FieldMemOperand(result_register(),
break;
}
- case Yield::DELEGATING: {
+ case Yield::kDelegating: {
VisitForStackValue(expr->generator_object());
// Initial stack layout is as follows:
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_; }
// 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;
}
}
+// 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
#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
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);
break;
}
- case Yield::FINAL: {
+ case Yield::kFinal: {
VisitForAccumulatorValue(expr->generator_object());
__ mov(FieldOperand(result_register(),
JSGeneratorObject::kContinuationOffset),
break;
}
- case Yield::DELEGATING: {
+ case Yield::kDelegating: {
VisitForStackValue(expr->generator_object());
// Initial stack layout is as follows:
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);
break;
}
- case Yield::FINAL: {
+ case Yield::kFinal: {
VisitForAccumulatorValue(expr->generator_object());
__ li(a1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed)));
__ sw(a1, FieldMemOperand(result_register(),
break;
}
- case Yield::DELEGATING: {
+ case Yield::kDelegating: {
VisitForStackValue(expr->generator_object());
// Initial stack layout is as follows:
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);
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;
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());
}
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());
}
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);
break;
}
- case Yield::FINAL: {
+ case Yield::kFinal: {
VisitForAccumulatorValue(expr->generator_object());
__ Move(FieldOperand(result_register(),
JSGeneratorObject::kContinuationOffset),
break;
}
- case Yield::DELEGATING: {
+ case Yield::kDelegating: {
VisitForStackValue(expr->generator_object());
// Initial stack layout is as follows: