| 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 |