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 |