Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
| 6 | 6 |
| 7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
| 8 #include "src/debug/debug-evaluate.h" | 8 #include "src/debug/debug-evaluate.h" |
| 9 #include "src/debug/debug-frames.h" | 9 #include "src/debug/debug-frames.h" |
| 10 #include "src/debug/debug-scopes.h" | 10 #include "src/debug/debug-scopes.h" |
| (...skipping 1577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1588 | 1588 |
| 1589 // TODO(5530): Remove once uses in debug.js are gone. | 1589 // TODO(5530): Remove once uses in debug.js are gone. |
| 1590 RUNTIME_FUNCTION(Runtime_ScriptLineCount) { | 1590 RUNTIME_FUNCTION(Runtime_ScriptLineCount) { |
| 1591 HandleScope scope(isolate); | 1591 HandleScope scope(isolate); |
| 1592 DCHECK(args.length() == 1); | 1592 DCHECK(args.length() == 1); |
| 1593 CONVERT_ARG_CHECKED(JSValue, script, 0); | 1593 CONVERT_ARG_CHECKED(JSValue, script, 0); |
| 1594 | 1594 |
| 1595 CHECK(script->value()->IsScript()); | 1595 CHECK(script->value()->IsScript()); |
| 1596 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); | 1596 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); |
| 1597 | 1597 |
| 1598 if (script_handle->type() == Script::TYPE_WASM) { | |
| 1599 // Return 0 for now; this function will disappear soon anyway. | |
| 1600 return Smi::FromInt(0); | |
| 1601 } | |
| 1602 | |
| 1598 Script::InitLineEnds(script_handle); | 1603 Script::InitLineEnds(script_handle); |
| 1599 | 1604 |
| 1600 FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends()); | 1605 FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends()); |
| 1601 return Smi::FromInt(line_ends_array->length()); | 1606 return Smi::FromInt(line_ends_array->length()); |
| 1602 } | 1607 } |
| 1603 | 1608 |
| 1609 namespace { | |
| 1610 | |
| 1611 int ScriptLinePosition(Handle<Script> script, int line) { | |
| 1612 if (script->type() == Script::TYPE_WASM) { | |
| 1613 return WasmCompiledModule::cast(script->wasm_compiled_module()) | |
| 1614 ->GetFunctionOffset(line); | |
| 1615 } | |
| 1616 | |
| 1617 Script::InitLineEnds(script); | |
| 1618 | |
| 1619 FixedArray* line_ends_array = FixedArray::cast(script->line_ends()); | |
| 1620 const int line_count = line_ends_array->length(); | |
| 1621 DCHECK_LT(0, line_count); | |
| 1622 | |
| 1623 if (line == 0) return 0; | |
| 1624 // If line == line_count, we return the first position beyond the last line. | |
| 1625 if (line > line_count) return -1; | |
|
jgruber
2016/11/18 13:57:35
The old code also handles negative values of 'line
Clemens Hammacher
2016/11/18 14:14:28
Done.
| |
| 1626 return Smi::cast(line_ends_array->get(line - 1))->value() + 1; | |
| 1627 } | |
| 1628 | |
| 1629 } // namespace | |
| 1630 | |
| 1604 // TODO(5530): Remove once uses in debug.js are gone. | 1631 // TODO(5530): Remove once uses in debug.js are gone. |
| 1605 RUNTIME_FUNCTION(Runtime_ScriptLineStartPosition) { | 1632 RUNTIME_FUNCTION(Runtime_ScriptLineStartPosition) { |
| 1606 HandleScope scope(isolate); | 1633 HandleScope scope(isolate); |
| 1607 DCHECK(args.length() == 2); | 1634 DCHECK(args.length() == 2); |
| 1608 CONVERT_ARG_CHECKED(JSValue, script, 0); | 1635 CONVERT_ARG_CHECKED(JSValue, script, 0); |
| 1609 CONVERT_NUMBER_CHECKED(int32_t, line, Int32, args[1]); | 1636 CONVERT_NUMBER_CHECKED(int32_t, line, Int32, args[1]); |
| 1610 | 1637 |
| 1611 CHECK(script->value()->IsScript()); | 1638 CHECK(script->value()->IsScript()); |
| 1612 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); | 1639 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); |
| 1613 | 1640 |
| 1614 Script::InitLineEnds(script_handle); | 1641 return Smi::FromInt(ScriptLinePosition(script_handle, line)); |
| 1615 | |
| 1616 FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends()); | |
| 1617 const int line_count = line_ends_array->length(); | |
| 1618 | |
| 1619 // If line == line_count, we return the first position beyond the last line. | |
| 1620 if (line < 0 || line > line_count) { | |
| 1621 return Smi::FromInt(-1); | |
| 1622 } else if (line == 0) { | |
| 1623 return Smi::kZero; | |
| 1624 } else { | |
| 1625 DCHECK(0 < line && line <= line_count); | |
| 1626 const int pos = Smi::cast(line_ends_array->get(line - 1))->value() + 1; | |
| 1627 return Smi::FromInt(pos); | |
| 1628 } | |
| 1629 } | 1642 } |
| 1630 | 1643 |
| 1631 // TODO(5530): Remove once uses in debug.js are gone. | 1644 // TODO(5530): Remove once uses in debug.js are gone. |
| 1632 RUNTIME_FUNCTION(Runtime_ScriptLineEndPosition) { | 1645 RUNTIME_FUNCTION(Runtime_ScriptLineEndPosition) { |
| 1633 HandleScope scope(isolate); | 1646 HandleScope scope(isolate); |
| 1634 DCHECK(args.length() == 2); | 1647 DCHECK(args.length() == 2); |
| 1635 CONVERT_ARG_CHECKED(JSValue, script, 0); | 1648 CONVERT_ARG_CHECKED(JSValue, script, 0); |
| 1636 CONVERT_NUMBER_CHECKED(int32_t, line, Int32, args[1]); | 1649 CONVERT_NUMBER_CHECKED(int32_t, line, Int32, args[1]); |
| 1637 | 1650 |
| 1638 CHECK(script->value()->IsScript()); | 1651 CHECK(script->value()->IsScript()); |
| 1639 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); | 1652 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); |
| 1640 | 1653 |
| 1654 if (script_handle->type() == Script::TYPE_WASM) { | |
| 1655 // Return zero for now; this function will disappear soon anyway. | |
| 1656 return Smi::FromInt(0); | |
| 1657 } | |
| 1658 | |
| 1641 Script::InitLineEnds(script_handle); | 1659 Script::InitLineEnds(script_handle); |
| 1642 | 1660 |
| 1643 FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends()); | 1661 FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends()); |
| 1644 const int line_count = line_ends_array->length(); | 1662 const int line_count = line_ends_array->length(); |
| 1645 | 1663 |
| 1646 if (line < 0 || line >= line_count) { | 1664 if (line < 0 || line >= line_count) { |
| 1647 return Smi::FromInt(-1); | 1665 return Smi::FromInt(-1); |
| 1648 } else { | 1666 } else { |
| 1649 return Smi::cast(line_ends_array->get(line)); | 1667 return Smi::cast(line_ends_array->get(line)); |
| 1650 } | 1668 } |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1676 JSObject::AddProperty(jsinfo, isolate->factory()->column_string(), | 1694 JSObject::AddProperty(jsinfo, isolate->factory()->column_string(), |
| 1677 handle(Smi::FromInt(info.column), isolate), NONE); | 1695 handle(Smi::FromInt(info.column), isolate), NONE); |
| 1678 JSObject::AddProperty(jsinfo, isolate->factory()->sourceText_string(), | 1696 JSObject::AddProperty(jsinfo, isolate->factory()->sourceText_string(), |
| 1679 sourceText, NONE); | 1697 sourceText, NONE); |
| 1680 | 1698 |
| 1681 return jsinfo; | 1699 return jsinfo; |
| 1682 } | 1700 } |
| 1683 | 1701 |
| 1684 namespace { | 1702 namespace { |
| 1685 | 1703 |
| 1704 int ScriptLinePositionWithOffset(Handle<Script> script, int line, int offset) { | |
| 1705 if (line < 0 || offset < 0) return -1; | |
| 1706 | |
| 1707 if (line == 0) return ScriptLinePosition(script, line) + offset; | |
| 1708 | |
| 1709 Script::PositionInfo info; | |
| 1710 if (!Script::GetPositionInfo(script, offset, &info, Script::NO_OFFSET)) { | |
| 1711 return -1; | |
| 1712 } | |
| 1713 | |
| 1714 const int total_line = info.line + line; | |
| 1715 return ScriptLinePosition(script, total_line); | |
| 1716 } | |
| 1717 | |
| 1686 Handle<Object> ScriptLocationFromLine(Isolate* isolate, Handle<Script> script, | 1718 Handle<Object> ScriptLocationFromLine(Isolate* isolate, Handle<Script> script, |
| 1687 Handle<Object> opt_line, | 1719 Handle<Object> opt_line, |
| 1688 Handle<Object> opt_column, | 1720 Handle<Object> opt_column, |
| 1689 int32_t offset) { | 1721 int32_t offset) { |
| 1690 // Line and column are possibly undefined and we need to handle these cases, | 1722 // Line and column are possibly undefined and we need to handle these cases, |
| 1691 // additionally subtracting corresponding offsets. | 1723 // additionally subtracting corresponding offsets. |
| 1692 | 1724 |
| 1693 int32_t line; | 1725 int32_t line = 0; |
| 1694 if (opt_line->IsNull(isolate) || opt_line->IsUndefined(isolate)) { | 1726 if (!opt_line->IsNull(isolate) && !opt_line->IsUndefined(isolate)) { |
| 1695 line = 0; | |
| 1696 } else { | |
| 1697 CHECK(opt_line->IsNumber()); | 1727 CHECK(opt_line->IsNumber()); |
| 1698 line = NumberToInt32(*opt_line) - script->line_offset(); | 1728 line = NumberToInt32(*opt_line) - script->line_offset(); |
| 1699 } | 1729 } |
| 1700 | 1730 |
| 1701 int32_t column; | 1731 int32_t column = 0; |
| 1702 if (opt_column->IsNull(isolate) || opt_column->IsUndefined(isolate)) { | 1732 if (!opt_column->IsNull(isolate) && !opt_column->IsUndefined(isolate)) { |
| 1703 column = 0; | |
| 1704 } else { | |
| 1705 CHECK(opt_column->IsNumber()); | 1733 CHECK(opt_column->IsNumber()); |
| 1706 column = NumberToInt32(*opt_column); | 1734 column = NumberToInt32(*opt_column); |
| 1707 if (line == 0) column -= script->column_offset(); | 1735 if (line == 0) column -= script->column_offset(); |
| 1708 } | 1736 } |
| 1709 | 1737 |
| 1710 if (line < 0 || column < 0 || offset < 0) { | 1738 int line_position = ScriptLinePositionWithOffset(script, line, offset); |
| 1711 return isolate->factory()->null_value(); | 1739 if (line_position < 0 || column < 0) return isolate->factory()->null_value(); |
| 1712 } | |
| 1713 | 1740 |
| 1714 Script::InitLineEnds(script); | 1741 return GetJSPositionInfo(script, line_position + column, Script::NO_OFFSET, |
| 1715 | 1742 isolate); |
| 1716 FixedArray* line_ends_array = FixedArray::cast(script->line_ends()); | |
| 1717 const int line_count = line_ends_array->length(); | |
| 1718 | |
| 1719 int position; | |
| 1720 if (line == 0) { | |
| 1721 position = offset + column; | |
| 1722 } else { | |
| 1723 Script::PositionInfo info; | |
| 1724 if (!Script::GetPositionInfo(script, offset, &info, Script::NO_OFFSET) || | |
| 1725 info.line + line >= line_count) { | |
| 1726 return isolate->factory()->null_value(); | |
| 1727 } | |
| 1728 | |
| 1729 const int offset_line = info.line + line; | |
| 1730 const int offset_line_position = | |
| 1731 (offset_line == 0) | |
| 1732 ? 0 | |
| 1733 : Smi::cast(line_ends_array->get(offset_line - 1))->value() + 1; | |
| 1734 position = offset_line_position + column; | |
| 1735 } | |
| 1736 | |
| 1737 return GetJSPositionInfo(script, position, Script::NO_OFFSET, isolate); | |
| 1738 } | 1743 } |
| 1739 | 1744 |
| 1740 // Slow traversal over all scripts on the heap. | 1745 // Slow traversal over all scripts on the heap. |
| 1741 bool GetScriptById(Isolate* isolate, int needle, Handle<Script>* result) { | 1746 bool GetScriptById(Isolate* isolate, int needle, Handle<Script>* result) { |
| 1742 Script::Iterator iterator(isolate); | 1747 Script::Iterator iterator(isolate); |
| 1743 Script* script = NULL; | 1748 Script* script = NULL; |
| 1744 while ((script = iterator.Next()) != NULL) { | 1749 while ((script = iterator.Next()) != NULL) { |
| 1745 if (script->id() == needle) { | 1750 if (script->id() == needle) { |
| 1746 *result = handle(script); | 1751 *result = handle(script); |
| 1747 return true; | 1752 return true; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1813 // TODO(5530): Remove once uses in debug.js are gone. | 1818 // TODO(5530): Remove once uses in debug.js are gone. |
| 1814 RUNTIME_FUNCTION(Runtime_ScriptSourceLine) { | 1819 RUNTIME_FUNCTION(Runtime_ScriptSourceLine) { |
| 1815 HandleScope scope(isolate); | 1820 HandleScope scope(isolate); |
| 1816 DCHECK(args.length() == 2); | 1821 DCHECK(args.length() == 2); |
| 1817 CONVERT_ARG_CHECKED(JSValue, script, 0); | 1822 CONVERT_ARG_CHECKED(JSValue, script, 0); |
| 1818 CONVERT_NUMBER_CHECKED(int32_t, line, Int32, args[1]); | 1823 CONVERT_NUMBER_CHECKED(int32_t, line, Int32, args[1]); |
| 1819 | 1824 |
| 1820 CHECK(script->value()->IsScript()); | 1825 CHECK(script->value()->IsScript()); |
| 1821 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); | 1826 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); |
| 1822 | 1827 |
| 1828 if (script_handle->type() == Script::TYPE_WASM) { | |
| 1829 // Return null for now; this function will disappear soon anyway. | |
| 1830 return isolate->heap()->null_value(); | |
| 1831 } | |
| 1832 | |
| 1823 Script::InitLineEnds(script_handle); | 1833 Script::InitLineEnds(script_handle); |
| 1824 | 1834 |
| 1825 FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends()); | 1835 FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends()); |
| 1826 const int line_count = line_ends_array->length(); | 1836 const int line_count = line_ends_array->length(); |
| 1827 | 1837 |
| 1828 line -= script_handle->line_offset(); | 1838 line -= script_handle->line_offset(); |
| 1829 if (line < 0 || line_count <= line) { | 1839 if (line < 0 || line_count <= line) { |
| 1830 return isolate->heap()->null_value(); | 1840 return isolate->heap()->null_value(); |
| 1831 } | 1841 } |
| 1832 | 1842 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1908 } | 1918 } |
| 1909 | 1919 |
| 1910 | 1920 |
| 1911 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { | 1921 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { |
| 1912 UNIMPLEMENTED(); | 1922 UNIMPLEMENTED(); |
| 1913 return NULL; | 1923 return NULL; |
| 1914 } | 1924 } |
| 1915 | 1925 |
| 1916 } // namespace internal | 1926 } // namespace internal |
| 1917 } // namespace v8 | 1927 } // namespace v8 |
| OLD | NEW |