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 |