| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/service.h" | 5 #include "vm/service.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "platform/globals.h" | 8 #include "platform/globals.h" |
| 9 | 9 |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 Dart_ServiceRequestCallback callback_; | 148 Dart_ServiceRequestCallback callback_; |
| 149 void* user_data_; | 149 void* user_data_; |
| 150 EmbedderServiceHandler* next_; | 150 EmbedderServiceHandler* next_; |
| 151 }; | 151 }; |
| 152 | 152 |
| 153 | 153 |
| 154 class LibraryCoverageFilter : public CoverageFilter { | 154 class LibraryCoverageFilter : public CoverageFilter { |
| 155 public: | 155 public: |
| 156 explicit LibraryCoverageFilter(const Library& lib) : lib_(lib) {} | 156 explicit LibraryCoverageFilter(const Library& lib) : lib_(lib) {} |
| 157 bool ShouldOutputCoverageFor(const Library& lib, | 157 bool ShouldOutputCoverageFor(const Library& lib, |
| 158 const String& script_url, | 158 const Script& script, |
| 159 const Class& cls, | 159 const Class& cls, |
| 160 const Function& func) const { | 160 const Function& func) const { |
| 161 return lib.raw() == lib_.raw(); | 161 return lib.raw() == lib_.raw(); |
| 162 } | 162 } |
| 163 private: | 163 private: |
| 164 const Library& lib_; | 164 const Library& lib_; |
| 165 }; | 165 }; |
| 166 | 166 |
| 167 | 167 |
| 168 class ScriptCoverageFilter : public CoverageFilter { | 168 class ScriptCoverageFilter : public CoverageFilter { |
| 169 public: | 169 public: |
| 170 explicit ScriptCoverageFilter(const String& script_url) | 170 explicit ScriptCoverageFilter(const Script& script) |
| 171 : script_url_(script_url) {} | 171 : script_(script) {} |
| 172 bool ShouldOutputCoverageFor(const Library& lib, | 172 bool ShouldOutputCoverageFor(const Library& lib, |
| 173 const String& script_url, | 173 const Script& script, |
| 174 const Class& cls, | 174 const Class& cls, |
| 175 const Function& func) const { | 175 const Function& func) const { |
| 176 return script_url_.Equals(script_url); | 176 return script.raw() == script_.raw(); |
| 177 } | 177 } |
| 178 private: | 178 private: |
| 179 const String& script_url_; | 179 const Script& script_; |
| 180 }; | 180 }; |
| 181 | 181 |
| 182 | 182 |
| 183 class ClassCoverageFilter : public CoverageFilter { | 183 class ClassCoverageFilter : public CoverageFilter { |
| 184 public: | 184 public: |
| 185 explicit ClassCoverageFilter(const Class& cls) : cls_(cls) {} | 185 explicit ClassCoverageFilter(const Class& cls) : cls_(cls) {} |
| 186 bool ShouldOutputCoverageFor(const Library& lib, | 186 bool ShouldOutputCoverageFor(const Library& lib, |
| 187 const String& script_url, | 187 const Script& script, |
| 188 const Class& cls, | 188 const Class& cls, |
| 189 const Function& func) const { | 189 const Function& func) const { |
| 190 return cls.raw() == cls_.raw(); | 190 return cls.raw() == cls_.raw(); |
| 191 } | 191 } |
| 192 private: | 192 private: |
| 193 const Class& cls_; | 193 const Class& cls_; |
| 194 }; | 194 }; |
| 195 | 195 |
| 196 | 196 |
| 197 class FunctionCoverageFilter : public CoverageFilter { | 197 class FunctionCoverageFilter : public CoverageFilter { |
| 198 public: | 198 public: |
| 199 explicit FunctionCoverageFilter(const Function& func) : func_(func) {} | 199 explicit FunctionCoverageFilter(const Function& func) : func_(func) {} |
| 200 bool ShouldOutputCoverageFor(const Library& lib, | 200 bool ShouldOutputCoverageFor(const Library& lib, |
| 201 const String& script_url, | 201 const Script& script, |
| 202 const Class& cls, | 202 const Class& cls, |
| 203 const Function& func) const { | 203 const Function& func) const { |
| 204 return func.raw() == func_.raw(); | 204 return func.raw() == func_.raw(); |
| 205 } | 205 } |
| 206 private: | 206 private: |
| 207 const Function& func_; | 207 const Function& func_; |
| 208 }; | 208 }; |
| 209 | 209 |
| 210 | 210 |
| 211 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { | 211 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { |
| (...skipping 1189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1401 } | 1401 } |
| 1402 const String& expr_str = String::Handle(isolate, String::New(expr)); | 1402 const String& expr_str = String::Handle(isolate, String::New(expr)); |
| 1403 const Object& result = Object::Handle(lib.Evaluate(expr_str, | 1403 const Object& result = Object::Handle(lib.Evaluate(expr_str, |
| 1404 Array::empty_array(), | 1404 Array::empty_array(), |
| 1405 Array::empty_array())); | 1405 Array::empty_array())); |
| 1406 result.PrintJSON(js, true); | 1406 result.PrintJSON(js, true); |
| 1407 return true; | 1407 return true; |
| 1408 } | 1408 } |
| 1409 | 1409 |
| 1410 | 1410 |
| 1411 static bool HandleLibrariesScriptsCoverage( |
| 1412 Isolate* isolate, const Script& script, JSONStream* js) { |
| 1413 ScriptCoverageFilter sf(script); |
| 1414 CodeCoverage::PrintJSON(isolate, js, &sf); |
| 1415 return true; |
| 1416 } |
| 1417 |
| 1418 |
| 1419 static bool HandleLibrariesScripts(Isolate* isolate, |
| 1420 const Library& lib, |
| 1421 JSONStream* js) { |
| 1422 if (js->num_arguments() > 5) { |
| 1423 PrintError(js, "Command too long"); |
| 1424 return true; |
| 1425 } else if (js->num_arguments() < 4) { |
| 1426 PrintError(js, "Must specify collection object id: scripts/id"); |
| 1427 return true; |
| 1428 } |
| 1429 const String& id = String::Handle(String::New(js->GetArgument(3))); |
| 1430 ASSERT(!id.IsNull()); |
| 1431 // The id is the url of the script % encoded, decode it. |
| 1432 const String& requested_url = String::Handle(String::DecodeURI(id)); |
| 1433 Script& script = Script::Handle(); |
| 1434 String& script_url = String::Handle(); |
| 1435 const Array& loaded_scripts = Array::Handle(lib.LoadedScripts()); |
| 1436 ASSERT(!loaded_scripts.IsNull()); |
| 1437 intptr_t i; |
| 1438 for (i = 0; i < loaded_scripts.Length(); i++) { |
| 1439 script ^= loaded_scripts.At(i); |
| 1440 ASSERT(!script.IsNull()); |
| 1441 script_url ^= script.url(); |
| 1442 if (script_url.Equals(requested_url)) { |
| 1443 break; |
| 1444 } |
| 1445 } |
| 1446 if (i == loaded_scripts.Length()) { |
| 1447 PrintError(js, "Script %s not found", requested_url.ToCString()); |
| 1448 return true; |
| 1449 } |
| 1450 if (js->num_arguments() == 4) { |
| 1451 script.PrintJSON(js, false); |
| 1452 return true; |
| 1453 } else { |
| 1454 const char* subcollection = js->GetArgument(4); |
| 1455 if (strcmp(subcollection, "coverage") == 0) { |
| 1456 return HandleLibrariesScriptsCoverage(isolate, script, js); |
| 1457 } else { |
| 1458 PrintError(js, "Invalid sub collection %s", subcollection); |
| 1459 return true; |
| 1460 } |
| 1461 } |
| 1462 UNREACHABLE(); |
| 1463 return true; |
| 1464 } |
| 1465 |
| 1466 |
| 1411 static bool HandleLibrariesCoverage(Isolate* isolate, | 1467 static bool HandleLibrariesCoverage(Isolate* isolate, |
| 1412 const Library& lib, | 1468 const Library& lib, |
| 1413 JSONStream* js) { | 1469 JSONStream* js) { |
| 1414 LibraryCoverageFilter lf(lib); | 1470 LibraryCoverageFilter lf(lib); |
| 1415 CodeCoverage::PrintJSON(isolate, js, &lf); | 1471 CodeCoverage::PrintJSON(isolate, js, &lf); |
| 1416 return true; | 1472 return true; |
| 1417 } | 1473 } |
| 1418 | 1474 |
| 1419 | 1475 |
| 1420 static bool HandleLibraries(Isolate* isolate, JSONStream* js) { | 1476 static bool HandleLibraries(Isolate* isolate, JSONStream* js) { |
| 1421 // TODO(johnmccutchan): Support fields and functions on libraries. | 1477 // TODO(johnmccutchan): Support fields and functions on libraries. |
| 1422 REQUIRE_COLLECTION_ID("libraries"); | 1478 REQUIRE_COLLECTION_ID("libraries"); |
| 1423 const GrowableObjectArray& libs = | 1479 const GrowableObjectArray& libs = |
| 1424 GrowableObjectArray::Handle(isolate->object_store()->libraries()); | 1480 GrowableObjectArray::Handle(isolate->object_store()->libraries()); |
| 1425 ASSERT(!libs.IsNull()); | 1481 ASSERT(!libs.IsNull()); |
| 1426 intptr_t id = 0; | 1482 intptr_t id = 0; |
| 1427 CHECK_COLLECTION_ID_BOUNDS("libraries", libs.Length(), js->GetArgument(1), | 1483 CHECK_COLLECTION_ID_BOUNDS("libraries", libs.Length(), js->GetArgument(1), |
| 1428 id, js); | 1484 id, js); |
| 1429 Library& lib = Library::Handle(); | 1485 Library& lib = Library::Handle(); |
| 1430 lib ^= libs.At(id); | 1486 lib ^= libs.At(id); |
| 1431 ASSERT(!lib.IsNull()); | 1487 ASSERT(!lib.IsNull()); |
| 1432 if (js->num_arguments() == 2) { | 1488 if (js->num_arguments() == 2) { |
| 1433 lib.PrintJSON(js, false); | 1489 lib.PrintJSON(js, false); |
| 1434 return true; | 1490 return true; |
| 1435 } else if (js->num_arguments() >= 3) { | 1491 } else if (js->num_arguments() >= 3) { |
| 1436 const char* second = js->GetArgument(2); | 1492 const char* second = js->GetArgument(2); |
| 1437 if (strcmp(second, "eval") == 0) { | 1493 if (strcmp(second, "eval") == 0) { |
| 1438 return HandleLibrariesEval(isolate, lib, js); | 1494 return HandleLibrariesEval(isolate, lib, js); |
| 1495 } else if (strcmp(second, "scripts") == 0) { |
| 1496 return HandleLibrariesScripts(isolate, lib, js); |
| 1439 } else if (strcmp(second, "coverage") == 0) { | 1497 } else if (strcmp(second, "coverage") == 0) { |
| 1440 return HandleLibrariesCoverage(isolate, lib, js); | 1498 return HandleLibrariesCoverage(isolate, lib, js); |
| 1441 } else { | 1499 } else { |
| 1442 PrintError(js, "Invalid sub collection %s", second); | 1500 PrintError(js, "Invalid sub collection %s", second); |
| 1443 return true; | 1501 return true; |
| 1444 } | 1502 } |
| 1445 } | 1503 } |
| 1446 UNREACHABLE(); | 1504 UNREACHABLE(); |
| 1447 return true; | 1505 return true; |
| 1448 } | 1506 } |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1602 intptr_t num_scripts = loaded_scripts.Length(); | 1660 intptr_t num_scripts = loaded_scripts.Length(); |
| 1603 for (intptr_t i = 0; i < num_scripts; i++) { | 1661 for (intptr_t i = 0; i < num_scripts; i++) { |
| 1604 script ^= loaded_scripts.At(i); | 1662 script ^= loaded_scripts.At(i); |
| 1605 members.AddValue(script); | 1663 members.AddValue(script); |
| 1606 } | 1664 } |
| 1607 } | 1665 } |
| 1608 return true; | 1666 return true; |
| 1609 } | 1667 } |
| 1610 | 1668 |
| 1611 | 1669 |
| 1612 static bool HandleScriptsFetch( | |
| 1613 Isolate* isolate, const Script& script, JSONStream* js) { | |
| 1614 script.PrintJSON(js, false); | |
| 1615 return true; | |
| 1616 } | |
| 1617 | |
| 1618 | |
| 1619 static bool HandleScriptsCoverage( | |
| 1620 Isolate* isolate, const String& script_url, JSONStream* js) { | |
| 1621 ScriptCoverageFilter sf(script_url); | |
| 1622 CodeCoverage::PrintJSON(isolate, js, &sf); | |
| 1623 return true; | |
| 1624 } | |
| 1625 | |
| 1626 | |
| 1627 static bool HandleScripts(Isolate* isolate, JSONStream* js) { | 1670 static bool HandleScripts(Isolate* isolate, JSONStream* js) { |
| 1628 if (js->num_arguments() == 1) { | 1671 if (js->num_arguments() == 1) { |
| 1629 // Enumerate all scripts. | 1672 // Enumerate all scripts. |
| 1630 return HandleScriptsEnumerate(isolate, js); | 1673 return HandleScriptsEnumerate(isolate, js); |
| 1631 } | 1674 } |
| 1632 // Subcommands of scripts require a valid script id. | 1675 PrintError(js, "Command too long"); |
| 1633 const String& id = String::Handle(String::New(js->GetArgument(1))); | 1676 return true; |
| 1634 ASSERT(!id.IsNull()); | |
| 1635 // The id is the url of the script % encoded, decode it. | |
| 1636 String& requested_url = String::Handle(String::DecodeURI(id)); | |
| 1637 Script& script = Script::Handle(); | |
| 1638 // There may exist more than one script object for a given url. Since they all | |
| 1639 // have the same properties (source, tokens) we don't care which one we get. | |
| 1640 const GrowableObjectArray& libs = GrowableObjectArray::Handle( | |
| 1641 isolate, isolate->object_store()->libraries()); | |
| 1642 Library& lib = Library::Handle(); | |
| 1643 String& script_url = String::Handle(); | |
| 1644 bool found = false; | |
| 1645 for (intptr_t i = 0; !found && (i < libs.Length()); i++) { | |
| 1646 lib ^= libs.At(i); | |
| 1647 ASSERT(!lib.IsNull()); | |
| 1648 const Array& loaded_scripts = Array::Handle(lib.LoadedScripts()); | |
| 1649 ASSERT(!loaded_scripts.IsNull()); | |
| 1650 for (intptr_t j = 0; !found && (j < loaded_scripts.Length()); j++) { | |
| 1651 script ^= loaded_scripts.At(j); | |
| 1652 ASSERT(!script.IsNull()); | |
| 1653 script_url ^= script.url(); | |
| 1654 if (script_url.Equals(requested_url)) { | |
| 1655 found = true; | |
| 1656 } | |
| 1657 } | |
| 1658 } | |
| 1659 if (!found) { | |
| 1660 PrintErrorWithKind(js, "NotFoundError", "Cannot find script %s", | |
| 1661 requested_url.ToCString()); | |
| 1662 return true; | |
| 1663 } | |
| 1664 if (js->num_arguments() == 2) { | |
| 1665 // If no subcommand is given, just fetch the script. | |
| 1666 return HandleScriptsFetch(isolate, script, js); | |
| 1667 } else if (js->num_arguments() == 3) { | |
| 1668 const char* arg = js->GetArgument(2); | |
| 1669 if (strcmp(arg, "coverage") == 0) { | |
| 1670 return HandleScriptsCoverage(isolate, requested_url, js); | |
| 1671 } | |
| 1672 PrintError(js, "Unrecognized subcommand '%s'", arg); | |
| 1673 return true; | |
| 1674 } else { | |
| 1675 PrintError(js, "Command too long"); | |
| 1676 return true; | |
| 1677 } | |
| 1678 } | 1677 } |
| 1679 | 1678 |
| 1680 | 1679 |
| 1681 static bool HandleDebugResume(Isolate* isolate, JSONStream* js) { | 1680 static bool HandleDebugResume(Isolate* isolate, JSONStream* js) { |
| 1682 if (isolate->message_handler()->paused_on_start()) { | 1681 if (isolate->message_handler()->paused_on_start()) { |
| 1683 isolate->message_handler()->set_pause_on_start(false); | 1682 isolate->message_handler()->set_pause_on_start(false); |
| 1684 JSONObject jsobj(js); | 1683 JSONObject jsobj(js); |
| 1685 jsobj.AddProperty("type", "Success"); | 1684 jsobj.AddProperty("type", "Success"); |
| 1686 jsobj.AddProperty("id", ""); | 1685 jsobj.AddProperty("id", ""); |
| 1687 return true; | 1686 return true; |
| (...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2381 while (current != NULL) { | 2380 while (current != NULL) { |
| 2382 if (strcmp(name, current->name()) == 0) { | 2381 if (strcmp(name, current->name()) == 0) { |
| 2383 return current; | 2382 return current; |
| 2384 } | 2383 } |
| 2385 current = current->next(); | 2384 current = current->next(); |
| 2386 } | 2385 } |
| 2387 return NULL; | 2386 return NULL; |
| 2388 } | 2387 } |
| 2389 | 2388 |
| 2390 } // namespace dart | 2389 } // namespace dart |
| OLD | NEW |