OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/ast.h" | 5 #include "src/ast.h" |
6 | 6 |
7 #include <cmath> // For isfinite. | 7 #include <cmath> // For isfinite. |
8 #include "src/builtins.h" | 8 #include "src/builtins.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/contexts.h" | 10 #include "src/contexts.h" |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 bool ObjectLiteral::Property::emit_store() { | 232 bool ObjectLiteral::Property::emit_store() { |
233 return emit_store_; | 233 return emit_store_; |
234 } | 234 } |
235 | 235 |
236 | 236 |
237 void ObjectLiteral::CalculateEmitStore(Zone* zone) { | 237 void ObjectLiteral::CalculateEmitStore(Zone* zone) { |
238 ZoneAllocationPolicy allocator(zone); | 238 ZoneAllocationPolicy allocator(zone); |
239 | 239 |
240 ZoneHashMap table(Literal::Match, ZoneHashMap::kDefaultHashMapCapacity, | 240 ZoneHashMap table(Literal::Match, ZoneHashMap::kDefaultHashMapCapacity, |
241 allocator); | 241 allocator); |
242 bool seen_prototype = false; | |
243 for (int i = properties()->length() - 1; i >= 0; i--) { | 242 for (int i = properties()->length() - 1; i >= 0; i--) { |
244 ObjectLiteral::Property* property = properties()->at(i); | 243 ObjectLiteral::Property* property = properties()->at(i); |
245 if (property->is_computed_name()) continue; | 244 if (property->is_computed_name()) continue; |
246 Literal* literal = property->key()->AsLiteral(); | 245 Literal* literal = property->key()->AsLiteral(); |
247 if (literal->value()->IsNull()) continue; | 246 if (literal->value()->IsNull()) continue; |
248 uint32_t hash = literal->Hash(); | 247 uint32_t hash = literal->Hash(); |
249 // If the key of a computed property value is in the table, do not emit | 248 // If the key of a computed property value is in the table, do not emit |
250 // a store for the property later. | 249 // a store for the property later. |
251 if ((property->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL || | 250 if ((property->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL || |
252 property->kind() == ObjectLiteral::Property::COMPUTED) && | 251 property->kind() == ObjectLiteral::Property::COMPUTED) && |
253 table.Lookup(literal, hash, false, allocator) != NULL) { | 252 table.Lookup(literal, hash, false, allocator) != NULL) { |
254 property->set_emit_store(false); | 253 property->set_emit_store(false); |
255 } else if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 254 } else if (property->kind() != ObjectLiteral::Property::PROTOTYPE) { |
256 // Only emit a store for the last prototype property. Make sure we do not | |
257 // clobber the "__proto__" name for instance properties (using method or | |
258 // literal shorthand syntax). | |
259 property->set_emit_store(!seen_prototype); | |
260 seen_prototype = true; | |
261 } else { | |
262 // Add key to the table. | 255 // Add key to the table. |
263 table.Lookup(literal, hash, true, allocator); | 256 table.Lookup(literal, hash, true, allocator); |
264 } | 257 } |
265 } | 258 } |
266 } | 259 } |
267 | 260 |
268 | 261 |
269 bool ObjectLiteral::IsBoilerplateProperty(ObjectLiteral::Property* property) { | 262 bool ObjectLiteral::IsBoilerplateProperty(ObjectLiteral::Property* property) { |
270 return property != NULL && | 263 return property != NULL && |
271 property->kind() != ObjectLiteral::Property::PROTOTYPE; | 264 property->kind() != ObjectLiteral::Property::PROTOTYPE; |
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1036 // static | 1029 // static |
1037 bool Literal::Match(void* literal1, void* literal2) { | 1030 bool Literal::Match(void* literal1, void* literal2) { |
1038 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); | 1031 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); |
1039 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); | 1032 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); |
1040 return (x->IsString() && y->IsString() && *x->AsString() == *y->AsString()) || | 1033 return (x->IsString() && y->IsString() && *x->AsString() == *y->AsString()) || |
1041 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); | 1034 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); |
1042 } | 1035 } |
1043 | 1036 |
1044 | 1037 |
1045 } } // namespace v8::internal | 1038 } } // namespace v8::internal |
OLD | NEW |