| 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 854 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 }; | 865 }; |
| 866 | 866 |
| 867 | 867 |
| 868 class ParserLog BASE_EMBEDDED { | 868 class ParserLog BASE_EMBEDDED { |
| 869 public: | 869 public: |
| 870 virtual ~ParserLog() { } | 870 virtual ~ParserLog() { } |
| 871 | 871 |
| 872 // Records the occurrence of a function. | 872 // Records the occurrence of a function. |
| 873 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) {} | 874 virtual void LogSymbol(int start, Vector<const char> symbol) {} |
| 875 virtual void LogError() { } |
| 875 // Return the current position in the function entry log. | 876 // Return the current position in the function entry log. |
| 876 virtual int function_position() { return 0; } | 877 virtual int function_position() { return 0; } |
| 877 virtual int symbol_position() { return 0; } | 878 virtual int symbol_position() { return 0; } |
| 878 virtual int symbol_ids() { return 0; } | 879 virtual int symbol_ids() { return 0; } |
| 879 virtual void LogError() { } | 880 virtual Vector<unsigned> ExtractData() { |
| 881 return Vector<unsigned>(); |
| 882 }; |
| 880 }; | 883 }; |
| 881 | 884 |
| 882 | 885 |
| 883 class AstBuildingParserFactory : public ParserFactory { | 886 class AstBuildingParserFactory : public ParserFactory { |
| 884 public: | 887 public: |
| 885 explicit AstBuildingParserFactory(int expected_symbols) | 888 explicit AstBuildingParserFactory(int expected_symbols) |
| 886 : ParserFactory(false), symbol_cache_(expected_symbols) { } | 889 : ParserFactory(false), symbol_cache_(expected_symbols) { } |
| 887 | 890 |
| 888 virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with); | 891 virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with); |
| 889 | 892 |
| 890 virtual Handle<String> LookupSymbol(int symbol_id, | 893 virtual Handle<String> LookupSymbol(int symbol_id, |
| 891 Vector<const char> string) { | 894 Vector<const char> string) { |
| 892 // If there is no preparse data, we have no simpler way to identify similar | 895 // Length of symbol cache is the number of identified symbols. |
| 893 // symbols. | 896 // If we are larger than that, or negative, it's not a cached symbol. |
| 894 if (symbol_id < 0) return Factory::LookupSymbol(string); | 897 // This might also happen if there is no preparser symbol data, even |
| 898 // if there is some preparser data. |
| 899 if (static_cast<unsigned>(symbol_id) |
| 900 >= static_cast<unsigned>(symbol_cache_.length())) { |
| 901 return Factory::LookupSymbol(string); |
| 902 } |
| 895 return LookupCachedSymbol(symbol_id, string); | 903 return LookupCachedSymbol(symbol_id, string); |
| 896 } | 904 } |
| 897 | 905 |
| 898 Handle<String> LookupCachedSymbol(int symbol_id, | 906 Handle<String> LookupCachedSymbol(int symbol_id, |
| 899 Vector<const char> string) { | 907 Vector<const char> string) { |
| 900 // Make sure the cache is large enough to hold the symbol identifier. | 908 // Make sure the cache is large enough to hold the symbol identifier. |
| 901 if (symbol_cache_.length() <= symbol_id) { | 909 if (symbol_cache_.length() <= symbol_id) { |
| 902 // Increase length to index + 1. | 910 // Increase length to index + 1. |
| 903 symbol_cache_.AddBlock(Handle<String>::null(), | 911 symbol_cache_.AddBlock(Handle<String>::null(), |
| 904 symbol_id + 1 - symbol_cache_.length()); | 912 symbol_id + 1 - symbol_cache_.length()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 926 int pos) { | 934 int pos) { |
| 927 return new Call(expression, arguments, pos); | 935 return new Call(expression, arguments, pos); |
| 928 } | 936 } |
| 929 | 937 |
| 930 virtual Statement* EmptyStatement(); | 938 virtual Statement* EmptyStatement(); |
| 931 private: | 939 private: |
| 932 List<Handle<String> > symbol_cache_; | 940 List<Handle<String> > symbol_cache_; |
| 933 }; | 941 }; |
| 934 | 942 |
| 935 | 943 |
| 936 class ParserRecorder: public ParserLog { | 944 // Record only functions. |
| 945 class PartialParserRecorder: public ParserLog { |
| 937 public: | 946 public: |
| 938 ParserRecorder(); | 947 PartialParserRecorder(); |
| 939 virtual FunctionEntry LogFunction(int start); | 948 virtual FunctionEntry LogFunction(int start); |
| 949 |
| 950 virtual int function_position() { return function_store_.size(); } |
| 951 |
| 952 virtual void LogError() { } |
| 953 |
| 954 virtual void LogMessage(Scanner::Location loc, |
| 955 const char* message, |
| 956 Vector<const char*> args); |
| 957 |
| 958 virtual Vector<unsigned> ExtractData() { |
| 959 int function_size = function_store_.size(); |
| 960 int total_size = ScriptDataImpl::kHeaderSize + function_size; |
| 961 Vector<unsigned> data = Vector<unsigned>::New(total_size); |
| 962 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size; |
| 963 preamble_[ScriptDataImpl::kSymbolCountOffset] = 0; |
| 964 memcpy(data.start(), preamble_, sizeof(preamble_)); |
| 965 int symbol_start = ScriptDataImpl::kHeaderSize + function_size; |
| 966 if (function_size > 0) { |
| 967 function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize, |
| 968 symbol_start)); |
| 969 } |
| 970 return data; |
| 971 } |
| 972 |
| 973 protected: |
| 974 bool has_error() { |
| 975 return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]); |
| 976 } |
| 977 |
| 978 void WriteString(Vector<const char> str); |
| 979 |
| 980 Collector<unsigned> function_store_; |
| 981 unsigned preamble_[ScriptDataImpl::kHeaderSize]; |
| 982 #ifdef DEBUG |
| 983 int prev_start; |
| 984 #endif |
| 985 }; |
| 986 |
| 987 |
| 988 // Record both functions and symbols. |
| 989 class CompleteParserRecorder: public PartialParserRecorder { |
| 990 public: |
| 991 CompleteParserRecorder(); |
| 992 |
| 940 virtual void LogSymbol(int start, Vector<const char> literal) { | 993 virtual void LogSymbol(int start, Vector<const char> literal) { |
| 941 int hash = vector_hash(literal); | 994 int hash = vector_hash(literal); |
| 942 HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true); | 995 HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true); |
| 943 int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); | 996 int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
| 944 if (id == 0) { | 997 if (id == 0) { |
| 945 // Put (symbol_id_ + 1) into entry and increment it. | 998 // Put (symbol_id_ + 1) into entry and increment it. |
| 946 symbol_id_++; | 999 symbol_id_++; |
| 947 entry->value = reinterpret_cast<void*>(symbol_id_); | 1000 entry->value = reinterpret_cast<void*>(symbol_id_); |
| 948 Vector<Vector<const char> > symbol = symbol_entries_.AddBlock(1, literal); | 1001 Vector<Vector<const char> > symbol = symbol_entries_.AddBlock(1, literal); |
| 949 entry->key = &symbol[0]; | 1002 entry->key = &symbol[0]; |
| 950 } else { | 1003 } else { |
| 951 // Log a reuse of an earlier seen symbol. | 1004 // Log a reuse of an earlier seen symbol. |
| 952 symbol_store_.Add(start); | 1005 symbol_store_.Add(start); |
| 953 symbol_store_.Add(id - 1); | 1006 symbol_store_.Add(id - 1); |
| 954 } | 1007 } |
| 955 } | 1008 } |
| 956 virtual void LogError() { } | 1009 |
| 957 virtual void LogMessage(Scanner::Location loc, | 1010 virtual Vector<unsigned> ExtractData() { |
| 958 const char* message, | |
| 959 Vector<const char*> args); | |
| 960 Vector<unsigned> ExtractData() { | |
| 961 int function_size = function_store_.size(); | 1011 int function_size = function_store_.size(); |
| 962 int symbol_size = symbol_store_.size(); | 1012 int symbol_size = symbol_store_.size(); |
| 963 int total_size = ScriptDataImpl::kHeaderSize + function_size + symbol_size; | 1013 int total_size = ScriptDataImpl::kHeaderSize + function_size + symbol_size; |
| 964 Vector<unsigned> data = Vector<unsigned>::New(total_size); | 1014 Vector<unsigned> data = Vector<unsigned>::New(total_size); |
| 965 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size; | 1015 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size; |
| 966 preamble_[ScriptDataImpl::kSymbolCountOffset] = symbol_id_; | 1016 preamble_[ScriptDataImpl::kSymbolCountOffset] = symbol_id_; |
| 967 memcpy(data.start(), preamble_, sizeof(preamble_)); | 1017 memcpy(data.start(), preamble_, sizeof(preamble_)); |
| 968 int symbol_start = ScriptDataImpl::kHeaderSize + function_size; | 1018 int symbol_start = ScriptDataImpl::kHeaderSize + function_size; |
| 969 if (function_size > 0) { | 1019 if (function_size > 0) { |
| 970 function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize, | 1020 function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize, |
| 971 symbol_start)); | 1021 symbol_start)); |
| 972 } | 1022 } |
| 973 if (symbol_size > 0) { | 1023 if (symbol_size > 0) { |
| 974 symbol_store_.WriteTo(data.SubVector(symbol_start, total_size)); | 1024 symbol_store_.WriteTo(data.SubVector(symbol_start, total_size)); |
| 975 } | 1025 } |
| 976 return data; | 1026 return data; |
| 977 } | 1027 } |
| 978 | 1028 |
| 979 virtual int function_position() { return function_store_.size(); } | |
| 980 virtual int symbol_position() { return symbol_store_.size(); } | 1029 virtual int symbol_position() { return symbol_store_.size(); } |
| 981 virtual int symbol_ids() { return symbol_id_; } | 1030 virtual int symbol_ids() { return symbol_id_; } |
| 982 private: | 1031 private: |
| 983 Collector<unsigned> function_store_; | |
| 984 Collector<unsigned> symbol_store_; | 1032 Collector<unsigned> symbol_store_; |
| 985 Collector<Vector<const char> > symbol_entries_; | 1033 Collector<Vector<const char> > symbol_entries_; |
| 986 HashMap symbol_table_; | 1034 HashMap symbol_table_; |
| 987 int symbol_id_; | 1035 int symbol_id_; |
| 988 | 1036 |
| 989 static int vector_hash(Vector<const char> string) { | 1037 static int vector_hash(Vector<const char> string) { |
| 990 int hash = 0; | 1038 int hash = 0; |
| 991 for (int i = 0; i < string.length(); i++) { | 1039 for (int i = 0; i < string.length(); i++) { |
| 992 int c = string[i]; | 1040 int c = string[i]; |
| 993 hash += c; | 1041 hash += c; |
| 994 hash += (hash << 10); | 1042 hash += (hash << 10); |
| 995 hash ^= (hash >> 6); | 1043 hash ^= (hash >> 6); |
| 996 } | 1044 } |
| 997 return hash; | 1045 return hash; |
| 998 } | 1046 } |
| 999 | 1047 |
| 1000 static bool vector_compare(void* a, void* b) { | 1048 static bool vector_compare(void* a, void* b) { |
| 1001 Vector<const char>* string1 = reinterpret_cast<Vector<const char>* >(a); | 1049 Vector<const char>* string1 = reinterpret_cast<Vector<const char>* >(a); |
| 1002 Vector<const char>* string2 = reinterpret_cast<Vector<const char>* >(b); | 1050 Vector<const char>* string2 = reinterpret_cast<Vector<const char>* >(b); |
| 1003 int length = string1->length(); | 1051 int length = string1->length(); |
| 1004 if (string2->length() != length) return false; | 1052 if (string2->length() != length) return false; |
| 1005 return memcmp(string1->start(), string2->start(), length) == 0; | 1053 return memcmp(string1->start(), string2->start(), length) == 0; |
| 1006 } | 1054 } |
| 1007 | |
| 1008 unsigned preamble_[ScriptDataImpl::kHeaderSize]; | |
| 1009 #ifdef DEBUG | |
| 1010 int prev_start; | |
| 1011 #endif | |
| 1012 | |
| 1013 bool has_error() { | |
| 1014 return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]); | |
| 1015 } | |
| 1016 void WriteString(Vector<const char> str); | |
| 1017 }; | 1055 }; |
| 1018 | 1056 |
| 1019 | 1057 |
| 1020 void ScriptDataImpl::SkipFunctionEntry(int start) { | 1058 void ScriptDataImpl::SkipFunctionEntry(int start) { |
| 1021 ASSERT(function_index_ + FunctionEntry::kSize <= store_.length()); | 1059 ASSERT(function_index_ + FunctionEntry::kSize <= store_.length()); |
| 1022 ASSERT(static_cast<int>(store_[function_index_]) == start); | 1060 ASSERT(static_cast<int>(store_[function_index_]) == start); |
| 1023 function_index_ += FunctionEntry::kSize; | 1061 function_index_ += FunctionEntry::kSize; |
| 1024 } | 1062 } |
| 1025 | 1063 |
| 1026 | 1064 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1081 static_cast<int>(store_[ScriptDataImpl::kSymbolCountOffset]); | 1119 static_cast<int>(store_[ScriptDataImpl::kSymbolCountOffset]); |
| 1082 if (symbol_count < 0) return false; | 1120 if (symbol_count < 0) return false; |
| 1083 // Check that the total size has room both function entries. | 1121 // Check that the total size has room both function entries. |
| 1084 int minimum_size = | 1122 int minimum_size = |
| 1085 ScriptDataImpl::kHeaderSize + functions_size; | 1123 ScriptDataImpl::kHeaderSize + functions_size; |
| 1086 if (store_.length() < minimum_size) return false; | 1124 if (store_.length() < minimum_size) return false; |
| 1087 return true; | 1125 return true; |
| 1088 } | 1126 } |
| 1089 | 1127 |
| 1090 | 1128 |
| 1091 ParserRecorder::ParserRecorder() | 1129 |
| 1092 : function_store_(0), | 1130 PartialParserRecorder::PartialParserRecorder() : function_store_(0) { |
| 1093 symbol_store_(0), | |
| 1094 symbol_entries_(0), | |
| 1095 symbol_table_(vector_compare), | |
| 1096 symbol_id_(0) { | |
| 1097 #ifdef DEBUG | |
| 1098 prev_start = -1; | |
| 1099 #endif | |
| 1100 preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber; | 1131 preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber; |
| 1101 preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion; | 1132 preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion; |
| 1102 preamble_[ScriptDataImpl::kHasErrorOffset] = false; | 1133 preamble_[ScriptDataImpl::kHasErrorOffset] = false; |
| 1103 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = 0; | 1134 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = 0; |
| 1104 preamble_[ScriptDataImpl::kSymbolCountOffset] = 0; | 1135 preamble_[ScriptDataImpl::kSymbolCountOffset] = 0; |
| 1105 preamble_[ScriptDataImpl::kSizeOffset] = 0; | 1136 preamble_[ScriptDataImpl::kSizeOffset] = 0; |
| 1106 ASSERT_EQ(6, ScriptDataImpl::kHeaderSize); | 1137 ASSERT_EQ(6, ScriptDataImpl::kHeaderSize); |
| 1138 #ifdef DEBUG |
| 1139 prev_start = -1; |
| 1140 #endif |
| 1107 } | 1141 } |
| 1108 | 1142 |
| 1109 | 1143 |
| 1110 void ParserRecorder::WriteString(Vector<const char> str) { | 1144 CompleteParserRecorder::CompleteParserRecorder() |
| 1145 : PartialParserRecorder(), |
| 1146 symbol_store_(0), |
| 1147 symbol_entries_(0), |
| 1148 symbol_table_(vector_compare), |
| 1149 symbol_id_(0) { |
| 1150 } |
| 1151 |
| 1152 |
| 1153 void PartialParserRecorder::WriteString(Vector<const char> str) { |
| 1111 function_store_.Add(str.length()); | 1154 function_store_.Add(str.length()); |
| 1112 for (int i = 0; i < str.length(); i++) { | 1155 for (int i = 0; i < str.length(); i++) { |
| 1113 function_store_.Add(str[i]); | 1156 function_store_.Add(str[i]); |
| 1114 } | 1157 } |
| 1115 } | 1158 } |
| 1116 | 1159 |
| 1117 | 1160 |
| 1118 const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) { | 1161 const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) { |
| 1119 int length = start[0]; | 1162 int length = start[0]; |
| 1120 char* result = NewArray<char>(length + 1); | 1163 char* result = NewArray<char>(length + 1); |
| 1121 for (int i = 0; i < length; i++) { | 1164 for (int i = 0; i < length; i++) { |
| 1122 result[i] = start[i + 1]; | 1165 result[i] = start[i + 1]; |
| 1123 } | 1166 } |
| 1124 result[length] = '\0'; | 1167 result[length] = '\0'; |
| 1125 if (chars != NULL) *chars = length; | 1168 if (chars != NULL) *chars = length; |
| 1126 return result; | 1169 return result; |
| 1127 } | 1170 } |
| 1128 | 1171 |
| 1129 | 1172 |
| 1130 void ParserRecorder::LogMessage(Scanner::Location loc, const char* message, | 1173 void PartialParserRecorder::LogMessage(Scanner::Location loc, |
| 1131 Vector<const char*> args) { | 1174 const char* message, |
| 1175 Vector<const char*> args) { |
| 1132 if (has_error()) return; | 1176 if (has_error()) return; |
| 1133 preamble_[ScriptDataImpl::kHasErrorOffset] = true; | 1177 preamble_[ScriptDataImpl::kHasErrorOffset] = true; |
| 1134 function_store_.Reset(); | 1178 function_store_.Reset(); |
| 1135 STATIC_ASSERT(ScriptDataImpl::kMessageStartPos == 0); | 1179 STATIC_ASSERT(ScriptDataImpl::kMessageStartPos == 0); |
| 1136 function_store_.Add(loc.beg_pos); | 1180 function_store_.Add(loc.beg_pos); |
| 1137 STATIC_ASSERT(ScriptDataImpl::kMessageEndPos == 1); | 1181 STATIC_ASSERT(ScriptDataImpl::kMessageEndPos == 1); |
| 1138 function_store_.Add(loc.end_pos); | 1182 function_store_.Add(loc.end_pos); |
| 1139 STATIC_ASSERT(ScriptDataImpl::kMessageArgCountPos == 2); | 1183 STATIC_ASSERT(ScriptDataImpl::kMessageArgCountPos == 2); |
| 1140 function_store_.Add(args.length()); | 1184 function_store_.Add(args.length()); |
| 1141 STATIC_ASSERT(ScriptDataImpl::kMessageTextPos == 3); | 1185 STATIC_ASSERT(ScriptDataImpl::kMessageTextPos == 3); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1176 unsigned ScriptDataImpl::Read(int position) { | 1220 unsigned ScriptDataImpl::Read(int position) { |
| 1177 return store_[ScriptDataImpl::kHeaderSize + position]; | 1221 return store_[ScriptDataImpl::kHeaderSize + position]; |
| 1178 } | 1222 } |
| 1179 | 1223 |
| 1180 | 1224 |
| 1181 unsigned* ScriptDataImpl::ReadAddress(int position) { | 1225 unsigned* ScriptDataImpl::ReadAddress(int position) { |
| 1182 return &store_[ScriptDataImpl::kHeaderSize + position]; | 1226 return &store_[ScriptDataImpl::kHeaderSize + position]; |
| 1183 } | 1227 } |
| 1184 | 1228 |
| 1185 | 1229 |
| 1186 FunctionEntry ParserRecorder::LogFunction(int start) { | 1230 FunctionEntry PartialParserRecorder::LogFunction(int start) { |
| 1187 #ifdef DEBUG | 1231 #ifdef DEBUG |
| 1188 ASSERT(start > prev_start); | 1232 ASSERT(start > prev_start); |
| 1189 prev_start = start; | 1233 prev_start = start; |
| 1190 #endif | 1234 #endif |
| 1191 if (has_error()) return FunctionEntry(); | 1235 if (has_error()) return FunctionEntry(); |
| 1192 FunctionEntry result(function_store_.AddBlock(FunctionEntry::kSize, 0)); | 1236 FunctionEntry result(function_store_.AddBlock(FunctionEntry::kSize, 0)); |
| 1193 result.set_start_pos(start); | 1237 result.set_start_pos(start); |
| 1194 return result; | 1238 return result; |
| 1195 } | 1239 } |
| 1196 | 1240 |
| 1197 | 1241 |
| 1198 class AstBuildingParser : public Parser { | 1242 class AstBuildingParser : public Parser { |
| 1199 public: | 1243 public: |
| 1200 AstBuildingParser(Handle<Script> script, bool allow_natives_syntax, | 1244 AstBuildingParser(Handle<Script> script, bool allow_natives_syntax, |
| 1201 v8::Extension* extension, ScriptDataImpl* pre_data) | 1245 v8::Extension* extension, ScriptDataImpl* pre_data) |
| 1202 : Parser(script, | 1246 : Parser(script, |
| 1203 allow_natives_syntax, | 1247 allow_natives_syntax, |
| 1204 extension, | 1248 extension, |
| 1205 PARSE, | 1249 PARSE, |
| 1206 factory(), | 1250 factory(), |
| 1207 log(), | 1251 log(), |
| 1208 pre_data), | 1252 pre_data), |
| 1209 factory_(pre_data ? pre_data->symbol_count() : 16) { } | 1253 factory_(pre_data ? pre_data->symbol_count() : 0) { } |
| 1210 virtual void ReportMessageAt(Scanner::Location loc, const char* message, | 1254 virtual void ReportMessageAt(Scanner::Location loc, const char* message, |
| 1211 Vector<const char*> args); | 1255 Vector<const char*> args); |
| 1212 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, | 1256 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, |
| 1213 FunctionLiteral* fun, bool resolve, bool* ok); | 1257 FunctionLiteral* fun, bool resolve, bool* ok); |
| 1214 AstBuildingParserFactory* factory() { return &factory_; } | 1258 AstBuildingParserFactory* factory() { return &factory_; } |
| 1215 ParserLog* log() { return &log_; } | 1259 ParserLog* log() { return &log_; } |
| 1216 | 1260 |
| 1217 private: | 1261 private: |
| 1218 ParserLog log_; | 1262 ParserLog log_; |
| 1219 AstBuildingParserFactory factory_; | 1263 AstBuildingParserFactory factory_; |
| 1220 }; | 1264 }; |
| 1221 | 1265 |
| 1222 | 1266 |
| 1223 class PreParser : public Parser { | 1267 class PreParser : public Parser { |
| 1224 public: | 1268 public: |
| 1225 PreParser(Handle<Script> script, bool allow_natives_syntax, | 1269 PreParser(Handle<Script> script, bool allow_natives_syntax, |
| 1226 v8::Extension* extension) | 1270 v8::Extension* extension, ParserLog* recorder) |
| 1227 : Parser(script, allow_natives_syntax, extension, PREPARSE, | 1271 : Parser(script, allow_natives_syntax, extension, PREPARSE, |
| 1228 factory(), recorder(), NULL), | 1272 factory(), recorder, NULL), |
| 1229 factory_(true) { } | 1273 factory_(true) { } |
| 1230 virtual void ReportMessageAt(Scanner::Location loc, const char* message, | 1274 virtual void ReportMessageAt(Scanner::Location loc, const char* message, |
| 1231 Vector<const char*> args); | 1275 Vector<const char*> args); |
| 1232 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, | 1276 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, |
| 1233 FunctionLiteral* fun, bool resolve, bool* ok); | 1277 FunctionLiteral* fun, bool resolve, bool* ok); |
| 1234 ParserFactory* factory() { return &factory_; } | 1278 ParserFactory* factory() { return &factory_; } |
| 1235 ParserRecorder* recorder() { return &recorder_; } | 1279 virtual PartialParserRecorder* recorder() = 0; |
| 1236 | 1280 |
| 1237 private: | 1281 private: |
| 1238 ParserRecorder recorder_; | |
| 1239 ParserFactory factory_; | 1282 ParserFactory factory_; |
| 1240 }; | 1283 }; |
| 1241 | 1284 |
| 1242 | 1285 |
| 1286 class CompletePreParser : public PreParser { |
| 1287 public: |
| 1288 CompletePreParser(Handle<Script> script, bool allow_natives_syntax, |
| 1289 v8::Extension* extension) |
| 1290 : PreParser(script, allow_natives_syntax, extension, &recorder_) { } |
| 1291 virtual PartialParserRecorder* recorder() { return &recorder_; } |
| 1292 private: |
| 1293 CompleteParserRecorder recorder_; |
| 1294 }; |
| 1295 |
| 1296 |
| 1297 class PartialPreParser : public PreParser { |
| 1298 public: |
| 1299 PartialPreParser(Handle<Script> script, bool allow_natives_syntax, |
| 1300 v8::Extension* extension) |
| 1301 : PreParser(script, allow_natives_syntax, extension, &recorder_) { } |
| 1302 virtual PartialParserRecorder* recorder() { return &recorder_; } |
| 1303 private: |
| 1304 PartialParserRecorder recorder_; |
| 1305 }; |
| 1306 |
| 1307 |
| 1243 Scope* AstBuildingParserFactory::NewScope(Scope* parent, Scope::Type type, | 1308 Scope* AstBuildingParserFactory::NewScope(Scope* parent, Scope::Type type, |
| 1244 bool inside_with) { | 1309 bool inside_with) { |
| 1245 Scope* result = new Scope(parent, type); | 1310 Scope* result = new Scope(parent, type); |
| 1246 result->Initialize(inside_with); | 1311 result->Initialize(inside_with); |
| 1247 return result; | 1312 return result; |
| 1248 } | 1313 } |
| 1249 | 1314 |
| 1250 | 1315 |
| 1251 Statement* AstBuildingParserFactory::EmptyStatement() { | 1316 Statement* AstBuildingParserFactory::EmptyStatement() { |
| 1252 // Use a statically allocated empty statement singleton to avoid | 1317 // Use a statically allocated empty statement singleton to avoid |
| (...skipping 4153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5406 const char* ScriptDataImpl::Data() { | 5471 const char* ScriptDataImpl::Data() { |
| 5407 return reinterpret_cast<const char*>(store_.start()); | 5472 return reinterpret_cast<const char*>(store_.start()); |
| 5408 } | 5473 } |
| 5409 | 5474 |
| 5410 | 5475 |
| 5411 bool ScriptDataImpl::HasError() { | 5476 bool ScriptDataImpl::HasError() { |
| 5412 return has_error(); | 5477 return has_error(); |
| 5413 } | 5478 } |
| 5414 | 5479 |
| 5415 | 5480 |
| 5481 // Preparse, but only collect data that is immediately useful, |
| 5482 // even if the preparser data is only used once. |
| 5483 ScriptDataImpl* PartialPreParse(Handle<String> source, |
| 5484 unibrow::CharacterStream* stream, |
| 5485 v8::Extension* extension) { |
| 5486 Handle<Script> no_script; |
| 5487 bool allow_natives_syntax = |
| 5488 always_allow_natives_syntax || |
| 5489 FLAG_allow_natives_syntax || |
| 5490 Bootstrapper::IsActive(); |
| 5491 PartialPreParser parser(no_script, allow_natives_syntax, extension); |
| 5492 if (!parser.PreParseProgram(source, stream)) return NULL; |
| 5493 // Extract the accumulated data from the recorder as a single |
| 5494 // contiguous vector that we are responsible for disposing. |
| 5495 Vector<unsigned> store = parser.recorder()->ExtractData(); |
| 5496 return new ScriptDataImpl(store); |
| 5497 } |
| 5498 |
| 5499 |
| 5416 ScriptDataImpl* PreParse(Handle<String> source, | 5500 ScriptDataImpl* PreParse(Handle<String> source, |
| 5417 unibrow::CharacterStream* stream, | 5501 unibrow::CharacterStream* stream, |
| 5418 v8::Extension* extension) { | 5502 v8::Extension* extension) { |
| 5419 Handle<Script> no_script; | 5503 Handle<Script> no_script; |
| 5420 bool allow_natives_syntax = | 5504 bool allow_natives_syntax = |
| 5421 always_allow_natives_syntax || | 5505 always_allow_natives_syntax || |
| 5422 FLAG_allow_natives_syntax || | 5506 FLAG_allow_natives_syntax || |
| 5423 Bootstrapper::IsActive(); | 5507 Bootstrapper::IsActive(); |
| 5424 PreParser parser(no_script, allow_natives_syntax, extension); | 5508 CompletePreParser parser(no_script, allow_natives_syntax, extension); |
| 5425 if (!parser.PreParseProgram(source, stream)) return NULL; | 5509 if (!parser.PreParseProgram(source, stream)) return NULL; |
| 5426 // Extract the accumulated data from the recorder as a single | 5510 // Extract the accumulated data from the recorder as a single |
| 5427 // contiguous vector that we are responsible for disposing. | 5511 // contiguous vector that we are responsible for disposing. |
| 5428 Vector<unsigned> store = parser.recorder()->ExtractData(); | 5512 Vector<unsigned> store = parser.recorder()->ExtractData(); |
| 5429 return new ScriptDataImpl(store); | 5513 return new ScriptDataImpl(store); |
| 5430 } | 5514 } |
| 5431 | 5515 |
| 5432 | 5516 |
| 5433 bool ParseRegExp(FlatStringReader* input, | 5517 bool ParseRegExp(FlatStringReader* input, |
| 5434 bool multiline, | 5518 bool multiline, |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5501 parser.ParseLazy(script_source, name, | 5585 parser.ParseLazy(script_source, name, |
| 5502 start_position, end_position, is_expression); | 5586 start_position, end_position, is_expression); |
| 5503 return result; | 5587 return result; |
| 5504 } | 5588 } |
| 5505 | 5589 |
| 5506 | 5590 |
| 5507 #undef NEW | 5591 #undef NEW |
| 5508 | 5592 |
| 5509 | 5593 |
| 5510 } } // namespace v8::internal | 5594 } } // namespace v8::internal |
| OLD | NEW |