| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/api.h" | 5 #include "src/api.h" |
| 6 | 6 |
| 7 #include <string.h> // For memcpy, strlen. | 7 #include <string.h> // For memcpy, strlen. |
| 8 #ifdef V8_USE_ADDRESS_SANITIZER | 8 #ifdef V8_USE_ADDRESS_SANITIZER |
| 9 #include <sanitizer/asan_interface.h> | 9 #include <sanitizer/asan_interface.h> |
| 10 #endif // V8_USE_ADDRESS_SANITIZER | 10 #endif // V8_USE_ADDRESS_SANITIZER |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 | 89 |
| 90 #define EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, value) \ | 90 #define EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, value) \ |
| 91 EXCEPTION_BAILOUT_CHECK_GENERIC( \ | 91 EXCEPTION_BAILOUT_CHECK_GENERIC( \ |
| 92 isolate, value, isolate->FireCallCompletedCallback();) | 92 isolate, value, isolate->FireCallCompletedCallback();) |
| 93 | 93 |
| 94 | 94 |
| 95 #define EXCEPTION_BAILOUT_CHECK(isolate, value) \ | 95 #define EXCEPTION_BAILOUT_CHECK(isolate, value) \ |
| 96 EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, ;) | 96 EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, ;) |
| 97 | 97 |
| 98 | 98 |
| 99 #define PREPARE_FOR_EXECUTION_GENERIC(context, function_name, bailout_value, \ | 99 #define PREPARE_FOR_EXECUTION_GENERIC(isolate, context, function_name, \ |
| 100 HandleScopeClass, do_callback) \ | 100 bailout_value, HandleScopeClass, \ |
| 101 do_callback) \ |
| 102 if (IsExecutionTerminatingCheck(isolate)) { \ |
| 103 return bailout_value; \ |
| 104 } \ |
| 105 HandleScopeClass handle_scope(isolate); \ |
| 106 CallDepthScope call_depth_scope(isolate, context, do_callback); \ |
| 107 LOG_API(isolate, function_name); \ |
| 108 ENTER_V8(isolate); \ |
| 109 bool has_pending_exception = false |
| 110 |
| 111 |
| 112 #define PREPARE_FOR_EXECUTION_WITH_CONTEXT( \ |
| 113 context, function_name, bailout_value, HandleScopeClass, do_callback) \ |
| 101 auto isolate = context.IsEmpty() \ | 114 auto isolate = context.IsEmpty() \ |
| 102 ? i::Isolate::Current() \ | 115 ? i::Isolate::Current() \ |
| 103 : reinterpret_cast<i::Isolate*>(context->GetIsolate()); \ | 116 : reinterpret_cast<i::Isolate*>(context->GetIsolate()); \ |
| 104 if (IsExecutionTerminatingCheck(isolate)) { \ | 117 PREPARE_FOR_EXECUTION_GENERIC(isolate, context, function_name, \ |
| 105 return bailout_value; \ | 118 bailout_value, HandleScopeClass, do_callback); |
| 106 } \ | |
| 107 HandleScopeClass handle_scope(isolate); \ | |
| 108 CallDepthScope call_depth_scope(isolate, context, do_callback); \ | |
| 109 LOG_API(isolate, function_name); \ | |
| 110 ENTER_V8(isolate); \ | |
| 111 bool has_pending_exception = false | |
| 112 | 119 |
| 113 | 120 |
| 114 #define PREPARE_FOR_EXECUTION(context, function_name, T) \ | 121 #define PREPARE_FOR_EXECUTION_WITH_ISOLATE(isolate, function_name, T) \ |
| 115 PREPARE_FOR_EXECUTION_GENERIC(context, function_name, MaybeLocal<T>(), \ | 122 PREPARE_FOR_EXECUTION_GENERIC(isolate, Local<Context>(), function_name, \ |
| 116 InternalEscapableScope, false) | 123 MaybeLocal<T>(), InternalEscapableScope, \ |
| 124 false); |
| 117 | 125 |
| 118 | 126 |
| 119 #define PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, function_name, T) \ | 127 #define PREPARE_FOR_EXECUTION(context, function_name, T) \ |
| 120 PREPARE_FOR_EXECUTION_GENERIC(context, function_name, MaybeLocal<T>(), \ | 128 PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, function_name, MaybeLocal<T>(), \ |
| 121 InternalEscapableScope, true) | 129 InternalEscapableScope, false) |
| 122 | 130 |
| 123 | 131 |
| 124 #define PREPARE_FOR_EXECUTION_PRIMITIVE(context, function_name, T) \ | 132 #define PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, function_name, T) \ |
| 125 PREPARE_FOR_EXECUTION_GENERIC(context, function_name, Nothing<T>(), \ | 133 PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, function_name, MaybeLocal<T>(), \ |
| 126 i::HandleScope, false) | 134 InternalEscapableScope, true) |
| 135 |
| 136 |
| 137 #define PREPARE_FOR_EXECUTION_PRIMITIVE(context, function_name, T) \ |
| 138 PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, function_name, Nothing<T>(), \ |
| 139 i::HandleScope, false) |
| 127 | 140 |
| 128 | 141 |
| 129 #define EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, value) \ | 142 #define EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, value) \ |
| 130 do { \ | 143 do { \ |
| 131 if (has_pending_exception) { \ | 144 if (has_pending_exception) { \ |
| 132 call_depth_scope.Escape(); \ | 145 call_depth_scope.Escape(); \ |
| 133 return value; \ | 146 return value; \ |
| 134 } \ | 147 } \ |
| 135 } while (false) | 148 } while (false) |
| 136 | 149 |
| (...skipping 1438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1575 } | 1588 } |
| 1576 | 1589 |
| 1577 | 1590 |
| 1578 Local<UnboundScript> Script::GetUnboundScript() { | 1591 Local<UnboundScript> Script::GetUnboundScript() { |
| 1579 i::Handle<i::Object> obj = Utils::OpenHandle(this); | 1592 i::Handle<i::Object> obj = Utils::OpenHandle(this); |
| 1580 return ToApiHandle<UnboundScript>( | 1593 return ToApiHandle<UnboundScript>( |
| 1581 i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared())); | 1594 i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared())); |
| 1582 } | 1595 } |
| 1583 | 1596 |
| 1584 | 1597 |
| 1585 Local<UnboundScript> ScriptCompiler::CompileUnboundInternal( | 1598 MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal( |
| 1586 Isolate* v8_isolate, Source* source, CompileOptions options, | 1599 Isolate* v8_isolate, Source* source, CompileOptions options, |
| 1587 bool is_module) { | 1600 bool is_module) { |
| 1588 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); | 1601 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); |
| 1589 ON_BAILOUT(isolate, "v8::ScriptCompiler::CompileUnbound()", | 1602 PREPARE_FOR_EXECUTION_WITH_ISOLATE( |
| 1590 return Local<UnboundScript>()); | 1603 isolate, "v8::ScriptCompiler::CompileUnbound()", UnboundScript); |
| 1591 | 1604 |
| 1592 // Support the old API for a transition period: | 1605 // Support the old API for a transition period: |
| 1593 // - kProduceToCache -> kProduceParserCache | 1606 // - kProduceToCache -> kProduceParserCache |
| 1594 // - kNoCompileOptions + cached_data != NULL -> kConsumeParserCache | 1607 // - kNoCompileOptions + cached_data != NULL -> kConsumeParserCache |
| 1595 if (options == kProduceDataToCache) { | 1608 if (options == kProduceDataToCache) { |
| 1596 options = kProduceParserCache; | 1609 options = kProduceParserCache; |
| 1597 } else if (options == kNoCompileOptions && source->cached_data) { | 1610 } else if (options == kNoCompileOptions && source->cached_data) { |
| 1598 options = kConsumeParserCache; | 1611 options = kConsumeParserCache; |
| 1599 } | 1612 } |
| 1600 | 1613 |
| 1601 // Don't try to produce any kind of cache when the debugger is loaded. | 1614 // Don't try to produce any kind of cache when the debugger is loaded. |
| 1602 if (isolate->debug()->is_loaded() && | 1615 if (isolate->debug()->is_loaded() && |
| 1603 (options == kProduceParserCache || options == kProduceCodeCache)) { | 1616 (options == kProduceParserCache || options == kProduceCodeCache)) { |
| 1604 options = kNoCompileOptions; | 1617 options = kNoCompileOptions; |
| 1605 } | 1618 } |
| 1606 | 1619 |
| 1607 i::ScriptData* script_data = NULL; | 1620 i::ScriptData* script_data = NULL; |
| 1608 if (options == kConsumeParserCache || options == kConsumeCodeCache) { | 1621 if (options == kConsumeParserCache || options == kConsumeCodeCache) { |
| 1609 DCHECK(source->cached_data); | 1622 DCHECK(source->cached_data); |
| 1610 // ScriptData takes care of pointer-aligning the data. | 1623 // ScriptData takes care of pointer-aligning the data. |
| 1611 script_data = new i::ScriptData(source->cached_data->data, | 1624 script_data = new i::ScriptData(source->cached_data->data, |
| 1612 source->cached_data->length); | 1625 source->cached_data->length); |
| 1613 } | 1626 } |
| 1614 | 1627 |
| 1615 i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string)); | 1628 i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string)); |
| 1616 LOG_API(isolate, "ScriptCompiler::CompileUnbound"); | |
| 1617 ENTER_V8(isolate); | |
| 1618 i::SharedFunctionInfo* raw_result = NULL; | 1629 i::SharedFunctionInfo* raw_result = NULL; |
| 1619 { i::HandleScope scope(isolate); | 1630 { i::HandleScope scope(isolate); |
| 1620 i::HistogramTimerScope total(isolate->counters()->compile_script(), true); | 1631 i::HistogramTimerScope total(isolate->counters()->compile_script(), true); |
| 1621 i::Handle<i::Object> name_obj; | 1632 i::Handle<i::Object> name_obj; |
| 1622 int line_offset = 0; | 1633 int line_offset = 0; |
| 1623 int column_offset = 0; | 1634 int column_offset = 0; |
| 1624 bool is_embedder_debug_script = false; | 1635 bool is_embedder_debug_script = false; |
| 1625 bool is_shared_cross_origin = false; | 1636 bool is_shared_cross_origin = false; |
| 1626 if (!source->resource_name.IsEmpty()) { | 1637 if (!source->resource_name.IsEmpty()) { |
| 1627 name_obj = Utils::OpenHandle(*(source->resource_name)); | 1638 name_obj = Utils::OpenHandle(*(source->resource_name)); |
| 1628 } | 1639 } |
| 1629 if (!source->resource_line_offset.IsEmpty()) { | 1640 if (!source->resource_line_offset.IsEmpty()) { |
| 1630 line_offset = static_cast<int>(source->resource_line_offset->Value()); | 1641 line_offset = static_cast<int>(source->resource_line_offset->Value()); |
| 1631 } | 1642 } |
| 1632 if (!source->resource_column_offset.IsEmpty()) { | 1643 if (!source->resource_column_offset.IsEmpty()) { |
| 1633 column_offset = | 1644 column_offset = |
| 1634 static_cast<int>(source->resource_column_offset->Value()); | 1645 static_cast<int>(source->resource_column_offset->Value()); |
| 1635 } | 1646 } |
| 1636 if (!source->resource_is_shared_cross_origin.IsEmpty()) { | 1647 if (!source->resource_is_shared_cross_origin.IsEmpty()) { |
| 1637 is_shared_cross_origin = | 1648 is_shared_cross_origin = |
| 1638 source->resource_is_shared_cross_origin->IsTrue(); | 1649 source->resource_is_shared_cross_origin->IsTrue(); |
| 1639 } | 1650 } |
| 1640 if (!source->resource_is_embedder_debug_script.IsEmpty()) { | 1651 if (!source->resource_is_embedder_debug_script.IsEmpty()) { |
| 1641 is_embedder_debug_script = | 1652 is_embedder_debug_script = |
| 1642 source->resource_is_embedder_debug_script->IsTrue(); | 1653 source->resource_is_embedder_debug_script->IsTrue(); |
| 1643 } | 1654 } |
| 1644 EXCEPTION_PREAMBLE(isolate); | |
| 1645 i::Handle<i::SharedFunctionInfo> result = i::Compiler::CompileScript( | 1655 i::Handle<i::SharedFunctionInfo> result = i::Compiler::CompileScript( |
| 1646 str, name_obj, line_offset, column_offset, is_embedder_debug_script, | 1656 str, name_obj, line_offset, column_offset, is_embedder_debug_script, |
| 1647 is_shared_cross_origin, isolate->native_context(), NULL, &script_data, | 1657 is_shared_cross_origin, isolate->native_context(), NULL, &script_data, |
| 1648 options, i::NOT_NATIVES_CODE, is_module); | 1658 options, i::NOT_NATIVES_CODE, is_module); |
| 1649 has_pending_exception = result.is_null(); | 1659 has_pending_exception = result.is_null(); |
| 1650 if (has_pending_exception && script_data != NULL) { | 1660 if (has_pending_exception && script_data != NULL) { |
| 1651 // This case won't happen during normal operation; we have compiled | 1661 // This case won't happen during normal operation; we have compiled |
| 1652 // successfully and produced cached data, and but the second compilation | 1662 // successfully and produced cached data, and but the second compilation |
| 1653 // of the same source code fails. | 1663 // of the same source code fails. |
| 1654 delete script_data; | 1664 delete script_data; |
| 1655 script_data = NULL; | 1665 script_data = NULL; |
| 1656 } | 1666 } |
| 1657 EXCEPTION_BAILOUT_CHECK(isolate, Local<UnboundScript>()); | 1667 RETURN_ON_FAILED_EXECUTION(UnboundScript); |
| 1658 raw_result = *result; | 1668 raw_result = *result; |
| 1659 | 1669 |
| 1660 if ((options == kProduceParserCache || options == kProduceCodeCache) && | 1670 if ((options == kProduceParserCache || options == kProduceCodeCache) && |
| 1661 script_data != NULL) { | 1671 script_data != NULL) { |
| 1662 // script_data now contains the data that was generated. source will | 1672 // script_data now contains the data that was generated. source will |
| 1663 // take the ownership. | 1673 // take the ownership. |
| 1664 source->cached_data = new CachedData( | 1674 source->cached_data = new CachedData( |
| 1665 script_data->data(), script_data->length(), CachedData::BufferOwned); | 1675 script_data->data(), script_data->length(), CachedData::BufferOwned); |
| 1666 script_data->ReleaseDataOwnership(); | 1676 script_data->ReleaseDataOwnership(); |
| 1667 } else if (options == kConsumeParserCache || options == kConsumeCodeCache) { | 1677 } else if (options == kConsumeParserCache || options == kConsumeCodeCache) { |
| 1668 source->cached_data->rejected = script_data->rejected(); | 1678 source->cached_data->rejected = script_data->rejected(); |
| 1669 } | 1679 } |
| 1670 delete script_data; | 1680 delete script_data; |
| 1671 } | 1681 } |
| 1672 i::Handle<i::SharedFunctionInfo> result(raw_result, isolate); | 1682 i::Handle<i::SharedFunctionInfo> result(raw_result, isolate); |
| 1673 return ToApiHandle<UnboundScript>(result); | 1683 RETURN_ESCAPED(ToApiHandle<UnboundScript>(result)); |
| 1684 } |
| 1685 |
| 1686 |
| 1687 MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundScript( |
| 1688 Isolate* v8_isolate, Source* source, CompileOptions options) { |
| 1689 return CompileUnboundInternal(v8_isolate, source, options, false); |
| 1674 } | 1690 } |
| 1675 | 1691 |
| 1676 | 1692 |
| 1677 Local<UnboundScript> ScriptCompiler::CompileUnbound(Isolate* v8_isolate, | 1693 Local<UnboundScript> ScriptCompiler::CompileUnbound(Isolate* v8_isolate, |
| 1678 Source* source, | 1694 Source* source, |
| 1679 CompileOptions options) { | 1695 CompileOptions options) { |
| 1680 return CompileUnboundInternal(v8_isolate, source, options, false); | 1696 RETURN_TO_LOCAL_UNCHECKED( |
| 1697 CompileUnboundInternal(v8_isolate, source, options, false), |
| 1698 UnboundScript); |
| 1681 } | 1699 } |
| 1682 | 1700 |
| 1683 | 1701 |
| 1702 MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context, |
| 1703 Source* source, |
| 1704 CompileOptions options) { |
| 1705 auto isolate = context->GetIsolate(); |
| 1706 auto maybe = CompileUnboundInternal(isolate, source, options, false); |
| 1707 Local<UnboundScript> result; |
| 1708 if (!maybe.ToLocal(&result)) return MaybeLocal<Script>(); |
| 1709 v8::Context::Scope scope(context); |
| 1710 return result->BindToCurrentContext(); |
| 1711 } |
| 1712 |
| 1713 |
| 1684 Local<Script> ScriptCompiler::Compile( | 1714 Local<Script> ScriptCompiler::Compile( |
| 1685 Isolate* v8_isolate, | 1715 Isolate* v8_isolate, |
| 1686 Source* source, | 1716 Source* source, |
| 1687 CompileOptions options) { | 1717 CompileOptions options) { |
| 1688 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); | 1718 auto context = v8_isolate->GetCurrentContext(); |
| 1689 ON_BAILOUT(isolate, "v8::ScriptCompiler::Compile()", return Local<Script>()); | 1719 RETURN_TO_LOCAL_UNCHECKED(Compile(context, source, options), Script); |
| 1690 LOG_API(isolate, "ScriptCompiler::CompileBound()"); | 1720 } |
| 1691 ENTER_V8(isolate); | 1721 |
| 1692 Local<UnboundScript> generic = CompileUnbound(v8_isolate, source, options); | 1722 |
| 1693 if (generic.IsEmpty()) return Local<Script>(); | 1723 MaybeLocal<Script> ScriptCompiler::CompileModule(Local<Context> context, |
| 1724 Source* source, |
| 1725 CompileOptions options) { |
| 1726 CHECK(i::FLAG_harmony_modules); |
| 1727 auto isolate = context->GetIsolate(); |
| 1728 auto maybe = CompileUnboundInternal(isolate, source, options, true); |
| 1729 Local<UnboundScript> generic; |
| 1730 if (!maybe.ToLocal(&generic)) return MaybeLocal<Script>(); |
| 1731 v8::Context::Scope scope(context); |
| 1694 return generic->BindToCurrentContext(); | 1732 return generic->BindToCurrentContext(); |
| 1695 } | 1733 } |
| 1696 | 1734 |
| 1697 | 1735 |
| 1698 Local<Script> ScriptCompiler::CompileModule(Isolate* v8_isolate, Source* source, | 1736 Local<Script> ScriptCompiler::CompileModule(Isolate* v8_isolate, Source* source, |
| 1699 CompileOptions options) { | 1737 CompileOptions options) { |
| 1700 CHECK(i::FLAG_harmony_modules); | 1738 auto context = v8_isolate->GetCurrentContext(); |
| 1701 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); | 1739 RETURN_TO_LOCAL_UNCHECKED(CompileModule(context, source, options), Script); |
| 1702 ON_BAILOUT(isolate, "v8::ScriptCompiler::CompileModule()", | |
| 1703 return Local<Script>()); | |
| 1704 LOG_API(isolate, "ScriptCompiler::CompileModule()"); | |
| 1705 ENTER_V8(isolate); | |
| 1706 Local<UnboundScript> generic = | |
| 1707 CompileUnboundInternal(v8_isolate, source, options, true); | |
| 1708 if (generic.IsEmpty()) return Local<Script>(); | |
| 1709 return generic->BindToCurrentContext(); | |
| 1710 } | 1740 } |
| 1711 | 1741 |
| 1712 | 1742 |
| 1713 class IsIdentifierHelper { | 1743 class IsIdentifierHelper { |
| 1714 public: | 1744 public: |
| 1715 IsIdentifierHelper() : is_identifier_(false), first_char_(true) {} | 1745 IsIdentifierHelper() : is_identifier_(false), first_char_(true) {} |
| 1716 | 1746 |
| 1717 bool Check(i::String* string) { | 1747 bool Check(i::String* string) { |
| 1718 i::ConsString* cons_string = i::String::VisitFlat(this, string, 0); | 1748 i::ConsString* cons_string = i::String::VisitFlat(this, string, 0); |
| 1719 if (cons_string == NULL) return is_identifier_; | 1749 if (cons_string == NULL) return is_identifier_; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1742 } | 1772 } |
| 1743 | 1773 |
| 1744 private: | 1774 private: |
| 1745 bool is_identifier_; | 1775 bool is_identifier_; |
| 1746 bool first_char_; | 1776 bool first_char_; |
| 1747 i::UnicodeCache unicode_cache_; | 1777 i::UnicodeCache unicode_cache_; |
| 1748 DISALLOW_COPY_AND_ASSIGN(IsIdentifierHelper); | 1778 DISALLOW_COPY_AND_ASSIGN(IsIdentifierHelper); |
| 1749 }; | 1779 }; |
| 1750 | 1780 |
| 1751 | 1781 |
| 1752 Local<Function> ScriptCompiler::CompileFunctionInContext( | 1782 MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext( |
| 1753 Isolate* v8_isolate, Source* source, Local<Context> v8_context, | 1783 Local<Context> v8_context, Source* source, size_t arguments_count, |
| 1754 size_t arguments_count, Local<String> arguments[], | 1784 Local<String> arguments[], size_t context_extension_count, |
| 1755 size_t context_extension_count, Local<Object> context_extensions[]) { | 1785 Local<Object> context_extensions[]) { |
| 1756 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); | 1786 PREPARE_FOR_EXECUTION( |
| 1757 ON_BAILOUT(isolate, "v8::ScriptCompiler::CompileFunctionInContext()", | 1787 v8_context, "v8::ScriptCompiler::CompileFunctionInContext()", Function); |
| 1758 return Local<Function>()); | |
| 1759 LOG_API(isolate, "ScriptCompiler::CompileFunctionInContext()"); | |
| 1760 ENTER_V8(isolate); | |
| 1761 | |
| 1762 i::Handle<i::String> source_string; | 1788 i::Handle<i::String> source_string; |
| 1789 auto factory = isolate->factory(); |
| 1763 if (arguments_count) { | 1790 if (arguments_count) { |
| 1764 source_string = | 1791 source_string = factory->NewStringFromStaticChars("(function("); |
| 1765 Utils::OpenHandle(*v8::String::NewFromUtf8(v8_isolate, "(function(")); | |
| 1766 for (size_t i = 0; i < arguments_count; ++i) { | 1792 for (size_t i = 0; i < arguments_count; ++i) { |
| 1767 IsIdentifierHelper helper; | 1793 IsIdentifierHelper helper; |
| 1768 if (!helper.Check(*Utils::OpenHandle(*arguments[i]))) { | 1794 if (!helper.Check(*Utils::OpenHandle(*arguments[i]))) { |
| 1769 return Local<Function>(); | 1795 return Local<Function>(); |
| 1770 } | 1796 } |
| 1771 i::MaybeHandle<i::String> maybe_source = | 1797 has_pending_exception = |
| 1772 isolate->factory()->NewConsString(source_string, | 1798 !factory->NewConsString(source_string, |
| 1773 Utils::OpenHandle(*arguments[i])); | 1799 Utils::OpenHandle(*arguments[i])) |
| 1774 if (!maybe_source.ToHandle(&source_string)) { | 1800 .ToHandle(&source_string); |
| 1775 return Local<Function>(); | 1801 RETURN_ON_FAILED_EXECUTION(Function); |
| 1776 } | |
| 1777 if (i + 1 == arguments_count) continue; | 1802 if (i + 1 == arguments_count) continue; |
| 1778 maybe_source = isolate->factory()->NewConsString( | 1803 has_pending_exception = |
| 1779 source_string, | 1804 !factory->NewConsString(source_string, |
| 1780 isolate->factory()->LookupSingleCharacterStringFromCode(',')); | 1805 factory->LookupSingleCharacterStringFromCode( |
| 1781 if (!maybe_source.ToHandle(&source_string)) { | 1806 ',')).ToHandle(&source_string); |
| 1782 return Local<Function>(); | 1807 RETURN_ON_FAILED_EXECUTION(Function); |
| 1783 } | |
| 1784 } | 1808 } |
| 1785 i::Handle<i::String> brackets = | 1809 auto brackets = factory->NewStringFromStaticChars("){"); |
| 1786 Utils::OpenHandle(*v8::String::NewFromUtf8(v8_isolate, "){")); | 1810 has_pending_exception = !factory->NewConsString(source_string, brackets) |
| 1787 i::MaybeHandle<i::String> maybe_source = | 1811 .ToHandle(&source_string); |
| 1788 isolate->factory()->NewConsString(source_string, brackets); | 1812 RETURN_ON_FAILED_EXECUTION(Function); |
| 1789 if (!maybe_source.ToHandle(&source_string)) { | |
| 1790 return Local<Function>(); | |
| 1791 } | |
| 1792 } else { | 1813 } else { |
| 1793 source_string = | 1814 source_string = factory->NewStringFromStaticChars("(function(){"); |
| 1794 Utils::OpenHandle(*v8::String::NewFromUtf8(v8_isolate, "(function(){")); | |
| 1795 } | 1815 } |
| 1796 | 1816 |
| 1797 int scope_position = source_string->length(); | 1817 int scope_position = source_string->length(); |
| 1798 i::MaybeHandle<i::String> maybe_source = isolate->factory()->NewConsString( | 1818 has_pending_exception = |
| 1799 source_string, Utils::OpenHandle(*source->source_string)); | 1819 !factory->NewConsString(source_string, |
| 1800 if (!maybe_source.ToHandle(&source_string)) { | 1820 Utils::OpenHandle(*source->source_string)) |
| 1801 return Local<Function>(); | 1821 .ToHandle(&source_string); |
| 1802 } | 1822 RETURN_ON_FAILED_EXECUTION(Function); |
| 1803 // Include \n in case the source contains a line end comment. | 1823 // Include \n in case the source contains a line end comment. |
| 1804 i::Handle<i::String> brackets = | 1824 auto brackets = factory->NewStringFromStaticChars("\n})"); |
| 1805 Utils::OpenHandle(*v8::String::NewFromUtf8(v8_isolate, "\n})")); | 1825 has_pending_exception = |
| 1806 maybe_source = isolate->factory()->NewConsString(source_string, brackets); | 1826 !factory->NewConsString(source_string, brackets).ToHandle(&source_string); |
| 1807 if (!maybe_source.ToHandle(&source_string)) { | 1827 RETURN_ON_FAILED_EXECUTION(Function); |
| 1808 return Local<Function>(); | |
| 1809 } | |
| 1810 | 1828 |
| 1811 i::Handle<i::Context> context = Utils::OpenHandle(*v8_context); | 1829 i::Handle<i::Context> context = Utils::OpenHandle(*v8_context); |
| 1812 i::Handle<i::SharedFunctionInfo> outer_info(context->closure()->shared(), | 1830 i::Handle<i::SharedFunctionInfo> outer_info(context->closure()->shared(), |
| 1813 isolate); | 1831 isolate); |
| 1814 for (size_t i = 0; i < context_extension_count; ++i) { | 1832 for (size_t i = 0; i < context_extension_count; ++i) { |
| 1815 i::Handle<i::JSObject> extension = | 1833 i::Handle<i::JSObject> extension = |
| 1816 Utils::OpenHandle(*context_extensions[i]); | 1834 Utils::OpenHandle(*context_extensions[i]); |
| 1817 i::Handle<i::JSFunction> closure(context->closure(), isolate); | 1835 i::Handle<i::JSFunction> closure(context->closure(), isolate); |
| 1818 context = isolate->factory()->NewWithContext(closure, context, extension); | 1836 context = factory->NewWithContext(closure, context, extension); |
| 1819 } | 1837 } |
| 1820 | 1838 |
| 1821 EXCEPTION_PREAMBLE(isolate); | |
| 1822 i::MaybeHandle<i::JSFunction> maybe_fun = i::Compiler::GetFunctionFromEval( | |
| 1823 source_string, outer_info, context, i::SLOPPY, | |
| 1824 i::ONLY_SINGLE_FUNCTION_LITERAL, scope_position); | |
| 1825 i::Handle<i::JSFunction> fun; | 1839 i::Handle<i::JSFunction> fun; |
| 1826 has_pending_exception = !maybe_fun.ToHandle(&fun); | 1840 has_pending_exception = |
| 1827 EXCEPTION_BAILOUT_CHECK(isolate, Local<Function>()); | 1841 !i::Compiler::GetFunctionFromEval( |
| 1842 source_string, outer_info, context, i::SLOPPY, |
| 1843 i::ONLY_SINGLE_FUNCTION_LITERAL, scope_position).ToHandle(&fun); |
| 1844 RETURN_ON_FAILED_EXECUTION(Function); |
| 1828 | 1845 |
| 1829 i::MaybeHandle<i::Object> result = i::Execution::Call( | 1846 i::Handle<i::Object> result; |
| 1830 isolate, fun, Utils::OpenHandle(*v8_context->Global()), 0, NULL); | 1847 has_pending_exception = |
| 1831 i::Handle<i::Object> final_result; | 1848 !i::Execution::Call(isolate, fun, |
| 1832 has_pending_exception = !result.ToHandle(&final_result); | 1849 Utils::OpenHandle(*v8_context->Global()), 0, |
| 1833 EXCEPTION_BAILOUT_CHECK(isolate, Local<Function>()); | 1850 nullptr).ToHandle(&result); |
| 1834 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(final_result)); | 1851 RETURN_ON_FAILED_EXECUTION(Function); |
| 1852 RETURN_ESCAPED(Utils::ToLocal(i::Handle<i::JSFunction>::cast(result))); |
| 1835 } | 1853 } |
| 1836 | 1854 |
| 1837 | 1855 |
| 1856 Local<Function> ScriptCompiler::CompileFunctionInContext( |
| 1857 Isolate* v8_isolate, Source* source, Local<Context> v8_context, |
| 1858 size_t arguments_count, Local<String> arguments[], |
| 1859 size_t context_extension_count, Local<Object> context_extensions[]) { |
| 1860 RETURN_TO_LOCAL_UNCHECKED( |
| 1861 CompileFunctionInContext(v8_context, source, arguments_count, arguments, |
| 1862 context_extension_count, context_extensions), |
| 1863 Function); |
| 1864 } |
| 1865 |
| 1866 |
| 1838 ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript( | 1867 ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript( |
| 1839 Isolate* v8_isolate, StreamedSource* source, CompileOptions options) { | 1868 Isolate* v8_isolate, StreamedSource* source, CompileOptions options) { |
| 1840 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); | 1869 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); |
| 1841 return new i::BackgroundParsingTask(source->impl(), options, | 1870 return new i::BackgroundParsingTask(source->impl(), options, |
| 1842 i::FLAG_stack_size, isolate); | 1871 i::FLAG_stack_size, isolate); |
| 1843 } | 1872 } |
| 1844 | 1873 |
| 1845 | 1874 |
| 1846 Local<Script> ScriptCompiler::Compile(Isolate* v8_isolate, | 1875 MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context, |
| 1847 StreamedSource* v8_source, | 1876 StreamedSource* v8_source, |
| 1848 Handle<String> full_source_string, | 1877 Handle<String> full_source_string, |
| 1849 const ScriptOrigin& origin) { | 1878 const ScriptOrigin& origin) { |
| 1850 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); | 1879 PREPARE_FOR_EXECUTION(context, "v8::ScriptCompiler::Compile()", Script); |
| 1851 i::StreamedSource* source = v8_source->impl(); | 1880 i::StreamedSource* source = v8_source->impl(); |
| 1852 ON_BAILOUT(isolate, "v8::ScriptCompiler::Compile()", return Local<Script>()); | 1881 i::SharedFunctionInfo* raw_result = nullptr; |
| 1853 LOG_API(isolate, "ScriptCompiler::Compile()"); | |
| 1854 ENTER_V8(isolate); | |
| 1855 i::SharedFunctionInfo* raw_result = NULL; | |
| 1856 | |
| 1857 { | 1882 { |
| 1858 i::HandleScope scope(isolate); | 1883 i::HandleScope scope(isolate); |
| 1859 i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string)); | 1884 i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string)); |
| 1860 i::Handle<i::Script> script = isolate->factory()->NewScript(str); | 1885 i::Handle<i::Script> script = isolate->factory()->NewScript(str); |
| 1861 if (!origin.ResourceName().IsEmpty()) { | 1886 if (!origin.ResourceName().IsEmpty()) { |
| 1862 script->set_name(*Utils::OpenHandle(*(origin.ResourceName()))); | 1887 script->set_name(*Utils::OpenHandle(*(origin.ResourceName()))); |
| 1863 } | 1888 } |
| 1864 if (!origin.ResourceLineOffset().IsEmpty()) { | 1889 if (!origin.ResourceLineOffset().IsEmpty()) { |
| 1865 script->set_line_offset(i::Smi::FromInt( | 1890 script->set_line_offset(i::Smi::FromInt( |
| 1866 static_cast<int>(origin.ResourceLineOffset()->Value()))); | 1891 static_cast<int>(origin.ResourceLineOffset()->Value()))); |
| 1867 } | 1892 } |
| 1868 if (!origin.ResourceColumnOffset().IsEmpty()) { | 1893 if (!origin.ResourceColumnOffset().IsEmpty()) { |
| 1869 script->set_column_offset(i::Smi::FromInt( | 1894 script->set_column_offset(i::Smi::FromInt( |
| 1870 static_cast<int>(origin.ResourceColumnOffset()->Value()))); | 1895 static_cast<int>(origin.ResourceColumnOffset()->Value()))); |
| 1871 } | 1896 } |
| 1872 if (!origin.ResourceIsSharedCrossOrigin().IsEmpty()) { | 1897 if (!origin.ResourceIsSharedCrossOrigin().IsEmpty()) { |
| 1873 script->set_is_shared_cross_origin( | 1898 script->set_is_shared_cross_origin( |
| 1874 origin.ResourceIsSharedCrossOrigin()->IsTrue()); | 1899 origin.ResourceIsSharedCrossOrigin()->IsTrue()); |
| 1875 } | 1900 } |
| 1876 if (!origin.ResourceIsEmbedderDebugScript().IsEmpty()) { | 1901 if (!origin.ResourceIsEmbedderDebugScript().IsEmpty()) { |
| 1877 script->set_is_embedder_debug_script( | 1902 script->set_is_embedder_debug_script( |
| 1878 origin.ResourceIsEmbedderDebugScript()->IsTrue()); | 1903 origin.ResourceIsEmbedderDebugScript()->IsTrue()); |
| 1879 } | 1904 } |
| 1880 source->info->set_script(script); | 1905 source->info->set_script(script); |
| 1881 source->info->SetContext(isolate->native_context()); | 1906 source->info->SetContext(isolate->native_context()); |
| 1882 | 1907 |
| 1883 EXCEPTION_PREAMBLE(isolate); | |
| 1884 | |
| 1885 // Do the parsing tasks which need to be done on the main thread. This will | 1908 // Do the parsing tasks which need to be done on the main thread. This will |
| 1886 // also handle parse errors. | 1909 // also handle parse errors. |
| 1887 source->parser->Internalize(isolate, script, | 1910 source->parser->Internalize(isolate, script, |
| 1888 source->info->function() == NULL); | 1911 source->info->function() == nullptr); |
| 1889 source->parser->HandleSourceURLComments(isolate, script); | 1912 source->parser->HandleSourceURLComments(isolate, script); |
| 1890 | 1913 |
| 1891 i::Handle<i::SharedFunctionInfo> result = | 1914 i::Handle<i::SharedFunctionInfo> result; |
| 1892 i::Handle<i::SharedFunctionInfo>::null(); | 1915 if (source->info->function() != nullptr) { |
| 1893 if (source->info->function() != NULL) { | |
| 1894 // Parsing has succeeded. | 1916 // Parsing has succeeded. |
| 1895 result = | 1917 result = |
| 1896 i::Compiler::CompileStreamedScript(source->info.get(), str->length()); | 1918 i::Compiler::CompileStreamedScript(source->info.get(), str->length()); |
| 1897 } | 1919 } |
| 1898 has_pending_exception = result.is_null(); | 1920 has_pending_exception = result.is_null(); |
| 1899 if (has_pending_exception) isolate->ReportPendingMessages(); | 1921 if (has_pending_exception) isolate->ReportPendingMessages(); |
| 1900 EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>()); | 1922 RETURN_ON_FAILED_EXECUTION(Script); |
| 1901 | 1923 |
| 1902 raw_result = *result; | 1924 raw_result = *result; |
| 1903 // The Handle<Script> will go out of scope soon; make sure CompilationInfo | 1925 // The Handle<Script> will go out of scope soon; make sure CompilationInfo |
| 1904 // doesn't point to it. | 1926 // doesn't point to it. |
| 1905 source->info->set_script(i::Handle<i::Script>()); | 1927 source->info->set_script(i::Handle<i::Script>()); |
| 1906 } // HandleScope goes out of scope. | 1928 } // HandleScope goes out of scope. |
| 1907 i::Handle<i::SharedFunctionInfo> result(raw_result, isolate); | 1929 i::Handle<i::SharedFunctionInfo> result(raw_result, isolate); |
| 1908 Local<UnboundScript> generic = ToApiHandle<UnboundScript>(result); | 1930 Local<UnboundScript> generic = ToApiHandle<UnboundScript>(result); |
| 1909 if (generic.IsEmpty()) { | 1931 if (generic.IsEmpty()) return Local<Script>(); |
| 1910 return Local<Script>(); | 1932 RETURN_ESCAPED(generic->BindToCurrentContext()); |
| 1911 } | |
| 1912 return generic->BindToCurrentContext(); | |
| 1913 } | 1933 } |
| 1914 | 1934 |
| 1915 | 1935 |
| 1936 Local<Script> ScriptCompiler::Compile(Isolate* v8_isolate, |
| 1937 StreamedSource* v8_source, |
| 1938 Handle<String> full_source_string, |
| 1939 const ScriptOrigin& origin) { |
| 1940 auto context = v8_isolate->GetCurrentContext(); |
| 1941 RETURN_TO_LOCAL_UNCHECKED( |
| 1942 Compile(context, v8_source, full_source_string, origin), Script); |
| 1943 } |
| 1944 |
| 1945 |
| 1916 uint32_t ScriptCompiler::CachedDataVersionTag() { | 1946 uint32_t ScriptCompiler::CachedDataVersionTag() { |
| 1917 return static_cast<uint32_t>(base::hash_combine( | 1947 return static_cast<uint32_t>(base::hash_combine( |
| 1918 internal::Version::Hash(), internal::FlagList::Hash(), | 1948 internal::Version::Hash(), internal::FlagList::Hash(), |
| 1919 static_cast<uint32_t>(internal::CpuFeatures::SupportedFeatures()))); | 1949 static_cast<uint32_t>(internal::CpuFeatures::SupportedFeatures()))); |
| 1920 } | 1950 } |
| 1921 | 1951 |
| 1922 | 1952 |
| 1953 MaybeLocal<Script> Script::Compile(Local<Context> context, |
| 1954 Handle<String> source, |
| 1955 ScriptOrigin* origin) { |
| 1956 if (origin) { |
| 1957 ScriptCompiler::Source script_source(source, *origin); |
| 1958 return ScriptCompiler::Compile(context, &script_source); |
| 1959 } |
| 1960 ScriptCompiler::Source script_source(source); |
| 1961 return ScriptCompiler::Compile(context, &script_source); |
| 1962 } |
| 1963 |
| 1964 |
| 1923 Local<Script> Script::Compile(v8::Handle<String> source, | 1965 Local<Script> Script::Compile(v8::Handle<String> source, |
| 1924 v8::ScriptOrigin* origin) { | 1966 v8::ScriptOrigin* origin) { |
| 1925 i::Handle<i::String> str = Utils::OpenHandle(*source); | 1967 auto str = Utils::OpenHandle(*source); |
| 1926 if (origin) { | 1968 auto context = ContextFromHeapObject(str); |
| 1927 ScriptCompiler::Source script_source(source, *origin); | 1969 RETURN_TO_LOCAL_UNCHECKED(Compile(context, source, origin), Script); |
| 1928 return ScriptCompiler::Compile( | |
| 1929 reinterpret_cast<v8::Isolate*>(str->GetIsolate()), | |
| 1930 &script_source); | |
| 1931 } | |
| 1932 ScriptCompiler::Source script_source(source); | |
| 1933 return ScriptCompiler::Compile( | |
| 1934 reinterpret_cast<v8::Isolate*>(str->GetIsolate()), | |
| 1935 &script_source); | |
| 1936 } | 1970 } |
| 1937 | 1971 |
| 1938 | 1972 |
| 1939 Local<Script> Script::Compile(v8::Handle<String> source, | 1973 Local<Script> Script::Compile(v8::Handle<String> source, |
| 1940 v8::Handle<String> file_name) { | 1974 v8::Handle<String> file_name) { |
| 1941 ScriptOrigin origin(file_name); | 1975 ScriptOrigin origin(file_name); |
| 1942 return Compile(source, &origin); | 1976 return Compile(source, &origin); |
| 1943 } | 1977 } |
| 1944 | 1978 |
| 1945 | 1979 |
| (...skipping 6038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7984 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); | 8018 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); |
| 7985 Address callback_address = | 8019 Address callback_address = |
| 7986 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); | 8020 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); |
| 7987 VMState<EXTERNAL> state(isolate); | 8021 VMState<EXTERNAL> state(isolate); |
| 7988 ExternalCallbackScope call_scope(isolate, callback_address); | 8022 ExternalCallbackScope call_scope(isolate, callback_address); |
| 7989 callback(info); | 8023 callback(info); |
| 7990 } | 8024 } |
| 7991 | 8025 |
| 7992 | 8026 |
| 7993 } } // namespace v8::internal | 8027 } } // namespace v8::internal |
| OLD | NEW |