4c0f559d23
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@15 260f80e4-7a28-3924-810f-c04153c831b5
258 lines
7.3 KiB
C++
258 lines
7.3 KiB
C++
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
#include "include/dart_api.h"
|
|
|
|
#include "bin/builtin.h"
|
|
#include "bin/file.h"
|
|
#include "bin/globals.h"
|
|
#include "bin/process_script.h"
|
|
|
|
// snapshot_buffer points to a snapshot if we link in a snapshot otherwise
|
|
// it is initialized to NULL.
|
|
extern const uint8_t* snapshot_buffer;
|
|
|
|
|
|
// Global state that indicates whether pprof symbol information is
|
|
// to be generated or not.
|
|
static const char* generate_pprof_symbols_filename = NULL;
|
|
|
|
|
|
static bool IsValidFlag(const char* name,
|
|
const char* prefix,
|
|
intptr_t prefix_length) {
|
|
intptr_t name_length = strlen(name);
|
|
return ((name_length > prefix_length) &&
|
|
(strncmp(name, prefix, prefix_length) == 0));
|
|
}
|
|
|
|
|
|
static const char* ProcessOption(const char* option, const char* name) {
|
|
const intptr_t length = strlen(name);
|
|
if (strncmp(option, name, length) == 0) {
|
|
return (option + length);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
static bool ProcessPprofOption(const char* option) {
|
|
const char* kProfOption = "--generate_pprof_symbols=";
|
|
generate_pprof_symbols_filename = ProcessOption(option, kProfOption);
|
|
return generate_pprof_symbols_filename != NULL;
|
|
}
|
|
|
|
|
|
// Parse out the command line arguments. Returns -1 if the arguments
|
|
// are incorrect, 0 otherwise.
|
|
static int ParseArguments(int argc,
|
|
char** argv,
|
|
CommandLineOptions* vm_options,
|
|
char** script_name,
|
|
CommandLineOptions* dart_options) {
|
|
const char* kPrefix = "--";
|
|
const intptr_t kPrefixLen = strlen(kPrefix);
|
|
|
|
// Skip the binary name.
|
|
int i = 1;
|
|
|
|
// Parse out the vm options.
|
|
while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) {
|
|
if (ProcessPprofOption(argv[i])) {
|
|
i += 1;
|
|
Dart_InitPprofSupport();
|
|
continue;
|
|
}
|
|
vm_options->AddArgument(argv[i]);
|
|
i += 1;
|
|
}
|
|
|
|
// Get the script name.
|
|
if (i < argc) {
|
|
*script_name = argv[i];
|
|
i += 1;
|
|
} else {
|
|
return -1;
|
|
}
|
|
|
|
// Parse out options to be passed to dart main.
|
|
while (i < argc) {
|
|
dart_options->AddArgument(argv[i]);
|
|
i += 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static void DumpPprofSymbolInfo() {
|
|
if (generate_pprof_symbols_filename != NULL) {
|
|
Dart_EnterScope();
|
|
File* pprof_file = File::OpenFile(generate_pprof_symbols_filename, true);
|
|
ASSERT(pprof_file != NULL);
|
|
void* buffer;
|
|
int buffer_size;
|
|
Dart_GetPprofSymbolInfo(&buffer, &buffer_size);
|
|
if (buffer_size > 0) {
|
|
ASSERT(buffer != NULL);
|
|
pprof_file->WriteFully(buffer, buffer_size);
|
|
}
|
|
delete pprof_file; // Closes the file.
|
|
Dart_ExitScope();
|
|
}
|
|
}
|
|
|
|
|
|
static void* MainIsolateInitCallback(void* data) {
|
|
const char* script_name = reinterpret_cast<const char*>(data);
|
|
Dart_Result result;
|
|
Dart_EnterScope();
|
|
|
|
// Load the specified script.
|
|
result = LoadScript(script_name);
|
|
if (!Dart_IsValidResult(result)) {
|
|
const char* err_msg = Dart_GetErrorCString(result);
|
|
fprintf(stderr, "Errors encountered while loading script: %s\n", err_msg);
|
|
Dart_ExitScope();
|
|
exit(255);
|
|
}
|
|
|
|
Dart_Handle library = Dart_GetResult(result);
|
|
if (!Dart_IsLibrary(library)) {
|
|
fprintf(stderr,
|
|
"Expected a library when loading script: %s",
|
|
script_name);
|
|
Dart_ExitScope();
|
|
exit(255);
|
|
}
|
|
Builtin_ImportLibrary(library);
|
|
// Setup the native resolver for built in library functions.
|
|
Builtin_SetNativeResolver();
|
|
|
|
Dart_ExitScope();
|
|
return data;
|
|
}
|
|
|
|
|
|
static void PrintUsage() {
|
|
fprintf(stderr,
|
|
"dart [<vm-flags>] <dart-script-file> [<dart-options>]\n");
|
|
}
|
|
|
|
|
|
static bool HasCompileAll(const CommandLineOptions& options) {
|
|
for (int i = 0; i < options.count(); i++) {
|
|
if (strcmp(options.GetArgument(i), "--compile_all") == 0) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
static void PrintObject(FILE* out, Dart_Handle object) {
|
|
Dart_Result result = Dart_ObjectToString(object);
|
|
if (Dart_IsValidResult(result)) {
|
|
Dart_Handle string = Dart_GetResult(result);
|
|
PrintString(out, string);
|
|
} else {
|
|
fprintf(out, "%s\n", Dart_GetErrorCString(result));
|
|
}
|
|
}
|
|
|
|
|
|
int main(int argc, char** argv) {
|
|
char* script_name;
|
|
CommandLineOptions vm_options(argc);
|
|
CommandLineOptions dart_options(argc);
|
|
|
|
// Parse command line arguments.
|
|
if (ParseArguments(argc,
|
|
argv,
|
|
&vm_options,
|
|
&script_name,
|
|
&dart_options) < 0) {
|
|
PrintUsage();
|
|
return 255;
|
|
}
|
|
|
|
// Initialize the Dart VM.
|
|
Dart_Initialize(vm_options.count(),
|
|
vm_options.arguments(),
|
|
MainIsolateInitCallback);
|
|
|
|
// Create an isolate. As a side effect, MainIsolateInitCallback
|
|
// gets called, which loads the scripts and libraries.
|
|
Dart_Isolate isolate = Dart_CreateIsolate(snapshot_buffer, script_name);
|
|
if (isolate == NULL) {
|
|
return 255;
|
|
}
|
|
|
|
Dart_EnterScope();
|
|
// TODO(asiva): Create a dart options object that can be accessed from
|
|
// dart code.
|
|
if (HasCompileAll(vm_options)) {
|
|
Dart_Result result = Dart_CompileAll();
|
|
if (!Dart_IsValidResult(result)) {
|
|
fprintf(stderr, "%s\n", Dart_GetErrorCString(result));
|
|
Dart_ExitScope();
|
|
Dart_ShutdownIsolate();
|
|
return 255; // Indicates we encountered an error.
|
|
}
|
|
}
|
|
|
|
// Lookup and invoke the top level main function.
|
|
Dart_Handle script_url = Dart_NewString(script_name);
|
|
Dart_Result result = Dart_LookupLibrary(script_url);
|
|
if (!Dart_IsValidResult(result)) {
|
|
fprintf(stderr, "%s\n", Dart_GetErrorCString(result));
|
|
Dart_ExitScope();
|
|
Dart_ShutdownIsolate();
|
|
return 255; // Indicates we encountered an error.
|
|
}
|
|
Dart_Handle library = Dart_GetResult(result);
|
|
result = Dart_InvokeStatic(library,
|
|
Dart_NewString(""),
|
|
Dart_NewString("main"),
|
|
0,
|
|
NULL);
|
|
|
|
if (Dart_IsValidResult(result)) {
|
|
Dart_Handle result_obj = Dart_GetResult(result);
|
|
if (Dart_ExceptionOccurred(result_obj)) {
|
|
// Print the exception object.
|
|
fprintf(stderr, "An unhandled exception has been thrown\n");
|
|
Dart_Result exception_result = Dart_GetException(result_obj);
|
|
assert(Dart_IsValidResult(exception_result));
|
|
PrintObject(stderr, Dart_GetResult(exception_result));
|
|
// Print the stack trace.
|
|
Dart_Result stacktrace = Dart_GetStacktrace(result_obj);
|
|
assert(Dart_IsValidResult(stacktrace));
|
|
PrintObject(stderr, Dart_GetResult(stacktrace));
|
|
fprintf(stderr, "\n");
|
|
Dart_ExitScope();
|
|
Dart_ShutdownIsolate();
|
|
return 255; // We had an unhandled exception, hence indicate an error.
|
|
}
|
|
} else {
|
|
fprintf(stderr, "%s\n", Dart_GetErrorCString(result));
|
|
Dart_ExitScope();
|
|
Dart_ShutdownIsolate();
|
|
return 255; // Indicates we encountered an error.
|
|
}
|
|
Dart_ExitScope();
|
|
// Keep handling messages until the last active receive port is closed.
|
|
Dart_RunLoop();
|
|
// Dump symbol information for the profiler.
|
|
DumpPprofSymbolInfo();
|
|
// Shutdown the isolate.
|
|
Dart_ShutdownIsolate();
|
|
return 0;
|
|
}
|