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