| 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);
|
| }
|
|
|
|
|
|
|