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 |