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 |