Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(502)

Side by Side Diff: runtime/vm/object.cc

Issue 10854176: - Merge function lists when patching classes (no more duplicates). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/bigint_operations.h" 10 #include "vm/bigint_operations.h"
(...skipping 1482 matching lines...) Expand 10 before | Expand all | Expand 10 after
1493 // Prefinalized classes have a VM internal representation and no Dart fields. 1493 // Prefinalized classes have a VM internal representation and no Dart fields.
1494 // Their instance size is precomputed and field offsets are known. 1494 // Their instance size is precomputed and field offsets are known.
1495 if (!is_prefinalized()) { 1495 if (!is_prefinalized()) {
1496 // Compute offsets of instance fields and instance size. 1496 // Compute offsets of instance fields and instance size.
1497 CalculateFieldOffsets(); 1497 CalculateFieldOffsets();
1498 } 1498 }
1499 set_is_finalized(); 1499 set_is_finalized();
1500 } 1500 }
1501 1501
1502 1502
1503 static const char* FormatPatchError(const char* format, const Object& obj) {
1504 const char* msg = obj.ToCString();
1505 intptr_t len = OS::SNPrint(NULL, 0, format, msg) + 1;
1506 char* result = Isolate::Current()->current_zone()->Alloc<char>(len);
1507 OS::SNPrint(result, len, format, msg);
1508 return result;
1509 }
1510
1511
1503 // Apply the members from the patch class to the original class. 1512 // Apply the members from the patch class to the original class.
1504 void Class::ApplyPatch(const Class& patch) const { 1513 const char* Class::ApplyPatch(const Class& patch) const {
1505 ASSERT(!is_finalized()); 1514 ASSERT(!is_finalized());
1515 // Shared handles used during the iteration.
1516 String& member_name = String::Handle();
1517
1506 const Script& patch_script = Script::Handle(patch.script()); 1518 const Script& patch_script = Script::Handle(patch.script());
1507 const PatchClass& patch_class = PatchClass::Handle( 1519 const PatchClass& patch_class = PatchClass::Handle(
1508 PatchClass::New(*this, patch_script)); 1520 PatchClass::New(*this, patch_script));
1509 1521
1510 const Array& orig_functions = Array::Handle(functions()); 1522 Array& orig_list = Array::Handle(functions());
1511 intptr_t orig_len = orig_functions.Length(); 1523 intptr_t orig_len = orig_list.Length();
1512 1524 Array& patch_list = Array::Handle(patch.functions());
1513 const Array& patch_functions = Array::Handle(patch.functions()); 1525 intptr_t patch_len = patch_list.Length();
1514 intptr_t patch_len = patch_functions.Length();
1515 1526
1516 // TODO(iposva): Verify that only patching existing methods and adding only 1527 // TODO(iposva): Verify that only patching existing methods and adding only
1517 // new private methods. Currently we prepend all patch class members to the 1528 // new private methods.
1518 // members lists which makes them override the orignals.
1519 Function& func = Function::Handle(); 1529 Function& func = Function::Handle();
1520 const Array& new_functions = Array::Handle(Array::New(patch_len + orig_len)); 1530 Function& orig_func = Function::Handle();
1531 const GrowableObjectArray& new_functions = GrowableObjectArray::Handle(
1532 GrowableObjectArray::New(orig_len));
1533 for (intptr_t i = 0; i < orig_len; i++) {
1534 orig_func ^= orig_list.At(i);
1535 member_name = orig_func.name();
1536 func = patch.LookupFunction(member_name);
1537 if (func.IsNull()) {
1538 // Non-patched function is preserved, all patched functions are added in
1539 // the loop below.
1540 new_functions.Add(orig_func);
1541 } else if (!func.HasCompatibleParametersWith(orig_func)) {
1542 return FormatPatchError("mismatched parameters: %s", member_name);
1543 }
1544 }
1521 for (intptr_t i = 0; i < patch_len; i++) { 1545 for (intptr_t i = 0; i < patch_len; i++) {
1522 func ^= patch_functions.At(i); 1546 func ^= patch_list.At(i);
1523 func.set_owner(patch_class); 1547 func.set_owner(patch_class);
1524 new_functions.SetAt(i, func); 1548 new_functions.Add(func);
1549 }
1550 Array& new_list = Array::Handle(Array::MakeArray(new_functions));
1551 SetFunctions(new_list);
1552
1553 // Merge the two list of fields. Raise an error when duplicates are found or
1554 // when a public field is being added.
1555 orig_list = fields();
1556 orig_len = orig_list.Length();
1557 patch_list = patch.fields();
1558 patch_len = patch_list.Length();
1559
1560 Field& field = Field::Handle();
1561 Field& orig_field = Field::Handle();
1562 new_list = Array::New(patch_len + orig_len);
1563 for (intptr_t i = 0; i < patch_len; i++) {
1564 field ^= patch_list.At(i);
1565 field.set_owner(*this);
1566 member_name = field.name();
1567 // TODO(iposva): Verify non-public fields only.
1568
1569 // Verify no duplicate additions.
1570 orig_field = LookupField(member_name);
1571 if (!orig_field.IsNull()) {
1572 return FormatPatchError("duplicate field: %s", member_name);
1573 }
1574 new_list.SetAt(i, field);
1525 } 1575 }
1526 for (intptr_t i = 0; i < orig_len; i++) { 1576 for (intptr_t i = 0; i < orig_len; i++) {
1527 func ^= orig_functions.At(i); 1577 field ^= orig_list.At(i);
1528 new_functions.SetAt(patch_len + i, func); 1578 new_list.SetAt(patch_len + i, field);
1529 } 1579 }
1530 SetFunctions(new_functions); 1580 SetFields(new_list);
1531 1581 return NULL;
1532 const Array& orig_fields = Array::Handle(fields());
1533 orig_len = orig_fields.Length();
1534
1535 const Array& patch_fields = Array::Handle(patch.fields());
1536 patch_len = patch_fields.Length();
1537
1538 // TODO(iposva): Verify that no duplicate fields are entered. Currently we
1539 // prepend all patch class members to the members lists which makes them
1540 // override the orignals.
1541 Field& field = Field::Handle();
1542 const Array& new_fields = Array::Handle(Array::New(patch_len + orig_len));
1543 for (intptr_t i = 0; i < patch_len; i++) {
1544 field ^= patch_fields.At(i);
1545 field.set_owner(*this);
1546 new_fields.SetAt(i, field);
1547 }
1548 for (intptr_t i = 0; i < orig_len; i++) {
1549 field ^= orig_fields.At(i);
1550 new_fields.SetAt(patch_len + i, field);
1551 }
1552 SetFields(new_fields);
1553 } 1582 }
1554 1583
1555 1584
1556 void Class::SetFields(const Array& value) const { 1585 void Class::SetFields(const Array& value) const {
1557 ASSERT(!value.IsNull()); 1586 ASSERT(!value.IsNull());
1558 #if defined(DEBUG) 1587 #if defined(DEBUG)
1559 // Verify that all the fields in the array have this class as owner. 1588 // Verify that all the fields in the array have this class as owner.
1560 Field& field = Field::Handle(); 1589 Field& field = Field::Handle();
1561 intptr_t len = value.Length(); 1590 intptr_t len = value.Length();
1562 for (intptr_t i = 0; i < len; i++) { 1591 for (intptr_t i = 0; i < len; i++) {
(...skipping 9661 matching lines...) Expand 10 before | Expand all | Expand 10 after
11224 const char* JSRegExp::ToCString() const { 11253 const char* JSRegExp::ToCString() const {
11225 const String& str = String::Handle(pattern()); 11254 const String& str = String::Handle(pattern());
11226 const char* format = "JSRegExp: pattern=%s flags=%s"; 11255 const char* format = "JSRegExp: pattern=%s flags=%s";
11227 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); 11256 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags());
11228 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); 11257 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
11229 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); 11258 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags());
11230 return chars; 11259 return chars;
11231 } 11260 }
11232 11261
11233 } // namespace dart 11262 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698