Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(483)

Side by Side Diff: src/parser.cc

Issue 225753004: Remove the PreCompile API and ScriptData. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebased Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 result = scanner()->AllocateInternalizedString(isolate_); 217 result = scanner()->AllocateInternalizedString(isolate_);
218 ASSERT(!result.is_null()); 218 ASSERT(!result.is_null());
219 symbol_cache_.at(symbol_id) = result; 219 symbol_cache_.at(symbol_id) = result;
220 return result; 220 return result;
221 } 221 }
222 isolate()->counters()->total_preparse_symbols_skipped()->Increment(); 222 isolate()->counters()->total_preparse_symbols_skipped()->Increment();
223 return result; 223 return result;
224 } 224 }
225 225
226 226
227 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { 227 ScriptData* ScriptData::New(const char* data, int length) {
228 // The length is obviously invalid.
229 if (length % sizeof(unsigned) != 0) {
230 return new ScriptData();
231 }
232
233 int deserialized_data_length = length / sizeof(unsigned);
234 unsigned* deserialized_data;
235 ScriptData* script_data = new ScriptData();
236 script_data->owns_store_ =
237 reinterpret_cast<intptr_t>(data) % sizeof(unsigned) != 0;
238 if (script_data->owns_store_) {
239 // Copy the data to align it.
240 deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
241 i::CopyBytes(reinterpret_cast<char*>(deserialized_data),
242 data, static_cast<size_t>(length));
243 } else {
244 // If aligned, don't create a copy of the data.
245 deserialized_data = reinterpret_cast<unsigned*>(const_cast<char*>(data));
246 }
247 script_data->store_ =
248 Vector<unsigned>(deserialized_data, deserialized_data_length);
249 return script_data;
250 }
251
252
253 FunctionEntry ScriptData::GetFunctionEntry(int start) {
228 // The current pre-data entry must be a FunctionEntry with the given 254 // The current pre-data entry must be a FunctionEntry with the given
229 // start position. 255 // start position.
230 if ((function_index_ + FunctionEntry::kSize <= store_.length()) 256 if ((function_index_ + FunctionEntry::kSize <= store_.length())
231 && (static_cast<int>(store_[function_index_]) == start)) { 257 && (static_cast<int>(store_[function_index_]) == start)) {
232 int index = function_index_; 258 int index = function_index_;
233 function_index_ += FunctionEntry::kSize; 259 function_index_ += FunctionEntry::kSize;
234 return FunctionEntry(store_.SubVector(index, 260 return FunctionEntry(store_.SubVector(index,
235 index + FunctionEntry::kSize)); 261 index + FunctionEntry::kSize));
236 } 262 }
237 return FunctionEntry(); 263 return FunctionEntry();
238 } 264 }
239 265
240 266
241 int ScriptDataImpl::GetSymbolIdentifier() { 267 int ScriptData::GetSymbolIdentifier() {
242 return ReadNumber(&symbol_data_); 268 return ReadNumber(&symbol_data_);
243 } 269 }
244 270
245 271
246 bool ScriptDataImpl::SanityCheck() { 272 bool ScriptData::SanityCheck() {
247 // Check that the header data is valid and doesn't specify 273 // Check that the header data is valid and doesn't specify
248 // point to positions outside the store. 274 // point to positions outside the store.
249 if (store_.length() < PreparseDataConstants::kHeaderSize) return false; 275 if (store_.length() < PreparseDataConstants::kHeaderSize) return false;
250 if (magic() != PreparseDataConstants::kMagicNumber) return false; 276 if (magic() != PreparseDataConstants::kMagicNumber) return false;
251 if (version() != PreparseDataConstants::kCurrentVersion) return false; 277 if (version() != PreparseDataConstants::kCurrentVersion) return false;
252 if (has_error()) { 278 if (has_error()) {
253 // Extra sane sanity check for error message encoding. 279 // Extra sane sanity check for error message encoding.
254 if (store_.length() <= PreparseDataConstants::kHeaderSize 280 if (store_.length() <= PreparseDataConstants::kHeaderSize
255 + PreparseDataConstants::kMessageTextPos) { 281 + PreparseDataConstants::kMessageTextPos) {
256 return false; 282 return false;
(...skipping 28 matching lines...) Expand all
285 if (symbol_count < 0) return false; 311 if (symbol_count < 0) return false;
286 // Check that the total size has room for header and function entries. 312 // Check that the total size has room for header and function entries.
287 int minimum_size = 313 int minimum_size =
288 PreparseDataConstants::kHeaderSize + functions_size; 314 PreparseDataConstants::kHeaderSize + functions_size;
289 if (store_.length() < minimum_size) return false; 315 if (store_.length() < minimum_size) return false;
290 return true; 316 return true;
291 } 317 }
292 318
293 319
294 320
295 const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) { 321 const char* ScriptData::ReadString(unsigned* start, int* chars) {
296 int length = start[0]; 322 int length = start[0];
297 char* result = NewArray<char>(length + 1); 323 char* result = NewArray<char>(length + 1);
298 for (int i = 0; i < length; i++) { 324 for (int i = 0; i < length; i++) {
299 result[i] = start[i + 1]; 325 result[i] = start[i + 1];
300 } 326 }
301 result[length] = '\0'; 327 result[length] = '\0';
302 if (chars != NULL) *chars = length; 328 if (chars != NULL) *chars = length;
303 return result; 329 return result;
304 } 330 }
305 331
306 332
307 Scanner::Location ScriptDataImpl::MessageLocation() const { 333 Scanner::Location ScriptData::MessageLocation() const {
308 int beg_pos = Read(PreparseDataConstants::kMessageStartPos); 334 int beg_pos = Read(PreparseDataConstants::kMessageStartPos);
309 int end_pos = Read(PreparseDataConstants::kMessageEndPos); 335 int end_pos = Read(PreparseDataConstants::kMessageEndPos);
310 return Scanner::Location(beg_pos, end_pos); 336 return Scanner::Location(beg_pos, end_pos);
311 } 337 }
312 338
313 339
314 bool ScriptDataImpl::IsReferenceError() const { 340 bool ScriptData::IsReferenceError() const {
315 return Read(PreparseDataConstants::kIsReferenceErrorPos); 341 return Read(PreparseDataConstants::kIsReferenceErrorPos);
316 } 342 }
317 343
318 344
319 const char* ScriptDataImpl::BuildMessage() const { 345 const char* ScriptData::BuildMessage() const {
320 unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos); 346 unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos);
321 return ReadString(start, NULL); 347 return ReadString(start, NULL);
322 } 348 }
323 349
324 350
325 Vector<const char*> ScriptDataImpl::BuildArgs() const { 351 Vector<const char*> ScriptData::BuildArgs() const {
326 int arg_count = Read(PreparseDataConstants::kMessageArgCountPos); 352 int arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
327 const char** array = NewArray<const char*>(arg_count); 353 const char** array = NewArray<const char*>(arg_count);
328 // Position after text found by skipping past length field and 354 // Position after text found by skipping past length field and
329 // length field content words. 355 // length field content words.
330 int pos = PreparseDataConstants::kMessageTextPos + 1 356 int pos = PreparseDataConstants::kMessageTextPos + 1
331 + Read(PreparseDataConstants::kMessageTextPos); 357 + Read(PreparseDataConstants::kMessageTextPos);
332 for (int i = 0; i < arg_count; i++) { 358 for (int i = 0; i < arg_count; i++) {
333 int count = 0; 359 int count = 0;
334 array[i] = ReadString(ReadAddress(pos), &count); 360 array[i] = ReadString(ReadAddress(pos), &count);
335 pos += count + 1; 361 pos += count + 1;
336 } 362 }
337 return Vector<const char*>(array, arg_count); 363 return Vector<const char*>(array, arg_count);
338 } 364 }
339 365
340 366
341 unsigned ScriptDataImpl::Read(int position) const { 367 unsigned ScriptData::Read(int position) const {
342 return store_[PreparseDataConstants::kHeaderSize + position]; 368 return store_[PreparseDataConstants::kHeaderSize + position];
343 } 369 }
344 370
345 371
346 unsigned* ScriptDataImpl::ReadAddress(int position) const { 372 unsigned* ScriptData::ReadAddress(int position) const {
347 return &store_[PreparseDataConstants::kHeaderSize + position]; 373 return &store_[PreparseDataConstants::kHeaderSize + position];
348 } 374 }
349 375
350 376
351 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { 377 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) {
352 Scope* result = new(zone()) Scope(parent, scope_type, zone()); 378 Scope* result = new(zone()) Scope(parent, scope_type, zone());
353 result->Initialize(); 379 result->Initialize();
354 return result; 380 return result;
355 } 381 }
356 382
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 String* name = String::cast(info()->script()->name()); 909 String* name = String::cast(info()->script()->name());
884 SmartArrayPointer<char> name_chars = name->ToCString(); 910 SmartArrayPointer<char> name_chars = name->ToCString();
885 PrintF("[parsing script: %s", name_chars.get()); 911 PrintF("[parsing script: %s", name_chars.get());
886 } else { 912 } else {
887 PrintF("[parsing script"); 913 PrintF("[parsing script");
888 } 914 }
889 PrintF(" - took %0.3f ms]\n", ms); 915 PrintF(" - took %0.3f ms]\n", ms);
890 } 916 }
891 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { 917 if (cached_data_mode_ == PRODUCE_CACHED_DATA) {
892 Vector<unsigned> store = recorder.ExtractData(); 918 Vector<unsigned> store = recorder.ExtractData();
893 *cached_data_ = new ScriptDataImpl(store); 919 *cached_data_ = new ScriptData(store);
894 log_ = NULL; 920 log_ = NULL;
895 } 921 }
896 return result; 922 return result;
897 } 923 }
898 924
899 925
900 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, 926 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
901 Handle<String> source) { 927 Handle<String> source) {
902 ASSERT(scope_ == NULL); 928 ASSERT(scope_ == NULL);
903 ASSERT(target_stack_ == NULL); 929 ASSERT(target_stack_ == NULL);
(...skipping 3626 matching lines...) Expand 10 before | Expand all | Expand 10 after
4530 ranges->Add(CharacterRange::Everything(), zone()); 4556 ranges->Add(CharacterRange::Everything(), zone());
4531 is_negated = !is_negated; 4557 is_negated = !is_negated;
4532 } 4558 }
4533 return new(zone()) RegExpCharacterClass(ranges, is_negated); 4559 return new(zone()) RegExpCharacterClass(ranges, is_negated);
4534 } 4560 }
4535 4561
4536 4562
4537 // ---------------------------------------------------------------------------- 4563 // ----------------------------------------------------------------------------
4538 // The Parser interface. 4564 // The Parser interface.
4539 4565
4540 ScriptDataImpl::~ScriptDataImpl() { 4566 ScriptData::~ScriptData() {
4541 if (owns_store_) store_.Dispose(); 4567 if (owns_store_) store_.Dispose();
4542 } 4568 }
4543 4569
4544 4570
4545 int ScriptDataImpl::Length() { 4571 int ScriptData::Length() {
4546 return store_.length() * sizeof(unsigned); 4572 return store_.length() * sizeof(unsigned);
4547 } 4573 }
4548 4574
4549 4575
4550 const char* ScriptDataImpl::Data() { 4576 const char* ScriptData::Data() {
4551 return reinterpret_cast<const char*>(store_.start()); 4577 return reinterpret_cast<const char*>(store_.start());
4552 } 4578 }
4553 4579
4554 4580
4555 bool ScriptDataImpl::HasError() { 4581 bool ScriptData::HasError() {
4556 return has_error(); 4582 return has_error();
4557 } 4583 }
4558 4584
4559 4585
4560 void ScriptDataImpl::Initialize() { 4586 void ScriptData::Initialize() {
4561 // Prepares state for use. 4587 // Prepares state for use.
4562 if (store_.length() >= PreparseDataConstants::kHeaderSize) { 4588 if (store_.length() >= PreparseDataConstants::kHeaderSize) {
4563 function_index_ = PreparseDataConstants::kHeaderSize; 4589 function_index_ = PreparseDataConstants::kHeaderSize;
4564 int symbol_data_offset = PreparseDataConstants::kHeaderSize 4590 int symbol_data_offset = PreparseDataConstants::kHeaderSize
4565 + store_[PreparseDataConstants::kFunctionsSizeOffset]; 4591 + store_[PreparseDataConstants::kFunctionsSizeOffset];
4566 if (store_.length() > symbol_data_offset) { 4592 if (store_.length() > symbol_data_offset) {
4567 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]); 4593 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]);
4568 } else { 4594 } else {
4569 // Partial preparse causes no symbol information. 4595 // Partial preparse causes no symbol information.
4570 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); 4596 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
4571 } 4597 }
4572 symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); 4598 symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
4573 } 4599 }
4574 } 4600 }
4575 4601
4576 4602
4577 int ScriptDataImpl::ReadNumber(byte** source) { 4603 int ScriptData::ReadNumber(byte** source) {
4578 // Reads a number from symbol_data_ in base 128. The most significant 4604 // Reads a number from symbol_data_ in base 128. The most significant
4579 // bit marks that there are more digits. 4605 // bit marks that there are more digits.
4580 // If the first byte is 0x80 (kNumberTerminator), it would normally 4606 // If the first byte is 0x80 (kNumberTerminator), it would normally
4581 // represent a leading zero. Since that is useless, and therefore won't 4607 // represent a leading zero. Since that is useless, and therefore won't
4582 // appear as the first digit of any actual value, it is used to 4608 // appear as the first digit of any actual value, it is used to
4583 // mark the end of the input stream. 4609 // mark the end of the input stream.
4584 byte* data = *source; 4610 byte* data = *source;
4585 if (data >= symbol_data_end_) return -1; 4611 if (data >= symbol_data_end_) return -1;
4586 byte input = *data; 4612 byte input = *data;
4587 if (input == PreparseDataConstants::kNumberTerminator) { 4613 if (input == PreparseDataConstants::kNumberTerminator) {
4588 // End of stream marker. 4614 // End of stream marker.
4589 return -1; 4615 return -1;
4590 } 4616 }
4591 int result = input & 0x7f; 4617 int result = input & 0x7f;
4592 data++; 4618 data++;
4593 while ((input & 0x80u) != 0) { 4619 while ((input & 0x80u) != 0) {
4594 if (data >= symbol_data_end_) return -1; 4620 if (data >= symbol_data_end_) return -1;
4595 input = *data; 4621 input = *data;
4596 result = (result << 7) | (input & 0x7f); 4622 result = (result << 7) | (input & 0x7f);
4597 data++; 4623 data++;
4598 } 4624 }
4599 *source = data; 4625 *source = data;
4600 return result; 4626 return result;
4601 } 4627 }
4602 4628
4603 4629
4604 // Create a Scanner for the preparser to use as input, and preparse the source.
4605 ScriptDataImpl* PreParserApi::PreParse(Isolate* isolate,
4606 Utf16CharacterStream* source) {
4607 CompleteParserRecorder recorder;
4608 HistogramTimerScope timer(isolate->counters()->pre_parse());
4609 Scanner scanner(isolate->unicode_cache());
4610 intptr_t stack_limit = isolate->stack_guard()->real_climit();
4611 PreParser preparser(&scanner, &recorder, stack_limit);
4612 preparser.set_allow_lazy(true);
4613 preparser.set_allow_generators(FLAG_harmony_generators);
4614 preparser.set_allow_for_of(FLAG_harmony_iteration);
4615 preparser.set_allow_harmony_scoping(FLAG_harmony_scoping);
4616 preparser.set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
4617 scanner.Initialize(source);
4618 PreParser::PreParseResult result = preparser.PreParseProgram();
4619 if (result == PreParser::kPreParseStackOverflow) {
4620 isolate->StackOverflow();
4621 return NULL;
4622 }
4623
4624 // Extract the accumulated data from the recorder as a single
4625 // contiguous vector that we are responsible for disposing.
4626 Vector<unsigned> store = recorder.ExtractData();
4627 return new ScriptDataImpl(store);
4628 }
4629
4630
4631 bool RegExpParser::ParseRegExp(FlatStringReader* input, 4630 bool RegExpParser::ParseRegExp(FlatStringReader* input,
4632 bool multiline, 4631 bool multiline,
4633 RegExpCompileData* result, 4632 RegExpCompileData* result,
4634 Zone* zone) { 4633 Zone* zone) {
4635 ASSERT(result != NULL); 4634 ASSERT(result != NULL);
4636 RegExpParser parser(input, &result->error, multiline, zone); 4635 RegExpParser parser(input, &result->error, multiline, zone);
4637 RegExpTree* tree = parser.ParsePattern(); 4636 RegExpTree* tree = parser.ParsePattern();
4638 if (parser.failed()) { 4637 if (parser.failed()) {
4639 ASSERT(tree == NULL); 4638 ASSERT(tree == NULL);
4640 ASSERT(!result->error.is_null()); 4639 ASSERT(!result->error.is_null());
(...skipping 17 matching lines...) Expand all
4658 ASSERT(!info()->is_eval()); 4657 ASSERT(!info()->is_eval());
4659 if (info()->shared_info()->is_function()) { 4658 if (info()->shared_info()->is_function()) {
4660 result = ParseLazy(); 4659 result = ParseLazy();
4661 } else { 4660 } else {
4662 result = ParseProgram(); 4661 result = ParseProgram();
4663 } 4662 }
4664 } else { 4663 } else {
4665 SetCachedData(info()->cached_data(), info()->cached_data_mode()); 4664 SetCachedData(info()->cached_data(), info()->cached_data_mode());
4666 if (info()->cached_data_mode() == CONSUME_CACHED_DATA && 4665 if (info()->cached_data_mode() == CONSUME_CACHED_DATA &&
4667 (*info()->cached_data())->has_error()) { 4666 (*info()->cached_data())->has_error()) {
4668 ScriptDataImpl* cached_data = *(info()->cached_data()); 4667 ScriptData* cached_data = *(info()->cached_data());
4669 Scanner::Location loc = cached_data->MessageLocation(); 4668 Scanner::Location loc = cached_data->MessageLocation();
4670 const char* message = cached_data->BuildMessage(); 4669 const char* message = cached_data->BuildMessage();
4671 Vector<const char*> args = cached_data->BuildArgs(); 4670 Vector<const char*> args = cached_data->BuildArgs();
4672 ParserTraits::ReportMessageAt(loc, message, args, 4671 ParserTraits::ReportMessageAt(loc, message, args,
4673 cached_data->IsReferenceError()); 4672 cached_data->IsReferenceError());
4674 DeleteArray(message); 4673 DeleteArray(message);
4675 for (int i = 0; i < args.length(); i++) { 4674 for (int i = 0; i < args.length(); i++) {
4676 DeleteArray(args[i]); 4675 DeleteArray(args[i]);
4677 } 4676 }
4678 DeleteArray(args.start()); 4677 DeleteArray(args.start());
4679 ASSERT(info()->isolate()->has_pending_exception()); 4678 ASSERT(info()->isolate()->has_pending_exception());
4680 } else { 4679 } else {
4681 result = ParseProgram(); 4680 result = ParseProgram();
4682 } 4681 }
4683 } 4682 }
4684 info()->SetFunction(result); 4683 info()->SetFunction(result);
4685 return (result != NULL); 4684 return (result != NULL);
4686 } 4685 }
4687 4686
4688 } } // namespace v8::internal 4687 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698