Index: src/parser.cc |
=================================================================== |
--- src/parser.cc (revision 1544) |
+++ src/parser.cc (working copy) |
@@ -158,10 +158,12 @@ |
// Decide if a property should be the object boilerplate. |
bool IsBoilerplateProperty(ObjectLiteral::Property* property); |
- // If the property is CONSTANT type, it returns the literal value, |
- // otherwise, it return undefined literal as the placeholder |
+ // If the expression is a literal, return the literal value; |
+ // if the expression is a materialized literal and is simple return a |
+ // compile time value as encoded by CompileTimeValue::GetValue(). |
+ // Otherwise, return undefined literal as the placeholder |
// in the object literal boilerplate. |
- Literal* GetBoilerplateValue(ObjectLiteral::Property* property); |
+ Handle<Object> GetBoilerplateValue(Expression* expression); |
enum FunctionLiteralType { |
EXPRESSION, |
@@ -3054,6 +3056,7 @@ |
// Update the scope information before the pre-parsing bailout. |
temp_scope_->set_contains_array_literal(); |
+ int literal_index = temp_scope_->NextMaterializedLiteralIndex(); |
if (is_pre_parsing_) return NULL; |
@@ -3062,16 +3065,24 @@ |
Factory::NewFixedArray(values.length(), TENURED); |
// Fill in the literals. |
+ bool is_simple = true; |
+ int depth = 1; |
for (int i = 0; i < values.length(); i++) { |
- Literal* literal = values.at(i)->AsLiteral(); |
- if (literal == NULL) { |
+ MaterializedLiteral* m_literal = values.at(i)->AsMaterializedLiteral(); |
+ if (m_literal != NULL && m_literal->depth() + 1 > depth) { |
+ depth = m_literal->depth() + 1; |
+ } |
+ Handle<Object> boilerplate_value = GetBoilerplateValue(values.at(i)); |
+ if (boilerplate_value->IsUndefined()) { |
literals->set_the_hole(i); |
+ is_simple = false; |
} else { |
- literals->set(i, *literal->handle()); |
+ literals->set(i, *boilerplate_value); |
} |
} |
- return NEW(ArrayLiteral(literals, values.elements())); |
+ return NEW(ArrayLiteral(literals, values.elements(), |
+ literal_index, is_simple, depth)); |
} |
@@ -3081,13 +3092,51 @@ |
} |
-Literal* Parser::GetBoilerplateValue(ObjectLiteral::Property* property) { |
- if (property->kind() == ObjectLiteral::Property::CONSTANT) |
- return property->value()->AsLiteral(); |
- return GetLiteralUndefined(); |
+bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { |
+ MaterializedLiteral* lit = expression->AsMaterializedLiteral(); |
+ return lit != NULL && lit->is_simple(); |
} |
+Handle<FixedArray> CompileTimeValue::GetValue(Expression* expression) { |
+ ASSERT(IsCompileTimeValue(expression)); |
+ Handle<FixedArray> result = Factory::NewFixedArray(2, TENURED); |
+ ObjectLiteral* object_literal = expression->AsObjectLiteral(); |
+ if (object_literal != NULL) { |
+ ASSERT(object_literal->is_simple()); |
+ result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL)); |
+ result->set(kElementsSlot, *object_literal->constant_properties()); |
+ } else { |
+ ArrayLiteral* array_literal = expression->AsArrayLiteral(); |
+ ASSERT(array_literal != NULL && array_literal->is_simple()); |
+ result->set(kTypeSlot, Smi::FromInt(ARRAY_LITERAL)); |
+ result->set(kElementsSlot, *array_literal->literals()); |
+ } |
+ return result; |
+} |
+ |
+CompileTimeValue::Type CompileTimeValue::GetType(Handle<FixedArray> value) { |
+ Smi* type_value = Smi::cast(value->get(kTypeSlot)); |
+ return static_cast<Type>(type_value->value()); |
+} |
+ |
+ |
+Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { |
+ return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); |
+} |
+ |
+ |
+Handle<Object> Parser::GetBoilerplateValue(Expression* expression) { |
+ if (expression->AsLiteral() != NULL) { |
+ return expression->AsLiteral()->handle(); |
+ } |
+ if (CompileTimeValue::IsCompileTimeValue(expression)) { |
+ return CompileTimeValue::GetValue(expression); |
+ } |
+ return Factory::undefined_value(); |
+} |
+ |
+ |
Expression* Parser::ParseObjectLiteral(bool* ok) { |
// ObjectLiteral :: |
// '{' ( |
@@ -3179,24 +3228,36 @@ |
Handle<FixedArray> constant_properties = |
Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED); |
int position = 0; |
+ bool is_simple = true; |
+ int depth = 1; |
for (int i = 0; i < properties.length(); i++) { |
ObjectLiteral::Property* property = properties.at(i); |
- if (!IsBoilerplateProperty(property)) continue; |
+ if (!IsBoilerplateProperty(property)) { |
+ is_simple = false; |
+ continue; |
+ } |
+ MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral(); |
+ if (m_literal != NULL && m_literal->depth() + 1 > depth) { |
+ depth = m_literal->depth() + 1; |
+ } |
// Add CONSTANT and COMPUTED properties to boilerplate. Use undefined |
// value for COMPUTED properties, the real value is filled in at |
// runtime. The enumeration order is maintained. |
Handle<Object> key = property->key()->handle(); |
- Literal* literal = GetBoilerplateValue(property); |
+ Handle<Object> value = GetBoilerplateValue(property->value()); |
+ is_simple = is_simple && !value->IsUndefined(); |
// Add name, value pair to the fixed array. |
constant_properties->set(position++, *key); |
- constant_properties->set(position++, *literal->handle()); |
+ constant_properties->set(position++, *value); |
} |
return new ObjectLiteral(constant_properties, |
properties.elements(), |
- literal_index); |
+ literal_index, |
+ is_simple, |
+ depth); |
} |