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 1544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1555 FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends()); | 1555 FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends()); |
1556 const int line_count = line_ends_array->length(); | 1556 const int line_count = line_ends_array->length(); |
1557 | 1557 |
1558 if (line < 0 || line >= line_count) { | 1558 if (line < 0 || line >= line_count) { |
1559 return Smi::FromInt(-1); | 1559 return Smi::FromInt(-1); |
1560 } else { | 1560 } else { |
1561 return Smi::cast(line_ends_array->get(line)); | 1561 return Smi::cast(line_ends_array->get(line)); |
1562 } | 1562 } |
1563 } | 1563 } |
1564 | 1564 |
1565 RUNTIME_FUNCTION(Runtime_ScriptPositionInfo) { | 1565 static Handle<Object> GetJSPositionInfo(Handle<Script> script, int position, |
1566 HandleScope scope(isolate); | 1566 Script::OffsetFlag offset_flag, |
1567 DCHECK(args.length() == 3); | 1567 Isolate* isolate) { |
1568 CONVERT_ARG_CHECKED(JSValue, script, 0); | |
1569 CONVERT_NUMBER_CHECKED(int32_t, position, Int32, args[1]); | |
1570 CONVERT_BOOLEAN_ARG_CHECKED(with_offset, 2); | |
1571 | |
1572 RUNTIME_ASSERT(script->value()->IsScript()); | |
1573 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); | |
1574 | |
1575 Script::PositionInfo info; | 1568 Script::PositionInfo info; |
1576 const Script::OffsetFlag offset_flag = | 1569 if (!script->GetPositionInfo(position, &info, offset_flag)) { |
1577 with_offset ? Script::WITH_OFFSET : Script::NO_OFFSET; | 1570 return handle(isolate->heap()->null_value(), isolate); |
1578 if (!script_handle->GetPositionInfo(position, &info, offset_flag)) { | |
1579 return isolate->heap()->null_value(); | |
1580 } | 1571 } |
1581 | 1572 |
1582 Handle<String> source = | 1573 Handle<String> source = handle(String::cast(script->source()), isolate); |
1583 handle(String::cast(script_handle->source()), isolate); | |
1584 Handle<String> sourceText = | 1574 Handle<String> sourceText = |
1585 isolate->factory()->NewSubString(source, info.line_start, info.line_end); | 1575 isolate->factory()->NewSubString(source, info.line_start, info.line_end); |
1586 | 1576 |
1587 Handle<JSObject> jsinfo = | 1577 Handle<JSObject> jsinfo = |
1588 isolate->factory()->NewJSObject(isolate->object_function()); | 1578 isolate->factory()->NewJSObject(isolate->object_function()); |
1589 | 1579 |
1590 JSObject::AddProperty(jsinfo, isolate->factory()->script_string(), | 1580 JSObject::AddProperty(jsinfo, isolate->factory()->script_string(), script, |
1591 script_handle, NONE); | 1581 NONE); |
1592 JSObject::AddProperty(jsinfo, isolate->factory()->position_string(), | 1582 JSObject::AddProperty(jsinfo, isolate->factory()->position_string(), |
1593 handle(Smi::FromInt(position), isolate), NONE); | 1583 handle(Smi::FromInt(position), isolate), NONE); |
1594 JSObject::AddProperty(jsinfo, isolate->factory()->line_string(), | 1584 JSObject::AddProperty(jsinfo, isolate->factory()->line_string(), |
1595 handle(Smi::FromInt(info.line), isolate), NONE); | 1585 handle(Smi::FromInt(info.line), isolate), NONE); |
1596 JSObject::AddProperty(jsinfo, isolate->factory()->column_string(), | 1586 JSObject::AddProperty(jsinfo, isolate->factory()->column_string(), |
1597 handle(Smi::FromInt(info.column), isolate), NONE); | 1587 handle(Smi::FromInt(info.column), isolate), NONE); |
1598 JSObject::AddProperty(jsinfo, isolate->factory()->sourceText_string(), | 1588 JSObject::AddProperty(jsinfo, isolate->factory()->sourceText_string(), |
1599 sourceText, NONE); | 1589 sourceText, NONE); |
1600 | 1590 |
1601 return *jsinfo; | 1591 return jsinfo; |
| 1592 } |
| 1593 |
| 1594 // Get information on a specific source line and column possibly offset by a |
| 1595 // fixed source position. This function is used to find a source position from |
| 1596 // a line and column position. The fixed source position offset is typically |
| 1597 // used to find a source position in a function based on a line and column in |
| 1598 // the source for the function alone. The offset passed will then be the |
| 1599 // start position of the source for the function within the full script source. |
| 1600 // Note that incoming line and column parameters may be undefined, and are |
| 1601 // assumed to be passed *with* offsets. |
| 1602 RUNTIME_FUNCTION(Runtime_ScriptLocationFromLine) { |
| 1603 HandleScope scope(isolate); |
| 1604 DCHECK(args.length() == 4); |
| 1605 CONVERT_ARG_CHECKED(JSValue, script, 0); |
| 1606 |
| 1607 RUNTIME_ASSERT(script->value()->IsScript()); |
| 1608 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); |
| 1609 |
| 1610 // Line and column are possibly undefined and we need to handle these cases, |
| 1611 // additionally subtracting corresponding offsets. |
| 1612 |
| 1613 int32_t line; |
| 1614 if (args[1]->IsNull() || args[1]->IsUndefined()) { |
| 1615 line = 0; |
| 1616 } else { |
| 1617 RUNTIME_ASSERT(args[1]->IsNumber()); |
| 1618 line = NumberToInt32(args[1]) - script_handle->line_offset(); |
| 1619 } |
| 1620 |
| 1621 int32_t column; |
| 1622 if (args[2]->IsNull() || args[2]->IsUndefined()) { |
| 1623 column = 0; |
| 1624 } else { |
| 1625 RUNTIME_ASSERT(args[2]->IsNumber()); |
| 1626 column = NumberToInt32(args[2]); |
| 1627 if (line == 0) column -= script_handle->column_offset(); |
| 1628 } |
| 1629 |
| 1630 CONVERT_NUMBER_CHECKED(int32_t, offset_position, Int32, args[3]); |
| 1631 |
| 1632 if (line < 0 || column < 0 || offset_position < 0) { |
| 1633 return isolate->heap()->null_value(); |
| 1634 } |
| 1635 |
| 1636 Script::InitLineEnds(script_handle); |
| 1637 |
| 1638 FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends()); |
| 1639 const int line_count = line_ends_array->length(); |
| 1640 |
| 1641 int position; |
| 1642 if (line == 0) { |
| 1643 position = offset_position + column; |
| 1644 } else { |
| 1645 Script::PositionInfo info; |
| 1646 if (!script_handle->GetPositionInfo(offset_position, &info, |
| 1647 Script::NO_OFFSET) || |
| 1648 info.line + line >= line_count) { |
| 1649 return isolate->heap()->null_value(); |
| 1650 } |
| 1651 |
| 1652 const int offset_line = info.line + line; |
| 1653 const int offset_line_position = |
| 1654 (offset_line == 0) |
| 1655 ? 0 |
| 1656 : Smi::cast(line_ends_array->get(offset_line - 1))->value() + 1; |
| 1657 position = offset_line_position + column; |
| 1658 } |
| 1659 |
| 1660 return *GetJSPositionInfo(script_handle, position, Script::NO_OFFSET, |
| 1661 isolate); |
| 1662 } |
| 1663 |
| 1664 RUNTIME_FUNCTION(Runtime_ScriptPositionInfo) { |
| 1665 HandleScope scope(isolate); |
| 1666 DCHECK(args.length() == 3); |
| 1667 CONVERT_ARG_CHECKED(JSValue, script, 0); |
| 1668 CONVERT_NUMBER_CHECKED(int32_t, position, Int32, args[1]); |
| 1669 CONVERT_BOOLEAN_ARG_CHECKED(with_offset, 2); |
| 1670 |
| 1671 RUNTIME_ASSERT(script->value()->IsScript()); |
| 1672 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); |
| 1673 |
| 1674 const Script::OffsetFlag offset_flag = |
| 1675 with_offset ? Script::WITH_OFFSET : Script::NO_OFFSET; |
| 1676 return *GetJSPositionInfo(script_handle, position, offset_flag, isolate); |
| 1677 } |
| 1678 |
| 1679 // Returns the given line as a string, or null if line is out of bounds. |
| 1680 // The parameter line is expected to include the script's line offset. |
| 1681 RUNTIME_FUNCTION(Runtime_ScriptSourceLine) { |
| 1682 HandleScope scope(isolate); |
| 1683 DCHECK(args.length() == 2); |
| 1684 CONVERT_ARG_CHECKED(JSValue, script, 0); |
| 1685 CONVERT_NUMBER_CHECKED(int32_t, line, Int32, args[1]); |
| 1686 |
| 1687 RUNTIME_ASSERT(script->value()->IsScript()); |
| 1688 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); |
| 1689 |
| 1690 Script::InitLineEnds(script_handle); |
| 1691 |
| 1692 FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends()); |
| 1693 const int line_count = line_ends_array->length(); |
| 1694 |
| 1695 line -= script_handle->line_offset(); |
| 1696 if (line < 0 || line_count <= line) { |
| 1697 return isolate->heap()->null_value(); |
| 1698 } |
| 1699 |
| 1700 const int start = |
| 1701 (line == 0) ? 0 : Smi::cast(line_ends_array->get(line - 1))->value() + 1; |
| 1702 const int end = Smi::cast(line_ends_array->get(line))->value(); |
| 1703 |
| 1704 Handle<String> source = |
| 1705 handle(String::cast(script_handle->source()), isolate); |
| 1706 Handle<String> str = isolate->factory()->NewSubString(source, start, end); |
| 1707 |
| 1708 return *str; |
1602 } | 1709 } |
1603 | 1710 |
1604 // Set one shot breakpoints for the callback function that is passed to a | 1711 // Set one shot breakpoints for the callback function that is passed to a |
1605 // built-in function such as Array.forEach to enable stepping into the callback, | 1712 // built-in function such as Array.forEach to enable stepping into the callback, |
1606 // if we are indeed stepping and the callback is subject to debugging. | 1713 // if we are indeed stepping and the callback is subject to debugging. |
1607 RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) { | 1714 RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) { |
1608 HandleScope scope(isolate); | 1715 HandleScope scope(isolate); |
1609 DCHECK_EQ(1, args.length()); | 1716 DCHECK_EQ(1, args.length()); |
1610 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); | 1717 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); |
1611 isolate->debug()->PrepareStepIn(fun); | 1718 isolate->debug()->PrepareStepIn(fun); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1647 return Smi::FromInt(isolate->debug()->is_active()); | 1754 return Smi::FromInt(isolate->debug()->is_active()); |
1648 } | 1755 } |
1649 | 1756 |
1650 | 1757 |
1651 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { | 1758 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { |
1652 UNIMPLEMENTED(); | 1759 UNIMPLEMENTED(); |
1653 return NULL; | 1760 return NULL; |
1654 } | 1761 } |
1655 } // namespace internal | 1762 } // namespace internal |
1656 } // namespace v8 | 1763 } // namespace v8 |
OLD | NEW |