Commit bcf9771b authored by Adam Klein's avatar Adam Klein Committed by Commit Bot

[ast] Expose Literal::Type enum and switch over it in BytecodeGenerator

Also replaced kTrue/kFalse with a kBoolean type, and remove now-unused
IsTypeX() methods (leaving ones that are called frequently).

Bug: v8:6984
Change-Id: I0cbffc37efaa391981d8dce564051ce43257ed8a
Reviewed-on: https://chromium-review.googlesource.com/745023Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Commit-Queue: Adam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49053}
parent 5e1a3632
...@@ -90,7 +90,7 @@ MaterializedLiteral* AstNode::AsMaterializedLiteral() { ...@@ -90,7 +90,7 @@ MaterializedLiteral* AstNode::AsMaterializedLiteral() {
#undef RETURN_NODE #undef RETURN_NODE
bool Expression::IsSmiLiteral() const { bool Expression::IsSmiLiteral() const {
return IsLiteral() && AsLiteral()->IsSmi(); return IsLiteral() && AsLiteral()->type() == Literal::kSmi;
} }
bool Expression::IsNumberLiteral() const { bool Expression::IsNumberLiteral() const {
...@@ -98,7 +98,7 @@ bool Expression::IsNumberLiteral() const { ...@@ -98,7 +98,7 @@ bool Expression::IsNumberLiteral() const {
} }
bool Expression::IsStringLiteral() const { bool Expression::IsStringLiteral() const {
return IsLiteral() && AsLiteral()->IsString(); return IsLiteral() && AsLiteral()->type() == Literal::kString;
} }
bool Expression::IsPropertyName() const { bool Expression::IsPropertyName() const {
...@@ -106,15 +106,15 @@ bool Expression::IsPropertyName() const { ...@@ -106,15 +106,15 @@ bool Expression::IsPropertyName() const {
} }
bool Expression::IsNullLiteral() const { bool Expression::IsNullLiteral() const {
return IsLiteral() && AsLiteral()->IsNull(); return IsLiteral() && AsLiteral()->type() == Literal::kNull;
} }
bool Expression::IsTheHoleLiteral() const { bool Expression::IsTheHoleLiteral() const {
return IsLiteral() && AsLiteral()->IsTheHole(); return IsLiteral() && AsLiteral()->type() == Literal::kTheHole;
} }
bool Expression::IsUndefinedLiteral() const { bool Expression::IsUndefinedLiteral() const {
if (IsLiteral() && AsLiteral()->IsUndefined()) return true; if (IsLiteral() && AsLiteral()->type() == Literal::kUndefined) return true;
const VariableProxy* var_proxy = AsVariableProxy(); const VariableProxy* var_proxy = AsVariableProxy();
if (var_proxy == nullptr) return false; if (var_proxy == nullptr) return false;
...@@ -825,10 +825,8 @@ Handle<Object> Literal::BuildValue(Isolate* isolate) const { ...@@ -825,10 +825,8 @@ Handle<Object> Literal::BuildValue(Isolate* isolate) const {
return string_->string(); return string_->string();
case kSymbol: case kSymbol:
return isolate->factory()->home_object_symbol(); return isolate->factory()->home_object_symbol();
case kTrue: case kBoolean:
return isolate->factory()->true_value(); return isolate->factory()->ToBoolean(boolean_);
case kFalse:
return isolate->factory()->false_value();
case kNull: case kNull:
return isolate->factory()->null_value(); return isolate->factory()->null_value();
case kUndefined: case kUndefined:
...@@ -852,10 +850,8 @@ bool Literal::ToBooleanIsTrue() const { ...@@ -852,10 +850,8 @@ bool Literal::ToBooleanIsTrue() const {
case kNull: case kNull:
case kUndefined: case kUndefined:
return false; return false;
case kTrue: case kBoolean:
return true; return boolean_;
case kFalse:
return false;
case kBigInt: { case kBigInt: {
const char* bigint_str = bigint_.c_str(); const char* bigint_str = bigint_.c_str();
size_t length = strlen(bigint_str); size_t length = strlen(bigint_str);
......
...@@ -987,6 +987,20 @@ class SloppyBlockFunctionStatement final : public Statement { ...@@ -987,6 +987,20 @@ class SloppyBlockFunctionStatement final : public Statement {
class Literal final : public Expression { class Literal final : public Expression {
public: public:
enum Type {
kSmi,
kHeapNumber,
kBigInt,
kString,
kSymbol,
kBoolean,
kUndefined,
kNull,
kTheHole,
};
Type type() const { return TypeField::decode(bit_field_); }
// Returns true if literal represents a property name (i.e. cannot be parsed // Returns true if literal represents a property name (i.e. cannot be parsed
// as array indices). // as array indices).
bool IsPropertyName() const; bool IsPropertyName() const;
...@@ -995,12 +1009,12 @@ class Literal final : public Expression { ...@@ -995,12 +1009,12 @@ class Literal final : public Expression {
return string_; return string_;
} }
bool IsSmi() const { return type() == kSmi; }
Smi* AsSmiLiteral() const { Smi* AsSmiLiteral() const {
DCHECK_EQ(kSmi, type()); DCHECK_EQ(kSmi, type());
return Smi::FromInt(smi_); return Smi::FromInt(smi_);
} }
// Returns true if literal represents a Number.
bool IsNumber() const { return type() == kHeapNumber || type() == kSmi; } bool IsNumber() const { return type() == kHeapNumber || type() == kSmi; }
double AsNumber() const { double AsNumber() const {
DCHECK(IsNumber()); DCHECK(IsNumber());
...@@ -1014,31 +1028,22 @@ class Literal final : public Expression { ...@@ -1014,31 +1028,22 @@ class Literal final : public Expression {
} }
} }
bool IsBigInt() const { return type() == kBigInt; }
AstBigInt AsBigInt() const { AstBigInt AsBigInt() const {
DCHECK(IsBigInt()); DCHECK_EQ(type(), kBigInt);
return bigint_; return bigint_;
} }
bool IsString() const { return type() == kString; } bool IsString() const { return type() == kString; }
const AstRawString* AsRawString() { const AstRawString* AsRawString() {
DCHECK(IsString()); DCHECK_EQ(type(), kString);
return string_; return string_;
} }
bool IsSymbol() const { return type() == kSymbol; }
AstSymbol AsSymbol() { AstSymbol AsSymbol() {
DCHECK(IsSymbol()); DCHECK_EQ(type(), kSymbol);
return symbol_; return symbol_;
} }
bool IsNull() const { return type() == kNull; }
bool IsUndefined() const { return type() == kUndefined; }
bool IsTheHole() const { return type() == kTheHole; }
bool IsTrue() const { return type() == kTrue; }
bool IsFalse() const { return type() == kFalse; }
V8_EXPORT_PRIVATE bool ToBooleanIsTrue() const; V8_EXPORT_PRIVATE bool ToBooleanIsTrue() const;
bool ToBooleanIsFalse() const { return !ToBooleanIsTrue(); } bool ToBooleanIsFalse() const { return !ToBooleanIsTrue(); }
...@@ -1057,23 +1062,8 @@ class Literal final : public Expression { ...@@ -1057,23 +1062,8 @@ class Literal final : public Expression {
private: private:
friend class AstNodeFactory; friend class AstNodeFactory;
enum Type {
kSmi,
kHeapNumber,
kBigInt,
kString,
kSymbol,
kUndefined,
kNull,
kTheHole,
kTrue,
kFalse
};
class TypeField : public BitField<Type, Expression::kNextBitFieldIndex, 4> {}; class TypeField : public BitField<Type, Expression::kNextBitFieldIndex, 4> {};
Type type() const { return TypeField::decode(bit_field_); }
Literal(int smi, int position) : Expression(position, kLiteral), smi_(smi) { Literal(int smi, int position) : Expression(position, kLiteral), smi_(smi) {
bit_field_ = TypeField::update(bit_field_, kSmi); bit_field_ = TypeField::update(bit_field_, kSmi);
} }
...@@ -1098,9 +1088,13 @@ class Literal final : public Expression { ...@@ -1098,9 +1088,13 @@ class Literal final : public Expression {
bit_field_ = TypeField::update(bit_field_, kSymbol); bit_field_ = TypeField::update(bit_field_, kSymbol);
} }
Literal(bool boolean, int position)
: Expression(position, kLiteral), boolean_(boolean) {
bit_field_ = TypeField::update(bit_field_, kBoolean);
}
Literal(Type type, int position) : Expression(position, kLiteral) { Literal(Type type, int position) : Expression(position, kLiteral) {
DCHECK(type == kNull || type == kUndefined || type == kTheHole || DCHECK(type == kNull || type == kUndefined || type == kTheHole);
type == kTrue || type == kFalse);
bit_field_ = TypeField::update(bit_field_, type); bit_field_ = TypeField::update(bit_field_, type);
} }
...@@ -1110,6 +1104,7 @@ class Literal final : public Expression { ...@@ -1110,6 +1104,7 @@ class Literal final : public Expression {
double number_; double number_;
AstSymbol symbol_; AstSymbol symbol_;
AstBigInt bigint_; AstBigInt bigint_;
bool boolean_;
}; };
}; };
...@@ -3031,10 +3026,7 @@ class AstNodeFactory final BASE_EMBEDDED { ...@@ -3031,10 +3026,7 @@ class AstNodeFactory final BASE_EMBEDDED {
} }
Literal* NewBooleanLiteral(bool b, int pos) { Literal* NewBooleanLiteral(bool b, int pos) {
if (b) { return new (zone_) Literal(b, pos);
return new (zone_) Literal(Literal::kTrue, pos);
}
return new (zone_) Literal(Literal::kFalse, pos);
} }
Literal* NewNullLiteral(int pos) { Literal* NewNullLiteral(int pos) {
......
...@@ -1976,32 +1976,36 @@ void BytecodeGenerator::VisitConditional(Conditional* expr) { ...@@ -1976,32 +1976,36 @@ void BytecodeGenerator::VisitConditional(Conditional* expr) {
} }
void BytecodeGenerator::VisitLiteral(Literal* expr) { void BytecodeGenerator::VisitLiteral(Literal* expr) {
if (!execution_result()->IsEffect()) { if (execution_result()->IsEffect()) return;
// TODO(adamk): Make this a switch statement. switch (expr->type()) {
if (expr->IsSmi()) { case Literal::kSmi:
builder()->LoadLiteral(expr->AsSmiLiteral()); builder()->LoadLiteral(expr->AsSmiLiteral());
} else if (expr->IsNumber()) { break;
case Literal::kHeapNumber:
builder()->LoadLiteral(expr->AsNumber()); builder()->LoadLiteral(expr->AsNumber());
} else if (expr->IsUndefined()) { break;
case Literal::kUndefined:
builder()->LoadUndefined(); builder()->LoadUndefined();
} else if (expr->IsTrue()) { break;
builder()->LoadTrue(); case Literal::kBoolean:
} else if (expr->IsFalse()) { builder()->LoadBoolean(expr->ToBooleanIsTrue());
builder()->LoadFalse(); execution_result()->SetResultIsBoolean();
} else if (expr->IsNull()) { break;
case Literal::kNull:
builder()->LoadNull(); builder()->LoadNull();
} else if (expr->IsTheHole()) { break;
case Literal::kTheHole:
builder()->LoadTheHole(); builder()->LoadTheHole();
} else if (expr->IsString()) { break;
case Literal::kString:
builder()->LoadLiteral(expr->AsRawString()); builder()->LoadLiteral(expr->AsRawString());
} else if (expr->IsSymbol()) { break;
case Literal::kSymbol:
builder()->LoadLiteral(expr->AsSymbol()); builder()->LoadLiteral(expr->AsSymbol());
} else if (expr->IsBigInt()) { break;
case Literal::kBigInt:
builder()->LoadLiteral(expr->AsBigInt()); builder()->LoadLiteral(expr->AsBigInt());
} break;
if (expr->IsTrue() || expr->IsFalse()) {
execution_result()->SetResultIsBoolean();
}
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment