OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 is_global.location() }; | 497 is_global.location() }; |
498 bool caught_exception = false; | 498 bool caught_exception = false; |
499 Handle<Object> result = TryCall(Top::get_stack_trace_line_fun(), | 499 Handle<Object> result = TryCall(Top::get_stack_trace_line_fun(), |
500 Top::builtins(), argc, args, | 500 Top::builtins(), argc, args, |
501 &caught_exception); | 501 &caught_exception); |
502 if (caught_exception || !result->IsString()) return Factory::empty_symbol(); | 502 if (caught_exception || !result->IsString()) return Factory::empty_symbol(); |
503 return Handle<String>::cast(result); | 503 return Handle<String>::cast(result); |
504 } | 504 } |
505 | 505 |
506 | 506 |
507 // --- P r i n t E x t e n s i o n --- | |
508 | |
509 const char* PrintExtension::kSource = "native function print();"; | |
510 | |
511 | |
512 v8::Handle<v8::FunctionTemplate> PrintExtension::GetNativeFunction( | |
513 v8::Handle<v8::String> str) { | |
514 return v8::FunctionTemplate::New(PrintExtension::Print); | |
515 } | |
516 | |
517 | |
518 v8::Handle<v8::Value> PrintExtension::Print(const v8::Arguments& args) { | |
519 for (int i = 0; i < args.Length(); i++) { | |
520 if (i != 0) printf(" "); | |
521 v8::HandleScope scope; | |
522 v8::Handle<v8::Value> arg = args[i]; | |
523 v8::Handle<v8::String> string_obj = arg->ToString(); | |
524 if (string_obj.IsEmpty()) return string_obj; | |
525 int length = string_obj->Length(); | |
526 uint16_t* string = NewArray<uint16_t>(length + 1); | |
527 string_obj->Write(string); | |
528 for (int j = 0; j < length; j++) | |
529 printf("%lc", string[j]); | |
530 DeleteArray(string); | |
531 } | |
532 printf("\n"); | |
533 return v8::Undefined(); | |
534 } | |
535 | |
536 | |
537 static PrintExtension kPrintExtension; | |
538 v8::DeclareExtension kPrintExtensionDeclaration(&kPrintExtension); | |
539 | |
540 | |
541 // --- L o a d E x t e n s i o n --- | |
542 | |
543 const char* LoadExtension::kSource = "native function load();"; | |
544 | |
545 | |
546 v8::Handle<v8::FunctionTemplate> LoadExtension::GetNativeFunction( | |
547 v8::Handle<v8::String> str) { | |
548 return v8::FunctionTemplate::New(LoadExtension::Load); | |
549 } | |
550 | |
551 | |
552 v8::Handle<v8::Value> LoadExtension::Load(const v8::Arguments& args) { | |
553 v8::Handle<v8::String> path = args[0]->ToString(); | |
554 | |
555 // Create a handle for the result. Keep the result empty to be | |
556 // useful as the return value in case of exceptions. | |
557 v8::Handle<Value> result; | |
558 | |
559 if (path.IsEmpty()) return result; // Exception was thrown in ToString. | |
560 | |
561 // Check that the length of the file name is within bounds. | |
562 static const int kMaxPathLength = 255; | |
563 if (path->Length() > kMaxPathLength) { | |
564 v8::Handle<v8::String> message = v8::String::New("Path name too long"); | |
565 v8::ThrowException(v8::Exception::RangeError(message)); | |
566 return result; | |
567 } | |
568 | |
569 // Convert the JavaScript string path into a C string and read the | |
570 // corresponding script from the file system. | |
571 char path_buffer[kMaxPathLength + 1]; | |
572 path->WriteAscii(path_buffer); | |
573 bool exists; | |
574 Vector<const char> script = ReadFile(path_buffer, &exists, false); | |
575 | |
576 // Find the base file name from the path. | |
577 char* file_name_buffer = path_buffer; | |
578 for (char* p = path_buffer; *p; p++) { | |
579 if (*p == '/' || *p == '\\') file_name_buffer = p + 1; | |
580 } | |
581 | |
582 // Throw an exception in case the script couldn't be read. | |
583 if (script.is_empty()) { | |
584 static const char* kErrorPrefix = "Unable to read from file "; | |
585 static const size_t kErrorPrefixLength = 25; // strlen is not constant | |
586 ASSERT(strlen(kErrorPrefix) == kErrorPrefixLength); | |
587 static const int kMaxErrorLength = kMaxPathLength + kErrorPrefixLength; | |
588 EmbeddedVector<char, kMaxErrorLength + 1> error_buffer; | |
589 OS::SNPrintF(error_buffer, "%s%s", kErrorPrefix, file_name_buffer); | |
590 v8::Handle<v8::String> error = | |
591 v8::String::New(error_buffer.start(), error_buffer.length()); | |
592 v8::ThrowException(v8::Exception::Error(error)); | |
593 return result; | |
594 } | |
595 | |
596 // Convert the file name buffer into a script origin | |
597 v8::ScriptOrigin origin = | |
598 v8::ScriptOrigin(v8::String::New(file_name_buffer)); | |
599 | |
600 // Compile and run script. | |
601 v8::Handle<v8::String> source = | |
602 v8::String::New(script.start(), script.length()); | |
603 v8::Handle<v8::Script> code = | |
604 v8::Script::Compile(source, &origin); | |
605 | |
606 // Run the code if no exception occurred during the compilation. In | |
607 // case of syntax errors, the code is empty and the exception is | |
608 // scheduled and will be thrown when returning to JavaScript. | |
609 if (!code.IsEmpty()) result = code->Run(); | |
610 script.Dispose(); | |
611 return result; | |
612 } | |
613 | |
614 | |
615 static LoadExtension kLoadExtension; | |
616 v8::DeclareExtension kLoadExtensionDeclaration(&kLoadExtension); | |
617 | |
618 | |
619 // --- Q u i t E x t e n s i o n --- | |
620 | |
621 const char* QuitExtension::kSource = "native function quit();"; | |
622 | |
623 | |
624 v8::Handle<v8::FunctionTemplate> QuitExtension::GetNativeFunction( | |
625 v8::Handle<v8::String> str) { | |
626 return v8::FunctionTemplate::New(QuitExtension::Quit); | |
627 } | |
628 | |
629 | |
630 v8::Handle<v8::Value> QuitExtension::Quit(const v8::Arguments& args) { | |
631 exit(args.Length() == 0 ? 0 : args[0]->Int32Value()); | |
632 return v8::Undefined(); | |
633 } | |
634 | |
635 | |
636 static QuitExtension kQuitExtension; | |
637 v8::DeclareExtension kQuitExtensionDeclaration(&kQuitExtension); | |
638 | |
639 | |
640 // --- V e r s i o n E x t e n s i o n --- | |
641 | |
642 static Extension kVersionExtension("v8/version", | |
643 "function version(){ return 150; }"); | |
644 v8::DeclareExtension kVersionExtensionDeclaration(&kVersionExtension); | |
645 | |
646 | |
647 // --- G C E x t e n s i o n --- | 507 // --- G C E x t e n s i o n --- |
648 | 508 |
649 const char* GCExtension::kSource = "native function gc();"; | 509 const char* GCExtension::kSource = "native function gc();"; |
650 | 510 |
651 | 511 |
652 v8::Handle<v8::FunctionTemplate> GCExtension::GetNativeFunction( | 512 v8::Handle<v8::FunctionTemplate> GCExtension::GetNativeFunction( |
653 v8::Handle<v8::String> str) { | 513 v8::Handle<v8::String> str) { |
654 return v8::FunctionTemplate::New(GCExtension::GC); | 514 return v8::FunctionTemplate::New(GCExtension::GC); |
655 } | 515 } |
656 | 516 |
657 | 517 |
658 v8::Handle<v8::Value> GCExtension::GC(const v8::Arguments& args) { | 518 v8::Handle<v8::Value> GCExtension::GC(const v8::Arguments& args) { |
659 // All allocation spaces other than NEW_SPACE have the same effect. | 519 // All allocation spaces other than NEW_SPACE have the same effect. |
660 Heap::CollectGarbage(0, OLD_DATA_SPACE); | 520 Heap::CollectGarbage(0, OLD_DATA_SPACE); |
661 return v8::Undefined(); | 521 return v8::Undefined(); |
662 } | 522 } |
663 | 523 |
664 | 524 |
665 static GCExtension kGCExtension; | 525 static GCExtension kGCExtension; |
666 v8::DeclareExtension kGCExtensionDeclaration(&kGCExtension); | 526 v8::DeclareExtension kGCExtensionDeclaration(&kGCExtension); |
667 | 527 |
668 } } // namespace v8::internal | 528 } } // namespace v8::internal |
OLD | NEW |