| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 12976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12987 return isolate->factory()->NewSubString( | 12987 return isolate->factory()->NewSubString( |
| 12988 script_source, Handle<Smi>::cast(class_start_position)->value(), | 12988 script_source, Handle<Smi>::cast(class_start_position)->value(), |
| 12989 Handle<Smi>::cast(class_end_position)->value()); | 12989 Handle<Smi>::cast(class_end_position)->value()); |
| 12990 } | 12990 } |
| 12991 | 12991 |
| 12992 // Check if we have source code for the {function}. | 12992 // Check if we have source code for the {function}. |
| 12993 if (!shared_info->HasSourceCode()) { | 12993 if (!shared_info->HasSourceCode()) { |
| 12994 return NativeCodeFunctionSourceString(shared_info); | 12994 return NativeCodeFunctionSourceString(shared_info); |
| 12995 } | 12995 } |
| 12996 | 12996 |
| 12997 if (FLAG_harmony_function_tostring) { |
| 12998 return Handle<String>::cast(shared_info->GetSourceCodeHarmony()); |
| 12999 } |
| 13000 |
| 12997 IncrementalStringBuilder builder(isolate); | 13001 IncrementalStringBuilder builder(isolate); |
| 12998 FunctionKind kind = shared_info->kind(); | 13002 FunctionKind kind = shared_info->kind(); |
| 12999 if (!IsArrowFunction(kind)) { | 13003 if (!IsArrowFunction(kind)) { |
| 13000 if (IsConciseMethod(kind)) { | 13004 if (IsConciseMethod(kind)) { |
| 13001 if (IsGeneratorFunction(kind)) { | 13005 if (IsGeneratorFunction(kind)) { |
| 13002 builder.AppendCharacter('*'); | 13006 builder.AppendCharacter('*'); |
| 13003 } else if (IsAsyncFunction(kind)) { | 13007 } else if (IsAsyncFunction(kind)) { |
| 13004 builder.AppendCString("async "); | 13008 builder.AppendCString("async "); |
| 13005 } | 13009 } |
| 13006 } else { | 13010 } else { |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13457 } | 13461 } |
| 13458 | 13462 |
| 13459 | 13463 |
| 13460 Handle<Object> SharedFunctionInfo::GetSourceCode() { | 13464 Handle<Object> SharedFunctionInfo::GetSourceCode() { |
| 13461 if (!HasSourceCode()) return GetIsolate()->factory()->undefined_value(); | 13465 if (!HasSourceCode()) return GetIsolate()->factory()->undefined_value(); |
| 13462 Handle<String> source(String::cast(Script::cast(script())->source())); | 13466 Handle<String> source(String::cast(Script::cast(script())->source())); |
| 13463 return GetIsolate()->factory()->NewSubString( | 13467 return GetIsolate()->factory()->NewSubString( |
| 13464 source, start_position(), end_position()); | 13468 source, start_position(), end_position()); |
| 13465 } | 13469 } |
| 13466 | 13470 |
| 13471 Handle<Object> SharedFunctionInfo::GetSourceCodeHarmony() { |
| 13472 Isolate* isolate = GetIsolate(); |
| 13473 if (!HasSourceCode()) return isolate->factory()->undefined_value(); |
| 13474 Handle<String> script_source(String::cast(Script::cast(script())->source())); |
| 13475 int start_pos = function_token_position(); |
| 13476 if (start_pos == kNoSourcePosition) start_pos = start_position(); |
| 13477 return isolate->factory()->NewSubString(script_source, start_pos, |
| 13478 end_position()); |
| 13479 } |
| 13467 | 13480 |
| 13468 bool SharedFunctionInfo::IsInlineable() { | 13481 bool SharedFunctionInfo::IsInlineable() { |
| 13469 // Check that the function has a script associated with it. | 13482 // Check that the function has a script associated with it. |
| 13470 if (!script()->IsScript()) return false; | 13483 if (!script()->IsScript()) return false; |
| 13471 return !optimization_disabled(); | 13484 return !optimization_disabled(); |
| 13472 } | 13485 } |
| 13473 | 13486 |
| 13474 | 13487 |
| 13475 int SharedFunctionInfo::SourceSize() { | 13488 int SharedFunctionInfo::SourceSize() { |
| 13476 return end_position() - start_position(); | 13489 return end_position() - start_position(); |
| (...skipping 2453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15930 } else { | 15943 } else { |
| 15931 os << " (" << PrivateSymbolToName() << ")"; | 15944 os << " (" << PrivateSymbolToName() << ")"; |
| 15932 } | 15945 } |
| 15933 os << ">"; | 15946 os << ">"; |
| 15934 } | 15947 } |
| 15935 | 15948 |
| 15936 | 15949 |
| 15937 // StringSharedKeys are used as keys in the eval cache. | 15950 // StringSharedKeys are used as keys in the eval cache. |
| 15938 class StringSharedKey : public HashTableKey { | 15951 class StringSharedKey : public HashTableKey { |
| 15939 public: | 15952 public: |
| 15953 // This tuple unambiguously identifies calls to eval() or |
| 15954 // CreateDynamicFunction() (such as through the Function() constructor). |
| 15955 // * source is the string passed into eval(). For dynamic functions, this is |
| 15956 // the effective source for the function, some of which is implicitly |
| 15957 // generated. |
| 15958 // * shared is the shared function info for the function containing the call |
| 15959 // to eval(). for dynamic functions, shared is the native context closure. |
| 15960 // * When positive, position is the position in the source where eval is |
| 15961 // called. When negative, position is the negation of the position in the |
| 15962 // dynamic function's effective source where the ')' ends the parameters. |
| 15940 StringSharedKey(Handle<String> source, Handle<SharedFunctionInfo> shared, | 15963 StringSharedKey(Handle<String> source, Handle<SharedFunctionInfo> shared, |
| 15941 LanguageMode language_mode, int scope_position) | 15964 LanguageMode language_mode, int position) |
| 15942 : source_(source), | 15965 : source_(source), |
| 15943 shared_(shared), | 15966 shared_(shared), |
| 15944 language_mode_(language_mode), | 15967 language_mode_(language_mode), |
| 15945 scope_position_(scope_position) {} | 15968 position_(position) {} |
| 15946 | 15969 |
| 15947 bool IsMatch(Object* other) override { | 15970 bool IsMatch(Object* other) override { |
| 15948 DisallowHeapAllocation no_allocation; | 15971 DisallowHeapAllocation no_allocation; |
| 15949 if (!other->IsFixedArray()) { | 15972 if (!other->IsFixedArray()) { |
| 15950 if (!other->IsNumber()) return false; | 15973 if (!other->IsNumber()) return false; |
| 15951 uint32_t other_hash = static_cast<uint32_t>(other->Number()); | 15974 uint32_t other_hash = static_cast<uint32_t>(other->Number()); |
| 15952 return Hash() == other_hash; | 15975 return Hash() == other_hash; |
| 15953 } | 15976 } |
| 15954 FixedArray* other_array = FixedArray::cast(other); | 15977 FixedArray* other_array = FixedArray::cast(other); |
| 15955 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); | 15978 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); |
| 15956 if (shared != *shared_) return false; | 15979 if (shared != *shared_) return false; |
| 15957 int language_unchecked = Smi::cast(other_array->get(2))->value(); | 15980 int language_unchecked = Smi::cast(other_array->get(2))->value(); |
| 15958 DCHECK(is_valid_language_mode(language_unchecked)); | 15981 DCHECK(is_valid_language_mode(language_unchecked)); |
| 15959 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked); | 15982 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked); |
| 15960 if (language_mode != language_mode_) return false; | 15983 if (language_mode != language_mode_) return false; |
| 15961 int scope_position = Smi::cast(other_array->get(3))->value(); | 15984 int position = Smi::cast(other_array->get(3))->value(); |
| 15962 if (scope_position != scope_position_) return false; | 15985 if (position != position_) return false; |
| 15963 String* source = String::cast(other_array->get(1)); | 15986 String* source = String::cast(other_array->get(1)); |
| 15964 return source->Equals(*source_); | 15987 return source->Equals(*source_); |
| 15965 } | 15988 } |
| 15966 | 15989 |
| 15967 static uint32_t StringSharedHashHelper(String* source, | 15990 static uint32_t StringSharedHashHelper(String* source, |
| 15968 SharedFunctionInfo* shared, | 15991 SharedFunctionInfo* shared, |
| 15969 LanguageMode language_mode, | 15992 LanguageMode language_mode, |
| 15970 int scope_position) { | 15993 int position) { |
| 15971 uint32_t hash = source->Hash(); | 15994 uint32_t hash = source->Hash(); |
| 15972 if (shared->HasSourceCode()) { | 15995 if (shared->HasSourceCode()) { |
| 15973 // Instead of using the SharedFunctionInfo pointer in the hash | 15996 // Instead of using the SharedFunctionInfo pointer in the hash |
| 15974 // code computation, we use a combination of the hash of the | 15997 // code computation, we use a combination of the hash of the |
| 15975 // script source code and the start position of the calling scope. | 15998 // script source code and the start position of the calling scope. |
| 15976 // We do this to ensure that the cache entries can survive garbage | 15999 // We do this to ensure that the cache entries can survive garbage |
| 15977 // collection. | 16000 // collection. |
| 15978 Script* script(Script::cast(shared->script())); | 16001 Script* script(Script::cast(shared->script())); |
| 15979 hash ^= String::cast(script->source())->Hash(); | 16002 hash ^= String::cast(script->source())->Hash(); |
| 15980 STATIC_ASSERT(LANGUAGE_END == 2); | 16003 STATIC_ASSERT(LANGUAGE_END == 2); |
| 15981 if (is_strict(language_mode)) hash ^= 0x8000; | 16004 if (is_strict(language_mode)) hash ^= 0x8000; |
| 15982 hash += scope_position; | 16005 hash += position; |
| 15983 } | 16006 } |
| 15984 return hash; | 16007 return hash; |
| 15985 } | 16008 } |
| 15986 | 16009 |
| 15987 uint32_t Hash() override { | 16010 uint32_t Hash() override { |
| 15988 return StringSharedHashHelper(*source_, *shared_, language_mode_, | 16011 return StringSharedHashHelper(*source_, *shared_, language_mode_, |
| 15989 scope_position_); | 16012 position_); |
| 15990 } | 16013 } |
| 15991 | 16014 |
| 15992 uint32_t HashForObject(Object* obj) override { | 16015 uint32_t HashForObject(Object* obj) override { |
| 15993 DisallowHeapAllocation no_allocation; | 16016 DisallowHeapAllocation no_allocation; |
| 15994 if (obj->IsNumber()) { | 16017 if (obj->IsNumber()) { |
| 15995 return static_cast<uint32_t>(obj->Number()); | 16018 return static_cast<uint32_t>(obj->Number()); |
| 15996 } | 16019 } |
| 15997 FixedArray* other_array = FixedArray::cast(obj); | 16020 FixedArray* other_array = FixedArray::cast(obj); |
| 15998 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); | 16021 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); |
| 15999 String* source = String::cast(other_array->get(1)); | 16022 String* source = String::cast(other_array->get(1)); |
| 16000 int language_unchecked = Smi::cast(other_array->get(2))->value(); | 16023 int language_unchecked = Smi::cast(other_array->get(2))->value(); |
| 16001 DCHECK(is_valid_language_mode(language_unchecked)); | 16024 DCHECK(is_valid_language_mode(language_unchecked)); |
| 16002 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked); | 16025 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked); |
| 16003 int scope_position = Smi::cast(other_array->get(3))->value(); | 16026 int position = Smi::cast(other_array->get(3))->value(); |
| 16004 return StringSharedHashHelper(source, shared, language_mode, | 16027 return StringSharedHashHelper(source, shared, language_mode, position); |
| 16005 scope_position); | |
| 16006 } | 16028 } |
| 16007 | 16029 |
| 16008 | 16030 |
| 16009 Handle<Object> AsHandle(Isolate* isolate) override { | 16031 Handle<Object> AsHandle(Isolate* isolate) override { |
| 16010 Handle<FixedArray> array = isolate->factory()->NewFixedArray(4); | 16032 Handle<FixedArray> array = isolate->factory()->NewFixedArray(4); |
| 16011 array->set(0, *shared_); | 16033 array->set(0, *shared_); |
| 16012 array->set(1, *source_); | 16034 array->set(1, *source_); |
| 16013 array->set(2, Smi::FromInt(language_mode_)); | 16035 array->set(2, Smi::FromInt(language_mode_)); |
| 16014 array->set(3, Smi::FromInt(scope_position_)); | 16036 array->set(3, Smi::FromInt(position_)); |
| 16015 return array; | 16037 return array; |
| 16016 } | 16038 } |
| 16017 | 16039 |
| 16018 private: | 16040 private: |
| 16019 Handle<String> source_; | 16041 Handle<String> source_; |
| 16020 Handle<SharedFunctionInfo> shared_; | 16042 Handle<SharedFunctionInfo> shared_; |
| 16021 LanguageMode language_mode_; | 16043 LanguageMode language_mode_; |
| 16022 int scope_position_; | 16044 int position_; |
| 16023 }; | 16045 }; |
| 16024 | 16046 |
| 16025 // static | 16047 // static |
| 16026 const char* JSPromise::Status(int status) { | 16048 const char* JSPromise::Status(int status) { |
| 16027 switch (status) { | 16049 switch (status) { |
| 16028 case v8::Promise::kFulfilled: | 16050 case v8::Promise::kFulfilled: |
| 16029 return "resolved"; | 16051 return "resolved"; |
| 16030 case v8::Promise::kPending: | 16052 case v8::Promise::kPending: |
| 16031 return "pending"; | 16053 return "pending"; |
| 16032 case v8::Promise::kRejected: | 16054 case v8::Promise::kRejected: |
| (...skipping 1581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17614 if (obj->IsSharedFunctionInfo()) { | 17636 if (obj->IsSharedFunctionInfo()) { |
| 17615 Cell* literals = | 17637 Cell* literals = |
| 17616 SearchLiteralsMap(this, index + 2, context->native_context()); | 17638 SearchLiteralsMap(this, index + 2, context->native_context()); |
| 17617 return InfoVectorPair(SharedFunctionInfo::cast(obj), literals); | 17639 return InfoVectorPair(SharedFunctionInfo::cast(obj), literals); |
| 17618 } | 17640 } |
| 17619 return empty_result; | 17641 return empty_result; |
| 17620 } | 17642 } |
| 17621 | 17643 |
| 17622 InfoVectorPair CompilationCacheTable::LookupEval( | 17644 InfoVectorPair CompilationCacheTable::LookupEval( |
| 17623 Handle<String> src, Handle<SharedFunctionInfo> outer_info, | 17645 Handle<String> src, Handle<SharedFunctionInfo> outer_info, |
| 17624 Handle<Context> native_context, LanguageMode language_mode, | 17646 Handle<Context> native_context, LanguageMode language_mode, int position) { |
| 17625 int scope_position) { | |
| 17626 InfoVectorPair empty_result; | 17647 InfoVectorPair empty_result; |
| 17627 // Cache key is the tuple (source, outer shared function info, scope position) | 17648 StringSharedKey key(src, outer_info, language_mode, position); |
| 17628 // to unambiguously identify the context chain the cached eval code assumes. | |
| 17629 StringSharedKey key(src, outer_info, language_mode, scope_position); | |
| 17630 int entry = FindEntry(&key); | 17649 int entry = FindEntry(&key); |
| 17631 if (entry == kNotFound) return empty_result; | 17650 if (entry == kNotFound) return empty_result; |
| 17632 int index = EntryToIndex(entry); | 17651 int index = EntryToIndex(entry); |
| 17633 if (!get(index)->IsFixedArray()) return empty_result; | 17652 if (!get(index)->IsFixedArray()) return empty_result; |
| 17634 Object* obj = get(EntryToIndex(entry) + 1); | 17653 Object* obj = get(EntryToIndex(entry) + 1); |
| 17635 if (obj->IsSharedFunctionInfo()) { | 17654 if (obj->IsSharedFunctionInfo()) { |
| 17636 Cell* literals = | 17655 Cell* literals = |
| 17637 SearchLiteralsMap(this, EntryToIndex(entry) + 2, *native_context); | 17656 SearchLiteralsMap(this, EntryToIndex(entry) + 2, *native_context); |
| 17638 return InfoVectorPair(SharedFunctionInfo::cast(obj), literals); | 17657 return InfoVectorPair(SharedFunctionInfo::cast(obj), literals); |
| 17639 } | 17658 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17680 cache->set(EntryToIndex(entry), *k); | 17699 cache->set(EntryToIndex(entry), *k); |
| 17681 cache->set(EntryToIndex(entry) + 1, *value); | 17700 cache->set(EntryToIndex(entry) + 1, *value); |
| 17682 AddToLiteralsMap(cache, EntryToIndex(entry) + 2, native_context, literals); | 17701 AddToLiteralsMap(cache, EntryToIndex(entry) + 2, native_context, literals); |
| 17683 cache->ElementAdded(); | 17702 cache->ElementAdded(); |
| 17684 return cache; | 17703 return cache; |
| 17685 } | 17704 } |
| 17686 | 17705 |
| 17687 Handle<CompilationCacheTable> CompilationCacheTable::PutEval( | 17706 Handle<CompilationCacheTable> CompilationCacheTable::PutEval( |
| 17688 Handle<CompilationCacheTable> cache, Handle<String> src, | 17707 Handle<CompilationCacheTable> cache, Handle<String> src, |
| 17689 Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value, | 17708 Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value, |
| 17690 Handle<Context> native_context, Handle<Cell> literals, int scope_position) { | 17709 Handle<Context> native_context, Handle<Cell> literals, int position) { |
| 17691 Isolate* isolate = cache->GetIsolate(); | 17710 Isolate* isolate = cache->GetIsolate(); |
| 17692 StringSharedKey key(src, outer_info, value->language_mode(), scope_position); | 17711 StringSharedKey key(src, outer_info, value->language_mode(), position); |
| 17693 { | 17712 { |
| 17694 Handle<Object> k = key.AsHandle(isolate); | 17713 Handle<Object> k = key.AsHandle(isolate); |
| 17695 int entry = cache->FindEntry(&key); | 17714 int entry = cache->FindEntry(&key); |
| 17696 if (entry != kNotFound) { | 17715 if (entry != kNotFound) { |
| 17697 cache->set(EntryToIndex(entry), *k); | 17716 cache->set(EntryToIndex(entry), *k); |
| 17698 cache->set(EntryToIndex(entry) + 1, *value); | 17717 cache->set(EntryToIndex(entry) + 1, *value); |
| 17699 // AddToLiteralsMap may allocate a new sub-array to live in the entry, | 17718 // AddToLiteralsMap may allocate a new sub-array to live in the entry, |
| 17700 // but it won't change the cache array. Therefore EntryToIndex and | 17719 // but it won't change the cache array. Therefore EntryToIndex and |
| 17701 // entry remains correct. | 17720 // entry remains correct. |
| 17702 AddToLiteralsMap(cache, EntryToIndex(entry) + 2, native_context, | 17721 AddToLiteralsMap(cache, EntryToIndex(entry) + 2, native_context, |
| (...skipping 2529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 20232 // depend on this. | 20251 // depend on this. |
| 20233 return DICTIONARY_ELEMENTS; | 20252 return DICTIONARY_ELEMENTS; |
| 20234 } | 20253 } |
| 20235 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 20254 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
| 20236 return kind; | 20255 return kind; |
| 20237 } | 20256 } |
| 20238 } | 20257 } |
| 20239 | 20258 |
| 20240 } // namespace internal | 20259 } // namespace internal |
| 20241 } // namespace v8 | 20260 } // namespace v8 |
| OLD | NEW |