Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 #include "runtime.h" | 42 #include "runtime.h" |
| 43 #include "scanner-character-streams.h" | 43 #include "scanner-character-streams.h" |
| 44 #include "scopeinfo.h" | 44 #include "scopeinfo.h" |
| 45 #include "string-stream.h" | 45 #include "string-stream.h" |
| 46 #include "scanner.h" | 46 #include "scanner.h" |
| 47 | 47 |
| 48 #include "experimental-scanner.h" | 48 #include "experimental-scanner.h" |
| 49 | 49 |
| 50 using namespace v8::internal; | 50 using namespace v8::internal; |
| 51 | 51 |
| 52 byte* ReadFile(const char* name, byte** end, int repeat, | 52 byte* ReadFile(const char* name, const byte** end, int repeat, |
| 53 bool convert_to_utf16) { | 53 bool convert_to_utf16) { |
| 54 FILE* file = fopen(name, "rb"); | 54 FILE* file = fopen(name, "rb"); |
| 55 if (file == NULL) return NULL; | 55 if (file == NULL) return NULL; |
| 56 | 56 |
| 57 fseek(file, 0, SEEK_END); | 57 fseek(file, 0, SEEK_END); |
| 58 int file_size = ftell(file); | 58 int file_size = ftell(file); |
| 59 rewind(file); | 59 rewind(file); |
| 60 | 60 |
| 61 int size = file_size * repeat; | 61 int size = file_size * repeat; |
| 62 | 62 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 102 | 102 |
| 103 struct HarmonySettings { | 103 struct HarmonySettings { |
| 104 bool numeric_literals; | 104 bool numeric_literals; |
| 105 bool modules; | 105 bool modules; |
| 106 bool scoping; | 106 bool scoping; |
| 107 HarmonySettings() : numeric_literals(false), modules(false), scoping(false) {} | 107 HarmonySettings() : numeric_literals(false), modules(false), scoping(false) {} |
| 108 }; | 108 }; |
| 109 | 109 |
| 110 class BaselineScanner { | 110 class BaselineScanner { |
| 111 public: | 111 public: |
| 112 BaselineScanner(const char* fname, | 112 BaselineScanner(const byte* source, |
| 113 const byte* source_end, | |
| 113 Isolate* isolate, | 114 Isolate* isolate, |
| 114 Encoding encoding, | 115 Encoding encoding, |
| 115 ElapsedTimer* timer, | 116 ElapsedTimer* timer, |
| 116 int repeat, | 117 int repeat, |
| 117 HarmonySettings harmony_settings) | 118 HarmonySettings harmony_settings) |
| 118 : stream_(NULL) { | 119 : source_(source), stream_(NULL) { |
| 119 byte* end = 0; | |
| 120 source_ = ReadFile(fname, &end, repeat, false); | |
| 121 unicode_cache_ = new UnicodeCache(); | 120 unicode_cache_ = new UnicodeCache(); |
| 122 scanner_ = new Scanner(unicode_cache_); | 121 scanner_ = new Scanner(unicode_cache_); |
| 123 scanner_->SetHarmonyNumericLiterals(harmony_settings.numeric_literals); | 122 scanner_->SetHarmonyNumericLiterals(harmony_settings.numeric_literals); |
| 124 scanner_->SetHarmonyModules(harmony_settings.modules); | 123 scanner_->SetHarmonyModules(harmony_settings.modules); |
| 125 scanner_->SetHarmonyScoping(harmony_settings.scoping); | 124 scanner_->SetHarmonyScoping(harmony_settings.scoping); |
| 126 switch (encoding) { | 125 switch (encoding) { |
| 127 case UTF8: | 126 case UTF8: |
| 128 case UTF8TO16: | 127 case UTF8TO16: |
| 129 stream_ = new Utf8ToUtf16CharacterStream(source_, end - source_); | 128 stream_ = new Utf8ToUtf16CharacterStream(source_, source_end - source_); |
| 130 break; | 129 break; |
| 131 case UTF16: { | 130 case UTF16: { |
| 132 Handle<String> result = isolate->factory()->NewStringFromTwoByte( | 131 Handle<String> result = isolate->factory()->NewStringFromTwoByte( |
| 133 Vector<const uint16_t>( | 132 Vector<const uint16_t>( |
| 134 reinterpret_cast<const uint16_t*>(source_), | 133 reinterpret_cast<const uint16_t*>(source_), |
| 135 (end - source_) / 2)); | 134 (source_end - source_) / 2)); |
| 136 stream_ = | 135 stream_ = |
| 137 new GenericStringUtf16CharacterStream(result, 0, result->length()); | 136 new GenericStringUtf16CharacterStream(result, 0, result->length()); |
| 138 break; | 137 break; |
| 139 } | 138 } |
| 140 case LATIN1: { | 139 case LATIN1: { |
| 141 Handle<String> result = isolate->factory()->NewStringFromOneByte( | 140 Handle<String> result = isolate->factory()->NewStringFromOneByte( |
| 142 Vector<const uint8_t>(source_, end - source_)); | 141 Vector<const uint8_t>(source_, source_end - source_)); |
| 143 stream_ = | 142 stream_ = |
| 144 new GenericStringUtf16CharacterStream(result, 0, result->length()); | 143 new GenericStringUtf16CharacterStream(result, 0, result->length()); |
| 145 break; | 144 break; |
| 146 } | 145 } |
| 147 } | 146 } |
| 148 timer->Start(); | 147 timer->Start(); |
| 149 scanner_->Initialize(stream_); | 148 scanner_->Initialize(stream_); |
| 150 } | 149 } |
| 151 | 150 |
| 152 ~BaselineScanner() { | 151 ~BaselineScanner() { |
| 153 delete scanner_; | 152 delete scanner_; |
| 154 delete stream_; | 153 delete stream_; |
| 155 delete unicode_cache_; | 154 delete unicode_cache_; |
| 156 delete[] source_; | |
| 157 } | 155 } |
| 158 | 156 |
| 159 Scanner* scanner_; | 157 Scanner* scanner_; |
| 160 | 158 |
| 161 private: | 159 private: |
| 162 UnicodeCache* unicode_cache_; | 160 UnicodeCache* unicode_cache_; |
| 163 const byte* source_; | 161 const byte* source_; |
| 164 BufferedUtf16CharacterStream* stream_; | 162 BufferedUtf16CharacterStream* stream_; |
| 165 }; | 163 }; |
| 166 | 164 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 if (scanner->is_literal_ascii()) { | 228 if (scanner->is_literal_ascii()) { |
| 231 result.literal = ToStdVector(scanner->literal_ascii_string()); | 229 result.literal = ToStdVector(scanner->literal_ascii_string()); |
| 232 } else { | 230 } else { |
| 233 result.literal = ToStdVector(scanner->literal_utf16_string()); | 231 result.literal = ToStdVector(scanner->literal_utf16_string()); |
| 234 } | 232 } |
| 235 } | 233 } |
| 236 return result; | 234 return result; |
| 237 } | 235 } |
| 238 | 236 |
| 239 | 237 |
| 240 TimeDelta RunBaselineScanner(const char* fname, | 238 TimeDelta RunBaselineScanner(const byte* source, |
| 239 const byte* source_end, | |
| 241 Isolate* isolate, | 240 Isolate* isolate, |
| 242 Encoding encoding, | 241 Encoding encoding, |
| 243 bool dump_tokens, | 242 bool dump_tokens, |
| 244 std::vector<TokenWithLocation>* tokens, | 243 std::vector<TokenWithLocation>* tokens, |
| 245 int repeat, | 244 int repeat, |
| 246 HarmonySettings harmony_settings) { | 245 HarmonySettings harmony_settings) { |
| 247 ElapsedTimer timer; | 246 ElapsedTimer timer; |
| 248 BaselineScanner scanner( | 247 BaselineScanner scanner(source, |
| 249 fname, isolate, encoding, &timer, repeat, harmony_settings); | 248 source_end, |
| 249 isolate, | |
| 250 encoding, | |
| 251 &timer, | |
| 252 repeat, | |
| 253 harmony_settings); | |
| 250 Token::Value token; | 254 Token::Value token; |
| 251 do { | 255 do { |
| 252 token = scanner.scanner_->Next(); | 256 token = scanner.scanner_->Next(); |
| 253 if (dump_tokens) { | 257 if (dump_tokens) { |
| 254 tokens->push_back(GetTokenWithLocation(scanner.scanner_, token)); | 258 tokens->push_back(GetTokenWithLocation(scanner.scanner_, token)); |
| 255 } else if (HasLiteral(token)) { | 259 } else if (HasLiteral(token)) { |
| 256 if (scanner.scanner_->is_literal_ascii()) { | 260 if (scanner.scanner_->is_literal_ascii()) { |
| 257 scanner.scanner_->literal_ascii_string(); | 261 scanner.scanner_->literal_ascii_string(); |
| 258 } else { | 262 } else { |
| 259 scanner.scanner_->literal_utf16_string(); | 263 scanner.scanner_->literal_utf16_string(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 311 std::pair<TimeDelta, TimeDelta> ProcessFile( | 315 std::pair<TimeDelta, TimeDelta> ProcessFile( |
| 312 const char* fname, | 316 const char* fname, |
| 313 Encoding encoding, | 317 Encoding encoding, |
| 314 Isolate* isolate, | 318 Isolate* isolate, |
| 315 bool run_baseline, | 319 bool run_baseline, |
| 316 bool run_experimental, | 320 bool run_experimental, |
| 317 bool print_tokens, | 321 bool print_tokens, |
| 318 bool check_tokens, | 322 bool check_tokens, |
| 319 bool break_after_illegal, | 323 bool break_after_illegal, |
| 320 int repeat, | 324 int repeat, |
| 321 HarmonySettings harmony_settings) { | 325 HarmonySettings harmony_settings, |
| 326 int truncate_by, | |
| 327 bool* can_truncate) { | |
| 322 if (print_tokens) { | 328 if (print_tokens) { |
| 323 printf("Processing file %s\n", fname); | 329 printf("Processing file %s, truncating by %d bytes\n", fname, truncate_by); |
| 324 } | 330 } |
| 325 HandleScope handle_scope(isolate); | 331 HandleScope handle_scope(isolate); |
| 326 std::vector<TokenWithLocation> baseline_tokens, experimental_tokens; | 332 std::vector<TokenWithLocation> baseline_tokens, experimental_tokens; |
| 327 TimeDelta baseline_time, experimental_time; | 333 TimeDelta baseline_time, experimental_time; |
| 328 if (run_baseline) { | 334 if (run_baseline) { |
| 329 baseline_time = RunBaselineScanner( | 335 const byte* buffer_end = 0; |
| 330 fname, isolate, encoding, print_tokens || check_tokens, | 336 const byte* buffer = ReadFile(fname, &buffer_end, repeat, false); |
| 331 &baseline_tokens, repeat, harmony_settings); | 337 if (truncate_by > buffer_end - buffer) { |
| 338 *can_truncate = false; | |
| 339 } else { | |
| 340 buffer_end -= truncate_by; | |
| 341 baseline_time = RunBaselineScanner( | |
| 342 buffer, buffer_end, isolate, encoding, print_tokens || check_tokens, | |
| 343 &baseline_tokens, repeat, harmony_settings); | |
| 344 } | |
| 345 delete[] buffer; | |
| 332 } | 346 } |
| 333 if (run_experimental) { | 347 if (run_experimental) { |
| 334 Handle<String> source; | 348 Handle<String> source; |
| 335 byte* buffer_end = 0; | 349 const byte* buffer_end = 0; |
| 336 const byte* buffer = ReadFile(fname, &buffer_end, repeat, | 350 const byte* buffer = ReadFile(fname, &buffer_end, repeat, |
| 337 encoding == UTF8TO16); | 351 encoding == UTF8TO16); |
| 338 switch (encoding) { | 352 if (truncate_by > buffer_end - buffer) { |
| 339 case UTF8: | 353 *can_truncate = false; |
| 340 case LATIN1: | 354 } else { |
| 341 source = isolate->factory()->NewStringFromAscii( | 355 buffer_end -= truncate_by; |
| 342 Vector<const char>(reinterpret_cast<const char*>(buffer), | 356 switch (encoding) { |
| 343 buffer_end - buffer)); | 357 case UTF8: |
| 344 experimental_time = RunExperimentalScanner<uint8_t>( | 358 case LATIN1: |
| 345 source, isolate, encoding, print_tokens || check_tokens, | 359 source = isolate->factory()->NewStringFromAscii( |
| 346 &experimental_tokens, repeat, harmony_settings); | 360 Vector<const char>(reinterpret_cast<const char*>(buffer), |
| 347 break; | 361 buffer_end - buffer)); |
| 348 case UTF16: | |
| 349 case UTF8TO16: { | |
| 350 const uc16* buffer_16 = reinterpret_cast<const uc16*>(buffer); | |
| 351 const uc16* buffer_end_16 = reinterpret_cast<const uc16*>(buffer_end); | |
| 352 source = isolate->factory()->NewStringFromTwoByte( | |
| 353 Vector<const uc16>(buffer_16, buffer_end_16 - buffer_16)); | |
| 354 // If the string was just an expaneded one byte string, V8 detects it | |
| 355 // and doesn't store it as two byte. | |
| 356 if (!source->IsTwoByteRepresentation()) { | |
| 357 experimental_time = RunExperimentalScanner<uint8_t>( | 362 experimental_time = RunExperimentalScanner<uint8_t>( |
| 358 source, isolate, encoding, print_tokens || check_tokens, | 363 source, isolate, encoding, print_tokens || check_tokens, |
| 359 &experimental_tokens, repeat, harmony_settings); | 364 &experimental_tokens, repeat, harmony_settings); |
| 360 } else { | 365 break; |
| 361 experimental_time = RunExperimentalScanner<uint16_t>( | 366 case UTF16: |
| 362 source, isolate, encoding, print_tokens || check_tokens, | 367 case UTF8TO16: { |
| 363 &experimental_tokens, repeat, harmony_settings); | 368 const uc16* buffer_16 = reinterpret_cast<const uc16*>(buffer); |
| 369 const uc16* buffer_end_16 = reinterpret_cast<const uc16*>(buffer_end); | |
| 370 source = isolate->factory()->NewStringFromTwoByte( | |
| 371 Vector<const uc16>(buffer_16, buffer_end_16 - buffer_16)); | |
| 372 // If the string was just an expaneded one byte string, V8 detects it | |
| 373 // and doesn't store it as two byte. | |
| 374 if (!source->IsTwoByteRepresentation()) { | |
| 375 experimental_time = RunExperimentalScanner<uint8_t>( | |
| 376 source, isolate, encoding, print_tokens || check_tokens, | |
| 377 &experimental_tokens, repeat, harmony_settings); | |
| 378 } else { | |
| 379 experimental_time = RunExperimentalScanner<uint16_t>( | |
| 380 source, isolate, encoding, print_tokens || check_tokens, | |
| 381 &experimental_tokens, repeat, harmony_settings); | |
| 382 } | |
| 383 break; | |
| 364 } | 384 } |
| 365 break; | 385 default: |
| 386 printf("Encoding not supported by the experimental scanner\n"); | |
| 387 exit(1); | |
| 388 break; | |
| 366 } | 389 } |
| 367 default: | |
| 368 printf("Encoding not supported by the experimental scanner\n"); | |
| 369 exit(1); | |
| 370 break; | |
| 371 } | 390 } |
| 391 delete[] buffer; | |
| 372 } | 392 } |
| 373 if (print_tokens && !run_experimental) { | 393 if (print_tokens && !run_experimental) { |
| 374 PrintTokens("Baseline", baseline_tokens); | 394 PrintTokens("Baseline", baseline_tokens); |
| 375 } | 395 } |
| 376 if (print_tokens && !run_baseline) { | 396 if (print_tokens && !run_baseline) { |
| 377 PrintTokens("Experimental", experimental_tokens); | 397 PrintTokens("Experimental", experimental_tokens); |
| 378 } | 398 } |
| 379 if ((print_tokens || check_tokens) && run_baseline && run_experimental) { | 399 if ((print_tokens || check_tokens) && run_baseline && run_experimental) { |
| 380 if (print_tokens) { | 400 if (print_tokens) { |
| 381 printf("No of tokens in Baseline: %d\n", | 401 printf("No of tokens in Baseline: %d\n", |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 412 | 432 |
| 413 int main(int argc, char* argv[]) { | 433 int main(int argc, char* argv[]) { |
| 414 v8::V8::InitializeICU(); | 434 v8::V8::InitializeICU(); |
| 415 v8::V8::SetFlagsFromCommandLine(&argc, argv, true); | 435 v8::V8::SetFlagsFromCommandLine(&argc, argv, true); |
| 416 Encoding encoding = LATIN1; | 436 Encoding encoding = LATIN1; |
| 417 bool print_tokens = false; | 437 bool print_tokens = false; |
| 418 bool run_baseline = true; | 438 bool run_baseline = true; |
| 419 bool run_experimental = true; | 439 bool run_experimental = true; |
| 420 bool check_tokens = true; | 440 bool check_tokens = true; |
| 421 bool break_after_illegal = false; | 441 bool break_after_illegal = false; |
| 442 bool eos_test = false; | |
| 422 std::vector<std::string> fnames; | 443 std::vector<std::string> fnames; |
| 423 std::string benchmark; | 444 std::string benchmark; |
| 424 int repeat = 1; | 445 int repeat = 1; |
| 425 HarmonySettings harmony_settings; | 446 HarmonySettings harmony_settings; |
| 426 for (int i = 0; i < argc; ++i) { | 447 for (int i = 0; i < argc; ++i) { |
| 427 if (strcmp(argv[i], "--latin1") == 0) { | 448 if (strcmp(argv[i], "--latin1") == 0) { |
| 428 encoding = LATIN1; | 449 encoding = LATIN1; |
| 429 } else if (strcmp(argv[i], "--utf8") == 0) { | 450 } else if (strcmp(argv[i], "--utf8") == 0) { |
| 430 encoding = UTF8; | 451 encoding = UTF8; |
| 431 } else if (strcmp(argv[i], "--utf16") == 0) { | 452 } else if (strcmp(argv[i], "--utf16") == 0) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 444 break_after_illegal = true; | 465 break_after_illegal = true; |
| 445 } else if (strcmp(argv[i], "--use-harmony") == 0) { | 466 } else if (strcmp(argv[i], "--use-harmony") == 0) { |
| 446 harmony_settings.numeric_literals = true; | 467 harmony_settings.numeric_literals = true; |
| 447 harmony_settings.modules = true; | 468 harmony_settings.modules = true; |
| 448 harmony_settings.scoping = true; | 469 harmony_settings.scoping = true; |
| 449 } else if (strncmp(argv[i], "--benchmark=", 12) == 0) { | 470 } else if (strncmp(argv[i], "--benchmark=", 12) == 0) { |
| 450 benchmark = std::string(argv[i]).substr(12); | 471 benchmark = std::string(argv[i]).substr(12); |
| 451 } else if (strncmp(argv[i], "--repeat=", 9) == 0) { | 472 } else if (strncmp(argv[i], "--repeat=", 9) == 0) { |
| 452 std::string repeat_str = std::string(argv[i]).substr(9); | 473 std::string repeat_str = std::string(argv[i]).substr(9); |
| 453 repeat = atoi(repeat_str.c_str()); | 474 repeat = atoi(repeat_str.c_str()); |
| 475 } else if (strcmp(argv[i], "--eos-test") == 0) { | |
| 476 eos_test = true; | |
| 454 } else if (i > 0 && argv[i][0] != '-') { | 477 } else if (i > 0 && argv[i][0] != '-') { |
| 455 fnames.push_back(std::string(argv[i])); | 478 fnames.push_back(std::string(argv[i])); |
| 456 } | 479 } |
| 457 } | 480 } |
| 481 check_tokens = check_tokens && run_baseline && run_experimental; | |
| 458 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 482 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
| 459 { | 483 { |
| 460 v8::HandleScope handle_scope(isolate); | 484 v8::HandleScope handle_scope(isolate); |
| 461 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); | 485 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); |
| 462 v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global); | 486 v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global); |
| 463 ASSERT(!context.IsEmpty()); | 487 ASSERT(!context.IsEmpty()); |
| 464 { | 488 { |
| 465 v8::Context::Scope scope(context); | 489 v8::Context::Scope scope(context); |
| 466 Isolate* internal_isolate = Isolate::Current(); | 490 Isolate* internal_isolate = Isolate::Current(); |
| 467 double baseline_total = 0, experimental_total = 0; | 491 double baseline_total = 0, experimental_total = 0; |
| 468 for (size_t i = 0; i < fnames.size(); i++) { | 492 for (size_t i = 0; i < fnames.size(); i++) { |
| 469 std::pair<TimeDelta, TimeDelta> times; | 493 std::pair<TimeDelta, TimeDelta> times; |
| 470 check_tokens = check_tokens && run_baseline && run_experimental; | 494 bool can_truncate = eos_test; |
| 471 times = ProcessFile(fnames[i].c_str(), | 495 int truncate_by = 0; |
| 472 encoding, | 496 do { |
|
ulan
2014/01/24 12:57:39
for loop would be also possible here.
marja
2014/01/24 14:10:18
Done.
| |
| 473 internal_isolate, | 497 times = ProcessFile(fnames[i].c_str(), |
| 474 run_baseline, | 498 encoding, |
| 475 run_experimental, | 499 internal_isolate, |
| 476 print_tokens, | 500 run_baseline, |
| 477 check_tokens, | 501 run_experimental, |
| 478 break_after_illegal, | 502 print_tokens, |
| 479 repeat, | 503 check_tokens, |
| 480 harmony_settings); | 504 break_after_illegal, |
| 481 baseline_total += times.first.InMillisecondsF(); | 505 repeat, |
| 482 experimental_total += times.second.InMillisecondsF(); | 506 harmony_settings, |
| 507 truncate_by, | |
| 508 &can_truncate); | |
| 509 baseline_total += times.first.InMillisecondsF(); | |
| 510 experimental_total += times.second.InMillisecondsF(); | |
| 511 ++truncate_by; | |
| 512 } while (can_truncate); | |
| 483 } | 513 } |
| 484 if (run_baseline) { | 514 if (run_baseline) { |
| 485 printf("Baseline%s(RunTime): %.f ms\n", benchmark.c_str(), | 515 printf("Baseline%s(RunTime): %.f ms\n", benchmark.c_str(), |
| 486 baseline_total); | 516 baseline_total); |
| 487 } | 517 } |
| 488 if (run_experimental) { | 518 if (run_experimental) { |
| 489 if (benchmark.empty()) benchmark = "Experimental"; | 519 if (benchmark.empty()) benchmark = "Experimental"; |
| 490 printf("%s(RunTime): %.f ms\n", benchmark.c_str(), | 520 printf("%s(RunTime): %.f ms\n", benchmark.c_str(), |
| 491 experimental_total); | 521 experimental_total); |
| 492 } | 522 } |
| 493 } | 523 } |
| 494 } | 524 } |
| 495 v8::V8::Dispose(); | 525 v8::V8::Dispose(); |
| 496 return 0; | 526 return 0; |
| 497 } | 527 } |
| OLD | NEW |