| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |