OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 // Magical syntax support. | 259 // Magical syntax support. |
260 Expression* ParseV8Intrinsic(bool* ok); | 260 Expression* ParseV8Intrinsic(bool* ok); |
261 | 261 |
262 INLINE(Token::Value peek()) { return scanner_.peek(); } | 262 INLINE(Token::Value peek()) { return scanner_.peek(); } |
263 INLINE(Token::Value Next()) { return scanner_.Next(); } | 263 INLINE(Token::Value Next()) { return scanner_.Next(); } |
264 INLINE(void Consume(Token::Value token)); | 264 INLINE(void Consume(Token::Value token)); |
265 void Expect(Token::Value token, bool* ok); | 265 void Expect(Token::Value token, bool* ok); |
266 bool Check(Token::Value token); | 266 bool Check(Token::Value token); |
267 void ExpectSemicolon(bool* ok); | 267 void ExpectSemicolon(bool* ok); |
268 | 268 |
| 269 Handle<String> GetSymbol(bool* ok); |
| 270 |
269 // Get odd-ball literals. | 271 // Get odd-ball literals. |
270 Literal* GetLiteralUndefined(); | 272 Literal* GetLiteralUndefined(); |
271 Literal* GetLiteralTheHole(); | 273 Literal* GetLiteralTheHole(); |
272 Literal* GetLiteralNumber(double value); | 274 Literal* GetLiteralNumber(double value); |
273 | 275 |
274 Handle<String> ParseIdentifier(bool* ok); | 276 Handle<String> ParseIdentifier(bool* ok); |
275 Handle<String> ParseIdentifierName(bool* ok); | 277 Handle<String> ParseIdentifierName(bool* ok); |
276 Handle<String> ParseIdentifierOrGetOrSet(bool* is_get, | 278 Handle<String> ParseIdentifierOrGetOrSet(bool* is_get, |
277 bool* is_set, | 279 bool* is_set, |
278 bool* ok); | 280 bool* ok); |
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 | 823 |
822 class ParserFactory BASE_EMBEDDED { | 824 class ParserFactory BASE_EMBEDDED { |
823 public: | 825 public: |
824 explicit ParserFactory(bool is_pre_parsing) : | 826 explicit ParserFactory(bool is_pre_parsing) : |
825 is_pre_parsing_(is_pre_parsing) { } | 827 is_pre_parsing_(is_pre_parsing) { } |
826 | 828 |
827 virtual ~ParserFactory() { } | 829 virtual ~ParserFactory() { } |
828 | 830 |
829 virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with); | 831 virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with); |
830 | 832 |
831 virtual Handle<String> LookupSymbol(const char* string, int length) { | 833 virtual Handle<String> LookupSymbol(int index, Vector<const char> string) { |
832 return Handle<String>(); | 834 return Handle<String>(); |
833 } | 835 } |
834 | 836 |
835 virtual Handle<String> EmptySymbol() { | 837 virtual Handle<String> EmptySymbol() { |
836 return Handle<String>(); | 838 return Handle<String>(); |
837 } | 839 } |
838 | 840 |
839 virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) { | 841 virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) { |
840 if (obj == VariableProxySentinel::this_proxy()) { | 842 if (obj == VariableProxySentinel::this_proxy()) { |
841 return Property::this_property(); | 843 return Property::this_property(); |
(...skipping 20 matching lines...) Expand all Loading... |
862 bool is_pre_parsing_; | 864 bool is_pre_parsing_; |
863 }; | 865 }; |
864 | 866 |
865 | 867 |
866 class ParserLog BASE_EMBEDDED { | 868 class ParserLog BASE_EMBEDDED { |
867 public: | 869 public: |
868 virtual ~ParserLog() { } | 870 virtual ~ParserLog() { } |
869 | 871 |
870 // Records the occurrence of a function. | 872 // Records the occurrence of a function. |
871 virtual FunctionEntry LogFunction(int start) { return FunctionEntry(); } | 873 virtual FunctionEntry LogFunction(int start) { return FunctionEntry(); } |
| 874 virtual void LogSymbol(int start, Vector<const char> symbol) {} |
872 // Return the current position in the function entry log. | 875 // Return the current position in the function entry log. |
873 virtual int position() { return 0; } | 876 virtual int function_position() { return 0; } |
| 877 virtual int symbol_position() { return 0; } |
| 878 virtual int symbol_ids() { return 0; } |
874 virtual void LogError() { } | 879 virtual void LogError() { } |
875 }; | 880 }; |
876 | 881 |
877 | 882 |
878 class AstBuildingParserFactory : public ParserFactory { | 883 class AstBuildingParserFactory : public ParserFactory { |
879 public: | 884 public: |
880 AstBuildingParserFactory() : ParserFactory(false) { } | 885 explicit AstBuildingParserFactory(int expected_symbols) |
| 886 : ParserFactory(false), symbol_cache_(expected_symbols) { } |
881 | 887 |
882 virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with); | 888 virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with); |
883 | 889 |
884 virtual Handle<String> LookupSymbol(const char* string, int length) { | 890 virtual Handle<String> LookupSymbol(int symbol_id, |
885 return Factory::LookupSymbol(Vector<const char>(string, length)); | 891 Vector<const char> string) { |
| 892 // If there is no preparse data, we have no simpler way to identify similar |
| 893 // symbols. |
| 894 if (symbol_id < 0) return Factory::LookupSymbol(string); |
| 895 return LookupCachedSymbol(symbol_id, string); |
| 896 } |
| 897 |
| 898 Handle<String> LookupCachedSymbol(int symbol_id, |
| 899 Vector<const char> string) { |
| 900 // Make sure the cache is large enough to hold the symbol identifier. |
| 901 if (symbol_cache_.length() <= symbol_id) { |
| 902 // Increase length to index + 1. |
| 903 symbol_cache_.AddBlock(Handle<String>::null(), |
| 904 symbol_id + 1 - symbol_cache_.length()); |
| 905 } |
| 906 Handle<String> result = symbol_cache_.at(symbol_id); |
| 907 if (result.is_null()) { |
| 908 result = Factory::LookupSymbol(string); |
| 909 symbol_cache_.at(symbol_id) = result; |
| 910 return result; |
| 911 } |
| 912 Counters::total_preparse_symbols_skipped.Increment(); |
| 913 return result; |
886 } | 914 } |
887 | 915 |
888 virtual Handle<String> EmptySymbol() { | 916 virtual Handle<String> EmptySymbol() { |
889 return Factory::empty_symbol(); | 917 return Factory::empty_symbol(); |
890 } | 918 } |
891 | 919 |
892 virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) { | 920 virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) { |
893 return new Property(obj, key, pos); | 921 return new Property(obj, key, pos); |
894 } | 922 } |
895 | 923 |
896 virtual Expression* NewCall(Expression* expression, | 924 virtual Expression* NewCall(Expression* expression, |
897 ZoneList<Expression*>* arguments, | 925 ZoneList<Expression*>* arguments, |
898 int pos) { | 926 int pos) { |
899 return new Call(expression, arguments, pos); | 927 return new Call(expression, arguments, pos); |
900 } | 928 } |
901 | 929 |
902 virtual Statement* EmptyStatement(); | 930 virtual Statement* EmptyStatement(); |
| 931 private: |
| 932 List<Handle<String> > symbol_cache_; |
903 }; | 933 }; |
904 | 934 |
905 | 935 |
906 class ParserRecorder: public ParserLog { | 936 class ParserRecorder: public ParserLog { |
907 public: | 937 public: |
908 ParserRecorder(); | 938 ParserRecorder(); |
909 virtual FunctionEntry LogFunction(int start); | 939 virtual FunctionEntry LogFunction(int start); |
| 940 virtual void LogSymbol(int start, Vector<const char> literal) { |
| 941 int hash = vector_hash(literal); |
| 942 HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true); |
| 943 int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
| 944 if (id == 0) { |
| 945 // Put (symbol_id_ + 1) into entry and increment it. |
| 946 symbol_id_++; |
| 947 entry->value = reinterpret_cast<void*>(symbol_id_); |
| 948 Vector<Vector<const char> > symbol = symbol_entries_.AddBlock(1, literal); |
| 949 entry->key = &symbol[0]; |
| 950 } else { |
| 951 // Log a reuse of an earlier seen symbol. |
| 952 symbol_store_.Add(start); |
| 953 symbol_store_.Add(id - 1); |
| 954 } |
| 955 } |
910 virtual void LogError() { } | 956 virtual void LogError() { } |
911 virtual void LogMessage(Scanner::Location loc, | 957 virtual void LogMessage(Scanner::Location loc, |
912 const char* message, | 958 const char* message, |
913 Vector<const char*> args); | 959 Vector<const char*> args); |
914 Vector<unsigned> ExtractData() { | 960 Vector<unsigned> ExtractData() { |
915 int total_size = ScriptDataImpl::kHeaderSize + store_.size(); | 961 int function_size = function_store_.size(); |
| 962 int symbol_size = symbol_store_.size(); |
| 963 int total_size = ScriptDataImpl::kHeaderSize + function_size + symbol_size; |
916 Vector<unsigned> data = Vector<unsigned>::New(total_size); | 964 Vector<unsigned> data = Vector<unsigned>::New(total_size); |
| 965 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size; |
| 966 preamble_[ScriptDataImpl::kSymbolCountOffset] = symbol_id_; |
917 memcpy(data.start(), preamble_, sizeof(preamble_)); | 967 memcpy(data.start(), preamble_, sizeof(preamble_)); |
918 if (ScriptDataImpl::kHeaderSize < total_size) { | 968 int symbol_start = ScriptDataImpl::kHeaderSize + function_size; |
919 store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize, total_size)); | 969 if (function_size > 0) { |
| 970 function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize, |
| 971 symbol_start)); |
| 972 } |
| 973 if (symbol_size > 0) { |
| 974 symbol_store_.WriteTo(data.SubVector(symbol_start, total_size)); |
920 } | 975 } |
921 return data; | 976 return data; |
922 } | 977 } |
923 virtual int position() { return store_.size(); } | 978 |
| 979 virtual int function_position() { return function_store_.size(); } |
| 980 virtual int symbol_position() { return symbol_store_.size(); } |
| 981 virtual int symbol_ids() { return symbol_id_; } |
924 private: | 982 private: |
925 Collector<unsigned> store_; | 983 Collector<unsigned> function_store_; |
| 984 Collector<unsigned> symbol_store_; |
| 985 Collector<Vector<const char> > symbol_entries_; |
| 986 HashMap symbol_table_; |
| 987 int symbol_id_; |
| 988 |
| 989 static int vector_hash(Vector<const char> string) { |
| 990 int hash = 0; |
| 991 for (int i = 0; i < string.length(); i++) { |
| 992 int c = string[i]; |
| 993 hash += c; |
| 994 hash += (hash << 10); |
| 995 hash ^= (hash >> 6); |
| 996 } |
| 997 return hash; |
| 998 } |
| 999 |
| 1000 static bool vector_compare(void* a, void* b) { |
| 1001 Vector<const char>* string1 = reinterpret_cast<Vector<const char>* >(a); |
| 1002 Vector<const char>* string2 = reinterpret_cast<Vector<const char>* >(b); |
| 1003 int length = string1->length(); |
| 1004 if (string2->length() != length) return false; |
| 1005 return memcmp(string1->start(), string2->start(), length) == 0; |
| 1006 } |
| 1007 |
926 unsigned preamble_[ScriptDataImpl::kHeaderSize]; | 1008 unsigned preamble_[ScriptDataImpl::kHeaderSize]; |
927 #ifdef DEBUG | 1009 #ifdef DEBUG |
928 int prev_start; | 1010 int prev_start; |
929 #endif | 1011 #endif |
930 | 1012 |
931 bool has_error() { | 1013 bool has_error() { |
932 return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]); | 1014 return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]); |
933 } | 1015 } |
934 void WriteString(Vector<const char> str); | 1016 void WriteString(Vector<const char> str); |
935 }; | 1017 }; |
936 | 1018 |
937 | 1019 |
938 void ScriptDataImpl::SkipFunctionEntry(int start) { | 1020 void ScriptDataImpl::SkipFunctionEntry(int start) { |
939 ASSERT(index_ + FunctionEntry::kSize <= store_.length()); | 1021 ASSERT(function_index_ + FunctionEntry::kSize <= store_.length()); |
940 ASSERT(static_cast<int>(store_[index_]) == start); | 1022 ASSERT(static_cast<int>(store_[function_index_]) == start); |
941 index_ += FunctionEntry::kSize; | 1023 function_index_ += FunctionEntry::kSize; |
942 } | 1024 } |
943 | 1025 |
944 | 1026 |
945 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { | 1027 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { |
946 // The current pre-data entry must be a FunctionEntry with the given | 1028 // The current pre-data entry must be a FunctionEntry with the given |
947 // start position. | 1029 // start position. |
948 if ((index_ + FunctionEntry::kSize <= store_.length()) | 1030 if ((function_index_ + FunctionEntry::kSize <= store_.length()) |
949 && (static_cast<int>(store_[index_]) == start)) { | 1031 && (static_cast<int>(store_[function_index_]) == start)) { |
950 int index = index_; | 1032 int index = function_index_; |
951 index_ += FunctionEntry::kSize; | 1033 function_index_ += FunctionEntry::kSize; |
952 return FunctionEntry(store_.SubVector(index, | 1034 return FunctionEntry(store_.SubVector(index, |
953 index + FunctionEntry::kSize)); | 1035 index + FunctionEntry::kSize)); |
954 } | 1036 } |
955 return FunctionEntry(); | 1037 return FunctionEntry(); |
956 } | 1038 } |
957 | 1039 |
958 | 1040 |
| 1041 int ScriptDataImpl::GetSymbolIdentifier(int start) { |
| 1042 int next = symbol_index_ + 2; |
| 1043 if (next <= store_.length() |
| 1044 && static_cast<int>(store_[symbol_index_]) == start) { |
| 1045 symbol_index_ = next; |
| 1046 return store_[next - 1]; |
| 1047 } |
| 1048 return symbol_id_++; |
| 1049 } |
| 1050 |
| 1051 |
| 1052 |
959 bool ScriptDataImpl::SanityCheck() { | 1053 bool ScriptDataImpl::SanityCheck() { |
960 if (store_.length() < static_cast<int>(ScriptDataImpl::kHeaderSize)) { | 1054 // Check that the header data is valid and doesn't specify |
961 return false; | 1055 // point to positions outside the store. |
962 } | 1056 if (store_.length() < ScriptDataImpl::kHeaderSize) return false; |
963 if (magic() != ScriptDataImpl::kMagicNumber) return false; | 1057 if (magic() != ScriptDataImpl::kMagicNumber) return false; |
964 if (version() != ScriptDataImpl::kCurrentVersion) return false; | 1058 if (version() != ScriptDataImpl::kCurrentVersion) return false; |
| 1059 if (has_error()) { |
| 1060 // Extra sane sanity check for error message encoding. |
| 1061 if (store_.length() <= kHeaderSize + kMessageTextPos) return false; |
| 1062 if (Read(kMessageStartPos) > Read(kMessageEndPos)) return false; |
| 1063 unsigned arg_count = Read(kMessageArgCountPos); |
| 1064 int pos = kMessageTextPos; |
| 1065 for (unsigned int i = 0; i <= arg_count; i++) { |
| 1066 if (store_.length() <= kHeaderSize + pos) return false; |
| 1067 int length = static_cast<int>(Read(pos)); |
| 1068 if (length < 0) return false; |
| 1069 pos += 1 + length; |
| 1070 } |
| 1071 if (store_.length() < kHeaderSize + pos) return false; |
| 1072 return true; |
| 1073 } |
| 1074 // Check that the space allocated for function entries is sane. |
| 1075 int functions_size = |
| 1076 static_cast<int>(store_[ScriptDataImpl::kFunctionsSizeOffset]); |
| 1077 if (functions_size < 0) return false; |
| 1078 if (functions_size % FunctionEntry::kSize != 0) return false; |
| 1079 // Check that the count of symbols is non-negative. |
| 1080 int symbol_count = |
| 1081 static_cast<int>(store_[ScriptDataImpl::kSymbolCountOffset]); |
| 1082 if (symbol_count < 0) return false; |
| 1083 // Check that the total size has room both function entries. |
| 1084 int minimum_size = |
| 1085 ScriptDataImpl::kHeaderSize + functions_size; |
| 1086 if (store_.length() < minimum_size) return false; |
965 return true; | 1087 return true; |
966 } | 1088 } |
967 | 1089 |
968 | 1090 |
969 ParserRecorder::ParserRecorder() | 1091 ParserRecorder::ParserRecorder() |
970 : store_(0) { | 1092 : function_store_(0), |
| 1093 symbol_store_(0), |
| 1094 symbol_entries_(0), |
| 1095 symbol_table_(vector_compare), |
| 1096 symbol_id_(0) { |
971 #ifdef DEBUG | 1097 #ifdef DEBUG |
972 prev_start = -1; | 1098 prev_start = -1; |
973 #endif | 1099 #endif |
974 preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber; | 1100 preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber; |
975 preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion; | 1101 preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion; |
976 preamble_[ScriptDataImpl::kHasErrorOffset] = false; | 1102 preamble_[ScriptDataImpl::kHasErrorOffset] = false; |
| 1103 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = 0; |
| 1104 preamble_[ScriptDataImpl::kSymbolCountOffset] = 0; |
977 preamble_[ScriptDataImpl::kSizeOffset] = 0; | 1105 preamble_[ScriptDataImpl::kSizeOffset] = 0; |
978 ASSERT_EQ(4, ScriptDataImpl::kHeaderSize); | 1106 ASSERT_EQ(6, ScriptDataImpl::kHeaderSize); |
979 } | 1107 } |
980 | 1108 |
981 | 1109 |
982 void ParserRecorder::WriteString(Vector<const char> str) { | 1110 void ParserRecorder::WriteString(Vector<const char> str) { |
983 store_.Add(str.length()); | 1111 function_store_.Add(str.length()); |
984 for (int i = 0; i < str.length(); i++) { | 1112 for (int i = 0; i < str.length(); i++) { |
985 store_.Add(str[i]); | 1113 function_store_.Add(str[i]); |
986 } | 1114 } |
987 } | 1115 } |
988 | 1116 |
989 | 1117 |
990 const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) { | 1118 const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) { |
991 int length = start[0]; | 1119 int length = start[0]; |
992 char* result = NewArray<char>(length + 1); | 1120 char* result = NewArray<char>(length + 1); |
993 for (int i = 0; i < length; i++) { | 1121 for (int i = 0; i < length; i++) { |
994 result[i] = start[i + 1]; | 1122 result[i] = start[i + 1]; |
995 } | 1123 } |
996 result[length] = '\0'; | 1124 result[length] = '\0'; |
997 if (chars != NULL) *chars = length; | 1125 if (chars != NULL) *chars = length; |
998 return result; | 1126 return result; |
999 } | 1127 } |
1000 | 1128 |
1001 | 1129 |
1002 void ParserRecorder::LogMessage(Scanner::Location loc, const char* message, | 1130 void ParserRecorder::LogMessage(Scanner::Location loc, const char* message, |
1003 Vector<const char*> args) { | 1131 Vector<const char*> args) { |
1004 if (has_error()) return; | 1132 if (has_error()) return; |
1005 preamble_[ScriptDataImpl::kHasErrorOffset] = true; | 1133 preamble_[ScriptDataImpl::kHasErrorOffset] = true; |
1006 store_.Reset(); | 1134 function_store_.Reset(); |
1007 store_.Add(loc.beg_pos); | 1135 STATIC_ASSERT(ScriptDataImpl::kMessageStartPos == 0); |
1008 store_.Add(loc.end_pos); | 1136 function_store_.Add(loc.beg_pos); |
1009 store_.Add(args.length()); | 1137 STATIC_ASSERT(ScriptDataImpl::kMessageEndPos == 1); |
| 1138 function_store_.Add(loc.end_pos); |
| 1139 STATIC_ASSERT(ScriptDataImpl::kMessageArgCountPos == 2); |
| 1140 function_store_.Add(args.length()); |
| 1141 STATIC_ASSERT(ScriptDataImpl::kMessageTextPos == 3); |
1010 WriteString(CStrVector(message)); | 1142 WriteString(CStrVector(message)); |
1011 for (int i = 0; i < args.length(); i++) { | 1143 for (int i = 0; i < args.length(); i++) { |
1012 WriteString(CStrVector(args[i])); | 1144 WriteString(CStrVector(args[i])); |
1013 } | 1145 } |
1014 } | 1146 } |
1015 | 1147 |
1016 | 1148 |
1017 Scanner::Location ScriptDataImpl::MessageLocation() { | 1149 Scanner::Location ScriptDataImpl::MessageLocation() { |
1018 int beg_pos = Read(0); | 1150 int beg_pos = Read(kMessageStartPos); |
1019 int end_pos = Read(1); | 1151 int end_pos = Read(kMessageEndPos); |
1020 return Scanner::Location(beg_pos, end_pos); | 1152 return Scanner::Location(beg_pos, end_pos); |
1021 } | 1153 } |
1022 | 1154 |
1023 | 1155 |
1024 const char* ScriptDataImpl::BuildMessage() { | 1156 const char* ScriptDataImpl::BuildMessage() { |
1025 unsigned* start = ReadAddress(3); | 1157 unsigned* start = ReadAddress(kMessageTextPos); |
1026 return ReadString(start, NULL); | 1158 return ReadString(start, NULL); |
1027 } | 1159 } |
1028 | 1160 |
1029 | 1161 |
1030 Vector<const char*> ScriptDataImpl::BuildArgs() { | 1162 Vector<const char*> ScriptDataImpl::BuildArgs() { |
1031 int arg_count = Read(2); | 1163 int arg_count = Read(kMessageArgCountPos); |
1032 const char** array = NewArray<const char*>(arg_count); | 1164 const char** array = NewArray<const char*>(arg_count); |
1033 int pos = ScriptDataImpl::kHeaderSize + Read(3); | 1165 // Position after the string starting at position 3. |
| 1166 int pos = kMessageTextPos + 1 + Read(kMessageTextPos); |
1034 for (int i = 0; i < arg_count; i++) { | 1167 for (int i = 0; i < arg_count; i++) { |
1035 int count = 0; | 1168 int count = 0; |
1036 array[i] = ReadString(ReadAddress(pos), &count); | 1169 array[i] = ReadString(ReadAddress(pos), &count); |
1037 pos += count + 1; | 1170 pos += count + 1; |
1038 } | 1171 } |
1039 return Vector<const char*>(array, arg_count); | 1172 return Vector<const char*>(array, arg_count); |
1040 } | 1173 } |
1041 | 1174 |
1042 | 1175 |
1043 unsigned ScriptDataImpl::Read(int position) { | 1176 unsigned ScriptDataImpl::Read(int position) { |
1044 return store_[ScriptDataImpl::kHeaderSize + position]; | 1177 return store_[ScriptDataImpl::kHeaderSize + position]; |
1045 } | 1178 } |
1046 | 1179 |
1047 | 1180 |
1048 unsigned* ScriptDataImpl::ReadAddress(int position) { | 1181 unsigned* ScriptDataImpl::ReadAddress(int position) { |
1049 return &store_[ScriptDataImpl::kHeaderSize + position]; | 1182 return &store_[ScriptDataImpl::kHeaderSize + position]; |
1050 } | 1183 } |
1051 | 1184 |
1052 void ScriptDataImpl::FindStart(int position) { | |
1053 // Only search forwards, and linearly for now. | |
1054 while ((index_ < store_.length()) | |
1055 && (static_cast<int>(store_[index_])) < position) { | |
1056 index_ += FunctionEntry::kSize; | |
1057 } | |
1058 } | |
1059 | |
1060 | 1185 |
1061 FunctionEntry ParserRecorder::LogFunction(int start) { | 1186 FunctionEntry ParserRecorder::LogFunction(int start) { |
1062 #ifdef DEBUG | 1187 #ifdef DEBUG |
1063 ASSERT(start > prev_start); | 1188 ASSERT(start > prev_start); |
1064 prev_start = start; | 1189 prev_start = start; |
1065 #endif | 1190 #endif |
1066 if (has_error()) return FunctionEntry(); | 1191 if (has_error()) return FunctionEntry(); |
1067 FunctionEntry result(store_.AddBlock(FunctionEntry::kSize, 0)); | 1192 FunctionEntry result(function_store_.AddBlock(FunctionEntry::kSize, 0)); |
1068 result.set_start_pos(start); | 1193 result.set_start_pos(start); |
1069 return result; | 1194 return result; |
1070 } | 1195 } |
1071 | 1196 |
1072 | 1197 |
1073 class AstBuildingParser : public Parser { | 1198 class AstBuildingParser : public Parser { |
1074 public: | 1199 public: |
1075 AstBuildingParser(Handle<Script> script, bool allow_natives_syntax, | 1200 AstBuildingParser(Handle<Script> script, bool allow_natives_syntax, |
1076 v8::Extension* extension, ScriptDataImpl* pre_data) | 1201 v8::Extension* extension, ScriptDataImpl* pre_data) |
1077 : Parser(script, allow_natives_syntax, extension, PARSE, | 1202 : Parser(script, |
1078 factory(), log(), pre_data) { } | 1203 allow_natives_syntax, |
| 1204 extension, |
| 1205 PARSE, |
| 1206 factory(), |
| 1207 log(), |
| 1208 pre_data), |
| 1209 factory_(pre_data ? pre_data->symbol_count() : 16) { } |
1079 virtual void ReportMessageAt(Scanner::Location loc, const char* message, | 1210 virtual void ReportMessageAt(Scanner::Location loc, const char* message, |
1080 Vector<const char*> args); | 1211 Vector<const char*> args); |
1081 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, | 1212 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, |
1082 FunctionLiteral* fun, bool resolve, bool* ok); | 1213 FunctionLiteral* fun, bool resolve, bool* ok); |
1083 AstBuildingParserFactory* factory() { return &factory_; } | 1214 AstBuildingParserFactory* factory() { return &factory_; } |
1084 ParserLog* log() { return &log_; } | 1215 ParserLog* log() { return &log_; } |
1085 | 1216 |
1086 private: | 1217 private: |
1087 ParserLog log_; | 1218 ParserLog log_; |
1088 AstBuildingParserFactory factory_; | 1219 AstBuildingParserFactory factory_; |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1435 if (result == NULL) zone_scope.DeleteOnExit(); | 1566 if (result == NULL) zone_scope.DeleteOnExit(); |
1436 return result; | 1567 return result; |
1437 } | 1568 } |
1438 | 1569 |
1439 void Parser::ReportMessage(const char* type, Vector<const char*> args) { | 1570 void Parser::ReportMessage(const char* type, Vector<const char*> args) { |
1440 Scanner::Location source_location = scanner_.location(); | 1571 Scanner::Location source_location = scanner_.location(); |
1441 ReportMessageAt(source_location, type, args); | 1572 ReportMessageAt(source_location, type, args); |
1442 } | 1573 } |
1443 | 1574 |
1444 | 1575 |
| 1576 Handle<String> Parser::GetSymbol(bool* ok) { |
| 1577 if (pre_data() != NULL) { |
| 1578 int symbol_id = |
| 1579 pre_data()->GetSymbolIdentifier(scanner_.location().beg_pos); |
| 1580 if (symbol_id < 0) { |
| 1581 ReportInvalidPreparseData(Factory::empty_symbol(), ok); |
| 1582 return Handle<String>::null(); |
| 1583 } |
| 1584 return factory()->LookupSymbol(symbol_id, scanner_.literal()); |
| 1585 } |
| 1586 log()->LogSymbol(scanner_.location().beg_pos, scanner_.literal()); |
| 1587 return factory()->LookupSymbol(-1, scanner_.literal()); |
| 1588 } |
| 1589 |
| 1590 |
1445 void AstBuildingParser::ReportMessageAt(Scanner::Location source_location, | 1591 void AstBuildingParser::ReportMessageAt(Scanner::Location source_location, |
1446 const char* type, | 1592 const char* type, |
1447 Vector<const char*> args) { | 1593 Vector<const char*> args) { |
1448 MessageLocation location(script_, | 1594 MessageLocation location(script_, |
1449 source_location.beg_pos, source_location.end_pos); | 1595 source_location.beg_pos, source_location.end_pos); |
1450 Handle<JSArray> array = Factory::NewJSArray(args.length()); | 1596 Handle<JSArray> array = Factory::NewJSArray(args.length()); |
1451 for (int i = 0; i < args.length(); i++) { | 1597 for (int i = 0; i < args.length(); i++) { |
1452 SetElement(array, i, Factory::NewStringFromUtf8(CStrVector(args[i]))); | 1598 SetElement(array, i, Factory::NewStringFromUtf8(CStrVector(args[i]))); |
1453 } | 1599 } |
1454 Handle<Object> result = Factory::NewSyntaxError(type, array); | 1600 Handle<Object> result = Factory::NewSyntaxError(type, array); |
(...skipping 1957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3412 case Token::NUMBER: { | 3558 case Token::NUMBER: { |
3413 Consume(Token::NUMBER); | 3559 Consume(Token::NUMBER); |
3414 double value = | 3560 double value = |
3415 StringToDouble(scanner_.literal(), ALLOW_HEX | ALLOW_OCTALS); | 3561 StringToDouble(scanner_.literal(), ALLOW_HEX | ALLOW_OCTALS); |
3416 result = NewNumberLiteral(value); | 3562 result = NewNumberLiteral(value); |
3417 break; | 3563 break; |
3418 } | 3564 } |
3419 | 3565 |
3420 case Token::STRING: { | 3566 case Token::STRING: { |
3421 Consume(Token::STRING); | 3567 Consume(Token::STRING); |
3422 Handle<String> symbol = | 3568 Handle<String> symbol = GetSymbol(CHECK_OK); |
3423 factory()->LookupSymbol(scanner_.literal_string(), | |
3424 scanner_.literal_length()); | |
3425 result = NEW(Literal(symbol)); | 3569 result = NEW(Literal(symbol)); |
3426 if (fni_ != NULL) fni_->PushLiteralName(symbol); | 3570 if (fni_ != NULL) fni_->PushLiteralName(symbol); |
3427 break; | 3571 break; |
3428 } | 3572 } |
3429 | 3573 |
3430 case Token::ASSIGN_DIV: | 3574 case Token::ASSIGN_DIV: |
3431 result = ParseRegExpLiteral(true, CHECK_OK); | 3575 result = ParseRegExpLiteral(true, CHECK_OK); |
3432 break; | 3576 break; |
3433 | 3577 |
3434 case Token::DIV: | 3578 case Token::DIV: |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3682 | 3826 |
3683 | 3827 |
3684 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, | 3828 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, |
3685 bool* ok) { | 3829 bool* ok) { |
3686 // Special handling of getter and setter syntax: | 3830 // Special handling of getter and setter syntax: |
3687 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } | 3831 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } |
3688 // We have already read the "get" or "set" keyword. | 3832 // We have already read the "get" or "set" keyword. |
3689 Token::Value next = Next(); | 3833 Token::Value next = Next(); |
3690 // TODO(820): Allow NUMBER and STRING as well (and handle array indices). | 3834 // TODO(820): Allow NUMBER and STRING as well (and handle array indices). |
3691 if (next == Token::IDENTIFIER || Token::IsKeyword(next)) { | 3835 if (next == Token::IDENTIFIER || Token::IsKeyword(next)) { |
3692 Handle<String> name = | 3836 Handle<String> name = GetSymbol(CHECK_OK); |
3693 factory()->LookupSymbol(scanner_.literal_string(), | |
3694 scanner_.literal_length()); | |
3695 FunctionLiteral* value = | 3837 FunctionLiteral* value = |
3696 ParseFunctionLiteral(name, | 3838 ParseFunctionLiteral(name, |
3697 RelocInfo::kNoPosition, | 3839 RelocInfo::kNoPosition, |
3698 DECLARATION, | 3840 DECLARATION, |
3699 CHECK_OK); | 3841 CHECK_OK); |
3700 ObjectLiteral::Property* property = | 3842 ObjectLiteral::Property* property = |
3701 NEW(ObjectLiteral::Property(is_getter, value)); | 3843 NEW(ObjectLiteral::Property(is_getter, value)); |
3702 return property; | 3844 return property; |
3703 } else { | 3845 } else { |
3704 ReportUnexpectedToken(next); | 3846 ReportUnexpectedToken(next); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3748 } | 3890 } |
3749 continue; // restart the while | 3891 continue; // restart the while |
3750 } | 3892 } |
3751 // Failed to parse as get/set property, so it's just a property | 3893 // Failed to parse as get/set property, so it's just a property |
3752 // called "get" or "set". | 3894 // called "get" or "set". |
3753 key = NEW(Literal(id)); | 3895 key = NEW(Literal(id)); |
3754 break; | 3896 break; |
3755 } | 3897 } |
3756 case Token::STRING: { | 3898 case Token::STRING: { |
3757 Consume(Token::STRING); | 3899 Consume(Token::STRING); |
3758 Handle<String> string = | 3900 Handle<String> string = GetSymbol(CHECK_OK); |
3759 factory()->LookupSymbol(scanner_.literal_string(), | |
3760 scanner_.literal_length()); | |
3761 if (fni_ != NULL) fni_->PushLiteralName(string); | 3901 if (fni_ != NULL) fni_->PushLiteralName(string); |
3762 uint32_t index; | 3902 uint32_t index; |
3763 if (!string.is_null() && string->AsArrayIndex(&index)) { | 3903 if (!string.is_null() && string->AsArrayIndex(&index)) { |
3764 key = NewNumberLiteral(index); | 3904 key = NewNumberLiteral(index); |
3765 break; | 3905 break; |
3766 } | 3906 } |
3767 key = NEW(Literal(string)); | 3907 key = NEW(Literal(string)); |
3768 break; | 3908 break; |
3769 } | 3909 } |
3770 case Token::NUMBER: { | 3910 case Token::NUMBER: { |
3771 Consume(Token::NUMBER); | 3911 Consume(Token::NUMBER); |
3772 double value = | 3912 double value = |
3773 StringToDouble(scanner_.literal(), ALLOW_HEX | ALLOW_OCTALS); | 3913 StringToDouble(scanner_.literal(), ALLOW_HEX | ALLOW_OCTALS); |
3774 key = NewNumberLiteral(value); | 3914 key = NewNumberLiteral(value); |
3775 break; | 3915 break; |
3776 } | 3916 } |
3777 default: | 3917 default: |
3778 if (Token::IsKeyword(next)) { | 3918 if (Token::IsKeyword(next)) { |
3779 Consume(next); | 3919 Consume(next); |
3780 Handle<String> string = | 3920 Handle<String> string = GetSymbol(CHECK_OK); |
3781 factory()->LookupSymbol(scanner_.literal_string(), | |
3782 scanner_.literal_length()); | |
3783 key = NEW(Literal(string)); | 3921 key = NEW(Literal(string)); |
3784 } else { | 3922 } else { |
3785 // Unexpected token. | 3923 // Unexpected token. |
3786 Token::Value next = Next(); | 3924 Token::Value next = Next(); |
3787 ReportUnexpectedToken(next); | 3925 ReportUnexpectedToken(next); |
3788 *ok = false; | 3926 *ok = false; |
3789 return NULL; | 3927 return NULL; |
3790 } | 3928 } |
3791 } | 3929 } |
3792 | 3930 |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3965 if (!entry.is_valid()) { | 4103 if (!entry.is_valid()) { |
3966 ReportInvalidPreparseData(name, CHECK_OK); | 4104 ReportInvalidPreparseData(name, CHECK_OK); |
3967 } | 4105 } |
3968 end_pos = entry.end_pos(); | 4106 end_pos = entry.end_pos(); |
3969 if (end_pos <= function_block_pos) { | 4107 if (end_pos <= function_block_pos) { |
3970 // End position greater than end of stream is safe, and hard to check. | 4108 // End position greater than end of stream is safe, and hard to check. |
3971 ReportInvalidPreparseData(name, CHECK_OK); | 4109 ReportInvalidPreparseData(name, CHECK_OK); |
3972 } | 4110 } |
3973 Counters::total_preparse_skipped.Increment(end_pos - function_block_pos); | 4111 Counters::total_preparse_skipped.Increment(end_pos - function_block_pos); |
3974 scanner_.SeekForward(end_pos); | 4112 scanner_.SeekForward(end_pos); |
3975 pre_data()->Skip(entry.predata_skip()); | 4113 pre_data()->Skip(entry.predata_function_skip(), |
| 4114 entry.predata_symbol_skip(), |
| 4115 entry.symbol_id_skip()); |
3976 materialized_literal_count = entry.literal_count(); | 4116 materialized_literal_count = entry.literal_count(); |
3977 expected_property_count = entry.property_count(); | 4117 expected_property_count = entry.property_count(); |
3978 only_simple_this_property_assignments = false; | 4118 only_simple_this_property_assignments = false; |
3979 this_property_assignments = Factory::empty_fixed_array(); | 4119 this_property_assignments = Factory::empty_fixed_array(); |
3980 Expect(Token::RBRACE, CHECK_OK); | 4120 Expect(Token::RBRACE, CHECK_OK); |
3981 } else { | 4121 } else { |
3982 if (pre_data() != NULL) { | 4122 if (pre_data() != NULL) { |
3983 // Skip pre-data entry for non-lazily compiled function. | 4123 // Skip pre-data entry for non-lazily compiled function. |
3984 pre_data()->SkipFunctionEntry(function_block_pos); | 4124 pre_data()->SkipFunctionEntry(function_block_pos); |
3985 } | 4125 } |
3986 FunctionEntry entry = log()->LogFunction(function_block_pos); | 4126 FunctionEntry entry = log()->LogFunction(function_block_pos); |
3987 int predata_position_before = log()->position(); | 4127 int predata_function_position_before = log()->function_position(); |
| 4128 int predata_symbol_position_before = log()->symbol_position(); |
| 4129 int symbol_ids_before = log()->symbol_ids(); |
3988 ParseSourceElements(&body, Token::RBRACE, CHECK_OK); | 4130 ParseSourceElements(&body, Token::RBRACE, CHECK_OK); |
3989 materialized_literal_count = temp_scope.materialized_literal_count(); | 4131 materialized_literal_count = temp_scope.materialized_literal_count(); |
3990 expected_property_count = temp_scope.expected_property_count(); | 4132 expected_property_count = temp_scope.expected_property_count(); |
3991 only_simple_this_property_assignments = | 4133 only_simple_this_property_assignments = |
3992 temp_scope.only_simple_this_property_assignments(); | 4134 temp_scope.only_simple_this_property_assignments(); |
3993 this_property_assignments = temp_scope.this_property_assignments(); | 4135 this_property_assignments = temp_scope.this_property_assignments(); |
3994 | 4136 |
3995 Expect(Token::RBRACE, CHECK_OK); | 4137 Expect(Token::RBRACE, CHECK_OK); |
3996 end_pos = scanner_.location().end_pos; | 4138 end_pos = scanner_.location().end_pos; |
3997 if (entry.is_valid()) { | 4139 if (entry.is_valid()) { |
3998 entry.set_end_pos(end_pos); | 4140 entry.set_end_pos(end_pos); |
3999 entry.set_literal_count(materialized_literal_count); | 4141 entry.set_literal_count(materialized_literal_count); |
4000 entry.set_property_count(expected_property_count); | 4142 entry.set_property_count(expected_property_count); |
4001 entry.set_predata_skip(log()->position() - predata_position_before); | 4143 entry.set_predata_function_skip( |
| 4144 log()->function_position() - predata_function_position_before); |
| 4145 entry.set_predata_symbol_skip( |
| 4146 log()->symbol_position() - predata_symbol_position_before); |
| 4147 entry.set_symbol_id_skip( |
| 4148 log()->symbol_ids() - symbol_ids_before); |
4002 } | 4149 } |
4003 } | 4150 } |
4004 | 4151 |
4005 FunctionLiteral* function_literal = | 4152 FunctionLiteral* function_literal = |
4006 NEW(FunctionLiteral(name, | 4153 NEW(FunctionLiteral(name, |
4007 top_scope_, | 4154 top_scope_, |
4008 body.elements(), | 4155 body.elements(), |
4009 materialized_literal_count, | 4156 materialized_literal_count, |
4010 expected_property_count, | 4157 expected_property_count, |
4011 only_simple_this_property_assignments, | 4158 only_simple_this_property_assignments, |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4141 | 4288 |
4142 | 4289 |
4143 Literal* Parser::GetLiteralNumber(double value) { | 4290 Literal* Parser::GetLiteralNumber(double value) { |
4144 return NewNumberLiteral(value); | 4291 return NewNumberLiteral(value); |
4145 } | 4292 } |
4146 | 4293 |
4147 | 4294 |
4148 Handle<String> Parser::ParseIdentifier(bool* ok) { | 4295 Handle<String> Parser::ParseIdentifier(bool* ok) { |
4149 Expect(Token::IDENTIFIER, ok); | 4296 Expect(Token::IDENTIFIER, ok); |
4150 if (!*ok) return Handle<String>(); | 4297 if (!*ok) return Handle<String>(); |
4151 return factory()->LookupSymbol(scanner_.literal_string(), | 4298 return GetSymbol(ok); |
4152 scanner_.literal_length()); | |
4153 } | 4299 } |
4154 | 4300 |
4155 | 4301 |
4156 Handle<String> Parser::ParseIdentifierName(bool* ok) { | 4302 Handle<String> Parser::ParseIdentifierName(bool* ok) { |
4157 Token::Value next = Next(); | 4303 Token::Value next = Next(); |
4158 if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) { | 4304 if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) { |
4159 ReportUnexpectedToken(next); | 4305 ReportUnexpectedToken(next); |
4160 *ok = false; | 4306 *ok = false; |
4161 return Handle<String>(); | 4307 return Handle<String>(); |
4162 } | 4308 } |
4163 return factory()->LookupSymbol(scanner_.literal_string(), | 4309 return GetSymbol(ok); |
4164 scanner_.literal_length()); | |
4165 } | 4310 } |
4166 | 4311 |
4167 | 4312 |
4168 // This function reads an identifier and determines whether or not it | 4313 // This function reads an identifier and determines whether or not it |
4169 // is 'get' or 'set'. The reason for not using ParseIdentifier and | 4314 // is 'get' or 'set'. The reason for not using ParseIdentifier and |
4170 // checking on the output is that this involves heap allocation which | 4315 // checking on the output is that this involves heap allocation which |
4171 // we can't do during preparsing. | 4316 // we can't do during preparsing. |
4172 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, | 4317 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, |
4173 bool* is_set, | 4318 bool* is_set, |
4174 bool* ok) { | 4319 bool* ok) { |
4175 Expect(Token::IDENTIFIER, ok); | 4320 Expect(Token::IDENTIFIER, ok); |
4176 if (!*ok) return Handle<String>(); | 4321 if (!*ok) return Handle<String>(); |
4177 if (scanner_.literal_length() == 3) { | 4322 if (scanner_.literal_length() == 3) { |
4178 const char* token = scanner_.literal_string(); | 4323 const char* token = scanner_.literal_string(); |
4179 *is_get = strcmp(token, "get") == 0; | 4324 *is_get = strcmp(token, "get") == 0; |
4180 *is_set = !*is_get && strcmp(token, "set") == 0; | 4325 *is_set = !*is_get && strcmp(token, "set") == 0; |
4181 } | 4326 } |
4182 return factory()->LookupSymbol(scanner_.literal_string(), | 4327 return GetSymbol(ok); |
4183 scanner_.literal_length()); | |
4184 } | 4328 } |
4185 | 4329 |
4186 | 4330 |
4187 // ---------------------------------------------------------------------------- | 4331 // ---------------------------------------------------------------------------- |
4188 // Parser support | 4332 // Parser support |
4189 | 4333 |
4190 | 4334 |
4191 bool Parser::TargetStackContainsLabel(Handle<String> label) { | 4335 bool Parser::TargetStackContainsLabel(Handle<String> label) { |
4192 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 4336 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
4193 BreakableStatement* stat = t->node()->AsBreakableStatement(); | 4337 BreakableStatement* stat = t->node()->AsBreakableStatement(); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4355 | 4499 |
4356 // Parse a JSON object. Scanner must be right after '{' token. | 4500 // Parse a JSON object. Scanner must be right after '{' token. |
4357 Expression* Parser::ParseJsonObject(bool* ok) { | 4501 Expression* Parser::ParseJsonObject(bool* ok) { |
4358 Consume(Token::LBRACE); | 4502 Consume(Token::LBRACE); |
4359 ZoneListWrapper<ObjectLiteral::Property> properties = | 4503 ZoneListWrapper<ObjectLiteral::Property> properties = |
4360 factory()->NewList<ObjectLiteral::Property>(4); | 4504 factory()->NewList<ObjectLiteral::Property>(4); |
4361 int boilerplate_properties = 0; | 4505 int boilerplate_properties = 0; |
4362 if (peek() != Token::RBRACE) { | 4506 if (peek() != Token::RBRACE) { |
4363 do { | 4507 do { |
4364 Expect(Token::STRING, CHECK_OK); | 4508 Expect(Token::STRING, CHECK_OK); |
4365 Handle<String> key = factory()->LookupSymbol(scanner_.literal_string(), | 4509 Handle<String> key = GetSymbol(CHECK_OK); |
4366 scanner_.literal_length()); | |
4367 Expect(Token::COLON, CHECK_OK); | 4510 Expect(Token::COLON, CHECK_OK); |
4368 Expression* value = ParseJsonValue(CHECK_OK); | 4511 Expression* value = ParseJsonValue(CHECK_OK); |
4369 Literal* key_literal; | 4512 Literal* key_literal; |
4370 uint32_t index; | 4513 uint32_t index; |
4371 if (key->AsArrayIndex(&index)) { | 4514 if (key->AsArrayIndex(&index)) { |
4372 key_literal = NewNumberLiteral(index); | 4515 key_literal = NewNumberLiteral(index); |
4373 } else { | 4516 } else { |
4374 key_literal = NEW(Literal(key)); | 4517 key_literal = NEW(Literal(key)); |
4375 } | 4518 } |
4376 ObjectLiteral::Property* property = | 4519 ObjectLiteral::Property* property = |
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5244 | 5387 |
5245 | 5388 |
5246 ParserMessage::~ParserMessage() { | 5389 ParserMessage::~ParserMessage() { |
5247 for (int i = 0; i < args().length(); i++) | 5390 for (int i = 0; i < args().length(); i++) |
5248 DeleteArray(args()[i]); | 5391 DeleteArray(args()[i]); |
5249 DeleteArray(args().start()); | 5392 DeleteArray(args().start()); |
5250 } | 5393 } |
5251 | 5394 |
5252 | 5395 |
5253 ScriptDataImpl::~ScriptDataImpl() { | 5396 ScriptDataImpl::~ScriptDataImpl() { |
5254 store_.Dispose(); | 5397 if (owns_store_) store_.Dispose(); |
5255 } | 5398 } |
5256 | 5399 |
5257 | 5400 |
5258 int ScriptDataImpl::Length() { | 5401 int ScriptDataImpl::Length() { |
5259 return store_.length() * sizeof(unsigned); | 5402 return store_.length() * sizeof(unsigned); |
5260 } | 5403 } |
5261 | 5404 |
5262 | 5405 |
5263 const char* ScriptDataImpl::Data() { | 5406 const char* ScriptDataImpl::Data() { |
5264 return reinterpret_cast<const char*>(store_.start()); | 5407 return reinterpret_cast<const char*>(store_.start()); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5358 parser.ParseLazy(script_source, name, | 5501 parser.ParseLazy(script_source, name, |
5359 start_position, end_position, is_expression); | 5502 start_position, end_position, is_expression); |
5360 return result; | 5503 return result; |
5361 } | 5504 } |
5362 | 5505 |
5363 | 5506 |
5364 #undef NEW | 5507 #undef NEW |
5365 | 5508 |
5366 | 5509 |
5367 } } // namespace v8::internal | 5510 } } // namespace v8::internal |
OLD | NEW |