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 12802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12813 return isolate->factory()->NewSubString( | 12813 return isolate->factory()->NewSubString( |
12814 script_source, Handle<Smi>::cast(class_start_position)->value(), | 12814 script_source, Handle<Smi>::cast(class_start_position)->value(), |
12815 Handle<Smi>::cast(class_end_position)->value()); | 12815 Handle<Smi>::cast(class_end_position)->value()); |
12816 } | 12816 } |
12817 | 12817 |
12818 // Check if we have source code for the {function}. | 12818 // Check if we have source code for the {function}. |
12819 if (!shared_info->HasSourceCode()) { | 12819 if (!shared_info->HasSourceCode()) { |
12820 return NativeCodeFunctionSourceString(shared_info); | 12820 return NativeCodeFunctionSourceString(shared_info); |
12821 } | 12821 } |
12822 | 12822 |
| 12823 if (FLAG_harmony_function_tostring) { |
| 12824 return Handle<String>::cast(shared_info->GetSourceCodeHarmony()); |
| 12825 } |
| 12826 |
12823 IncrementalStringBuilder builder(isolate); | 12827 IncrementalStringBuilder builder(isolate); |
12824 FunctionKind kind = shared_info->kind(); | 12828 FunctionKind kind = shared_info->kind(); |
12825 if (!IsArrowFunction(kind)) { | 12829 if (!IsArrowFunction(kind)) { |
12826 if (IsConciseMethod(kind)) { | 12830 if (IsConciseMethod(kind)) { |
12827 if (IsGeneratorFunction(kind)) { | 12831 if (IsGeneratorFunction(kind)) { |
12828 builder.AppendCharacter('*'); | 12832 builder.AppendCharacter('*'); |
12829 } else if (IsAsyncFunction(kind)) { | 12833 } else if (IsAsyncFunction(kind)) { |
12830 builder.AppendCString("async "); | 12834 builder.AppendCString("async "); |
12831 } | 12835 } |
12832 } else { | 12836 } else { |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13283 } | 13287 } |
13284 | 13288 |
13285 | 13289 |
13286 Handle<Object> SharedFunctionInfo::GetSourceCode() { | 13290 Handle<Object> SharedFunctionInfo::GetSourceCode() { |
13287 if (!HasSourceCode()) return GetIsolate()->factory()->undefined_value(); | 13291 if (!HasSourceCode()) return GetIsolate()->factory()->undefined_value(); |
13288 Handle<String> source(String::cast(Script::cast(script())->source())); | 13292 Handle<String> source(String::cast(Script::cast(script())->source())); |
13289 return GetIsolate()->factory()->NewSubString( | 13293 return GetIsolate()->factory()->NewSubString( |
13290 source, start_position(), end_position()); | 13294 source, start_position(), end_position()); |
13291 } | 13295 } |
13292 | 13296 |
| 13297 Handle<Object> SharedFunctionInfo::GetSourceCodeHarmony() { |
| 13298 Isolate* isolate = GetIsolate(); |
| 13299 if (!HasSourceCode()) return isolate->factory()->undefined_value(); |
| 13300 Handle<String> script_source(String::cast(Script::cast(script())->source())); |
| 13301 int start_pos = function_token_position(); |
| 13302 if (start_pos == kNoSourcePosition) start_pos = start_position(); |
| 13303 return isolate->factory()->NewSubString(script_source, start_pos, |
| 13304 end_position()); |
| 13305 } |
13293 | 13306 |
13294 bool SharedFunctionInfo::IsInlineable() { | 13307 bool SharedFunctionInfo::IsInlineable() { |
13295 // Check that the function has a script associated with it. | 13308 // Check that the function has a script associated with it. |
13296 if (!script()->IsScript()) return false; | 13309 if (!script()->IsScript()) return false; |
13297 return !optimization_disabled(); | 13310 return !optimization_disabled(); |
13298 } | 13311 } |
13299 | 13312 |
13300 | 13313 |
13301 int SharedFunctionInfo::SourceSize() { | 13314 int SharedFunctionInfo::SourceSize() { |
13302 return end_position() - start_position(); | 13315 return end_position() - start_position(); |
(...skipping 2457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15760 } else { | 15773 } else { |
15761 os << " (" << PrivateSymbolToName() << ")"; | 15774 os << " (" << PrivateSymbolToName() << ")"; |
15762 } | 15775 } |
15763 os << ">"; | 15776 os << ">"; |
15764 } | 15777 } |
15765 | 15778 |
15766 | 15779 |
15767 // StringSharedKeys are used as keys in the eval cache. | 15780 // StringSharedKeys are used as keys in the eval cache. |
15768 class StringSharedKey : public HashTableKey { | 15781 class StringSharedKey : public HashTableKey { |
15769 public: | 15782 public: |
| 15783 // This tuple unambiguously identifies calls to eval() or |
| 15784 // CreateDynamicFunction() (such as through the Function() constructor). |
| 15785 // * source is the string passed into eval(). For dynamic functions, this is |
| 15786 // the effective source for the function, some of which is implicitly |
| 15787 // generated. |
| 15788 // * shared is the shared function info for the function containing the call |
| 15789 // to eval(). for dynamic functions, shared is the native context closure. |
| 15790 // * When positive, position is the position in the source where eval is |
| 15791 // called. When negative, position is the negation of the position in the |
| 15792 // dynamic function's effective source where the ')' ends the parameters. |
15770 StringSharedKey(Handle<String> source, Handle<SharedFunctionInfo> shared, | 15793 StringSharedKey(Handle<String> source, Handle<SharedFunctionInfo> shared, |
15771 LanguageMode language_mode, int scope_position) | 15794 LanguageMode language_mode, int position) |
15772 : source_(source), | 15795 : source_(source), |
15773 shared_(shared), | 15796 shared_(shared), |
15774 language_mode_(language_mode), | 15797 language_mode_(language_mode), |
15775 scope_position_(scope_position) {} | 15798 position_(position) {} |
15776 | 15799 |
15777 bool IsMatch(Object* other) override { | 15800 bool IsMatch(Object* other) override { |
15778 DisallowHeapAllocation no_allocation; | 15801 DisallowHeapAllocation no_allocation; |
15779 if (!other->IsFixedArray()) { | 15802 if (!other->IsFixedArray()) { |
15780 if (!other->IsNumber()) return false; | 15803 if (!other->IsNumber()) return false; |
15781 uint32_t other_hash = static_cast<uint32_t>(other->Number()); | 15804 uint32_t other_hash = static_cast<uint32_t>(other->Number()); |
15782 return Hash() == other_hash; | 15805 return Hash() == other_hash; |
15783 } | 15806 } |
15784 FixedArray* other_array = FixedArray::cast(other); | 15807 FixedArray* other_array = FixedArray::cast(other); |
15785 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); | 15808 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); |
15786 if (shared != *shared_) return false; | 15809 if (shared != *shared_) return false; |
15787 int language_unchecked = Smi::cast(other_array->get(2))->value(); | 15810 int language_unchecked = Smi::cast(other_array->get(2))->value(); |
15788 DCHECK(is_valid_language_mode(language_unchecked)); | 15811 DCHECK(is_valid_language_mode(language_unchecked)); |
15789 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked); | 15812 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked); |
15790 if (language_mode != language_mode_) return false; | 15813 if (language_mode != language_mode_) return false; |
15791 int scope_position = Smi::cast(other_array->get(3))->value(); | 15814 int position = Smi::cast(other_array->get(3))->value(); |
15792 if (scope_position != scope_position_) return false; | 15815 if (position != position_) return false; |
15793 String* source = String::cast(other_array->get(1)); | 15816 String* source = String::cast(other_array->get(1)); |
15794 return source->Equals(*source_); | 15817 return source->Equals(*source_); |
15795 } | 15818 } |
15796 | 15819 |
15797 static uint32_t StringSharedHashHelper(String* source, | 15820 static uint32_t StringSharedHashHelper(String* source, |
15798 SharedFunctionInfo* shared, | 15821 SharedFunctionInfo* shared, |
15799 LanguageMode language_mode, | 15822 LanguageMode language_mode, |
15800 int scope_position) { | 15823 int position) { |
15801 uint32_t hash = source->Hash(); | 15824 uint32_t hash = source->Hash(); |
15802 if (shared->HasSourceCode()) { | 15825 if (shared->HasSourceCode()) { |
15803 // Instead of using the SharedFunctionInfo pointer in the hash | 15826 // Instead of using the SharedFunctionInfo pointer in the hash |
15804 // code computation, we use a combination of the hash of the | 15827 // code computation, we use a combination of the hash of the |
15805 // script source code and the start position of the calling scope. | 15828 // script source code and the start position of the calling scope. |
15806 // We do this to ensure that the cache entries can survive garbage | 15829 // We do this to ensure that the cache entries can survive garbage |
15807 // collection. | 15830 // collection. |
15808 Script* script(Script::cast(shared->script())); | 15831 Script* script(Script::cast(shared->script())); |
15809 hash ^= String::cast(script->source())->Hash(); | 15832 hash ^= String::cast(script->source())->Hash(); |
15810 STATIC_ASSERT(LANGUAGE_END == 2); | 15833 STATIC_ASSERT(LANGUAGE_END == 2); |
15811 if (is_strict(language_mode)) hash ^= 0x8000; | 15834 if (is_strict(language_mode)) hash ^= 0x8000; |
15812 hash += scope_position; | 15835 hash += position; |
15813 } | 15836 } |
15814 return hash; | 15837 return hash; |
15815 } | 15838 } |
15816 | 15839 |
15817 uint32_t Hash() override { | 15840 uint32_t Hash() override { |
15818 return StringSharedHashHelper(*source_, *shared_, language_mode_, | 15841 return StringSharedHashHelper(*source_, *shared_, language_mode_, |
15819 scope_position_); | 15842 position_); |
15820 } | 15843 } |
15821 | 15844 |
15822 uint32_t HashForObject(Object* obj) override { | 15845 uint32_t HashForObject(Object* obj) override { |
15823 DisallowHeapAllocation no_allocation; | 15846 DisallowHeapAllocation no_allocation; |
15824 if (obj->IsNumber()) { | 15847 if (obj->IsNumber()) { |
15825 return static_cast<uint32_t>(obj->Number()); | 15848 return static_cast<uint32_t>(obj->Number()); |
15826 } | 15849 } |
15827 FixedArray* other_array = FixedArray::cast(obj); | 15850 FixedArray* other_array = FixedArray::cast(obj); |
15828 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); | 15851 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); |
15829 String* source = String::cast(other_array->get(1)); | 15852 String* source = String::cast(other_array->get(1)); |
15830 int language_unchecked = Smi::cast(other_array->get(2))->value(); | 15853 int language_unchecked = Smi::cast(other_array->get(2))->value(); |
15831 DCHECK(is_valid_language_mode(language_unchecked)); | 15854 DCHECK(is_valid_language_mode(language_unchecked)); |
15832 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked); | 15855 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked); |
15833 int scope_position = Smi::cast(other_array->get(3))->value(); | 15856 int position = Smi::cast(other_array->get(3))->value(); |
15834 return StringSharedHashHelper(source, shared, language_mode, | 15857 return StringSharedHashHelper(source, shared, language_mode, position); |
15835 scope_position); | |
15836 } | 15858 } |
15837 | 15859 |
15838 | 15860 |
15839 Handle<Object> AsHandle(Isolate* isolate) override { | 15861 Handle<Object> AsHandle(Isolate* isolate) override { |
15840 Handle<FixedArray> array = isolate->factory()->NewFixedArray(4); | 15862 Handle<FixedArray> array = isolate->factory()->NewFixedArray(4); |
15841 array->set(0, *shared_); | 15863 array->set(0, *shared_); |
15842 array->set(1, *source_); | 15864 array->set(1, *source_); |
15843 array->set(2, Smi::FromInt(language_mode_)); | 15865 array->set(2, Smi::FromInt(language_mode_)); |
15844 array->set(3, Smi::FromInt(scope_position_)); | 15866 array->set(3, Smi::FromInt(position_)); |
15845 return array; | 15867 return array; |
15846 } | 15868 } |
15847 | 15869 |
15848 private: | 15870 private: |
15849 Handle<String> source_; | 15871 Handle<String> source_; |
15850 Handle<SharedFunctionInfo> shared_; | 15872 Handle<SharedFunctionInfo> shared_; |
15851 LanguageMode language_mode_; | 15873 LanguageMode language_mode_; |
15852 int scope_position_; | 15874 int position_; |
15853 }; | 15875 }; |
15854 | 15876 |
15855 // static | 15877 // static |
15856 const char* JSPromise::Status(int status) { | 15878 const char* JSPromise::Status(int status) { |
15857 switch (status) { | 15879 switch (status) { |
15858 case v8::Promise::kFulfilled: | 15880 case v8::Promise::kFulfilled: |
15859 return "resolved"; | 15881 return "resolved"; |
15860 case v8::Promise::kPending: | 15882 case v8::Promise::kPending: |
15861 return "pending"; | 15883 return "pending"; |
15862 case v8::Promise::kRejected: | 15884 case v8::Promise::kRejected: |
(...skipping 1581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17444 if (obj->IsSharedFunctionInfo()) { | 17466 if (obj->IsSharedFunctionInfo()) { |
17445 Cell* literals = | 17467 Cell* literals = |
17446 SearchLiteralsMap(this, index + 2, context->native_context()); | 17468 SearchLiteralsMap(this, index + 2, context->native_context()); |
17447 return InfoVectorPair(SharedFunctionInfo::cast(obj), literals); | 17469 return InfoVectorPair(SharedFunctionInfo::cast(obj), literals); |
17448 } | 17470 } |
17449 return empty_result; | 17471 return empty_result; |
17450 } | 17472 } |
17451 | 17473 |
17452 InfoVectorPair CompilationCacheTable::LookupEval( | 17474 InfoVectorPair CompilationCacheTable::LookupEval( |
17453 Handle<String> src, Handle<SharedFunctionInfo> outer_info, | 17475 Handle<String> src, Handle<SharedFunctionInfo> outer_info, |
17454 Handle<Context> native_context, LanguageMode language_mode, | 17476 Handle<Context> native_context, LanguageMode language_mode, int position) { |
17455 int scope_position) { | |
17456 InfoVectorPair empty_result; | 17477 InfoVectorPair empty_result; |
17457 // Cache key is the tuple (source, outer shared function info, scope position) | 17478 StringSharedKey key(src, outer_info, language_mode, position); |
17458 // to unambiguously identify the context chain the cached eval code assumes. | |
17459 StringSharedKey key(src, outer_info, language_mode, scope_position); | |
17460 int entry = FindEntry(&key); | 17479 int entry = FindEntry(&key); |
17461 if (entry == kNotFound) return empty_result; | 17480 if (entry == kNotFound) return empty_result; |
17462 int index = EntryToIndex(entry); | 17481 int index = EntryToIndex(entry); |
17463 if (!get(index)->IsFixedArray()) return empty_result; | 17482 if (!get(index)->IsFixedArray()) return empty_result; |
17464 Object* obj = get(EntryToIndex(entry) + 1); | 17483 Object* obj = get(EntryToIndex(entry) + 1); |
17465 if (obj->IsSharedFunctionInfo()) { | 17484 if (obj->IsSharedFunctionInfo()) { |
17466 Cell* literals = | 17485 Cell* literals = |
17467 SearchLiteralsMap(this, EntryToIndex(entry) + 2, *native_context); | 17486 SearchLiteralsMap(this, EntryToIndex(entry) + 2, *native_context); |
17468 return InfoVectorPair(SharedFunctionInfo::cast(obj), literals); | 17487 return InfoVectorPair(SharedFunctionInfo::cast(obj), literals); |
17469 } | 17488 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17510 cache->set(EntryToIndex(entry), *k); | 17529 cache->set(EntryToIndex(entry), *k); |
17511 cache->set(EntryToIndex(entry) + 1, *value); | 17530 cache->set(EntryToIndex(entry) + 1, *value); |
17512 AddToLiteralsMap(cache, EntryToIndex(entry) + 2, native_context, literals); | 17531 AddToLiteralsMap(cache, EntryToIndex(entry) + 2, native_context, literals); |
17513 cache->ElementAdded(); | 17532 cache->ElementAdded(); |
17514 return cache; | 17533 return cache; |
17515 } | 17534 } |
17516 | 17535 |
17517 Handle<CompilationCacheTable> CompilationCacheTable::PutEval( | 17536 Handle<CompilationCacheTable> CompilationCacheTable::PutEval( |
17518 Handle<CompilationCacheTable> cache, Handle<String> src, | 17537 Handle<CompilationCacheTable> cache, Handle<String> src, |
17519 Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value, | 17538 Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value, |
17520 Handle<Context> native_context, Handle<Cell> literals, int scope_position) { | 17539 Handle<Context> native_context, Handle<Cell> literals, int position) { |
17521 Isolate* isolate = cache->GetIsolate(); | 17540 Isolate* isolate = cache->GetIsolate(); |
17522 StringSharedKey key(src, outer_info, value->language_mode(), scope_position); | 17541 StringSharedKey key(src, outer_info, value->language_mode(), position); |
17523 { | 17542 { |
17524 Handle<Object> k = key.AsHandle(isolate); | 17543 Handle<Object> k = key.AsHandle(isolate); |
17525 int entry = cache->FindEntry(&key); | 17544 int entry = cache->FindEntry(&key); |
17526 if (entry != kNotFound) { | 17545 if (entry != kNotFound) { |
17527 cache->set(EntryToIndex(entry), *k); | 17546 cache->set(EntryToIndex(entry), *k); |
17528 cache->set(EntryToIndex(entry) + 1, *value); | 17547 cache->set(EntryToIndex(entry) + 1, *value); |
17529 // AddToLiteralsMap may allocate a new sub-array to live in the entry, | 17548 // AddToLiteralsMap may allocate a new sub-array to live in the entry, |
17530 // but it won't change the cache array. Therefore EntryToIndex and | 17549 // but it won't change the cache array. Therefore EntryToIndex and |
17531 // entry remains correct. | 17550 // entry remains correct. |
17532 AddToLiteralsMap(cache, EntryToIndex(entry) + 2, native_context, | 17551 AddToLiteralsMap(cache, EntryToIndex(entry) + 2, native_context, |
(...skipping 2529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
20062 // depend on this. | 20081 // depend on this. |
20063 return DICTIONARY_ELEMENTS; | 20082 return DICTIONARY_ELEMENTS; |
20064 } | 20083 } |
20065 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 20084 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
20066 return kind; | 20085 return kind; |
20067 } | 20086 } |
20068 } | 20087 } |
20069 | 20088 |
20070 } // namespace internal | 20089 } // namespace internal |
20071 } // namespace v8 | 20090 } // namespace v8 |
OLD | NEW |