| Index: src/top.cc
|
| ===================================================================
|
| --- src/top.cc (revision 4596)
|
| +++ src/top.cc (working copy)
|
| @@ -337,7 +337,7 @@
|
| static StringStream* incomplete_message = NULL;
|
|
|
|
|
| -Handle<String> Top::StackTrace() {
|
| +Handle<String> Top::StackTraceString() {
|
| if (stack_trace_nesting_level == 0) {
|
| stack_trace_nesting_level++;
|
| HeapStringAllocator allocator;
|
| @@ -365,6 +365,90 @@
|
| }
|
|
|
|
|
| +Local<StackTrace> Top::CaptureCurrentStackTrace(
|
| + int frame_limit, StackTrace::StackTraceOptions options) {
|
| + v8::HandleScope scope;
|
| + // Ensure no negative values.
|
| + int limit = Max(frame_limit, 0);
|
| + Handle<JSArray> stackTrace = Factory::NewJSArray(frame_limit);
|
| + FixedArray* frames = FixedArray::cast(stackTrace->elements());
|
| +
|
| + Handle<String> column_key = Factory::LookupAsciiSymbol("column");
|
| + Handle<String> line_key = Factory::LookupAsciiSymbol("lineNumber");
|
| + Handle<String> script_key = Factory::LookupAsciiSymbol("scriptName");
|
| + Handle<String> function_key = Factory::LookupAsciiSymbol("functionName");
|
| + Handle<String> eval_key = Factory::LookupAsciiSymbol("isEval");
|
| + Handle<String> constructor_key = Factory::LookupAsciiSymbol("isConstructor");
|
| +
|
| + StackTraceFrameIterator it;
|
| + int frames_seen = 0;
|
| + while (!it.done() && (frames_seen < limit)) {
|
| + // Create a JSObject to hold the information for the StackFrame.
|
| + Handle<JSObject> stackFrame = Factory::NewJSObject(object_function());
|
| +
|
| + JavaScriptFrame* frame = it.frame();
|
| + JSFunction* fun(JSFunction::cast(frame->function()));
|
| + Script* script = Script::cast(fun->shared()->script());
|
| +
|
| + if (options & StackTrace::kLineNumber) {
|
| + int script_line_offset = script->line_offset()->value();
|
| + int position = frame->code()->SourcePosition(frame->pc());
|
| + int line_number = GetScriptLineNumber(Handle<Script>(script), position);
|
| +
|
| + if (options & StackTrace::kColumnOffset) {
|
| + Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
|
| + int start = (line_number == 0) ?
|
| + 0 : Smi::cast(line_ends->get(line_number - 1))->value() + 1;
|
| + int column_offset = position - start;
|
| + if (line_number == script_line_offset) {
|
| + // For the case where the code is on the same line as the script tag.
|
| + column_offset += script_line_offset;
|
| + }
|
| + SetProperty(stackFrame, column_key,
|
| + Handle<Smi>(Smi::FromInt(column_offset + 1)), NONE);
|
| + }
|
| + // Adjust the line_number by the offset in the parent resource.
|
| + line_number += script_line_offset;
|
| + SetProperty(stackFrame, line_key,
|
| + Handle<Smi>(Smi::FromInt(line_number + 1)), NONE);
|
| + }
|
| +
|
| + if (options & StackTrace::kScriptName) {
|
| + Handle<Object> script_name(script->name());
|
| + SetProperty(stackFrame, script_key, script_name, NONE);
|
| + }
|
| +
|
| + if (options & StackTrace::kFunctionName) {
|
| + Handle<Object> fun_name(fun->shared()->name());
|
| + if (!fun_name->IsString()) {
|
| + fun_name = Handle<Object>(fun->shared()->inferred_name());
|
| + }
|
| + SetProperty(stackFrame, function_key, fun_name, NONE);
|
| + }
|
| +
|
| + if (options & StackTrace::kIsEval) {
|
| + int type = Smi::cast(script->compilation_type())->value();
|
| + Handle<Object> is_eval = (type == Script::COMPILATION_TYPE_EVAL) ?
|
| + Factory::true_value() : Factory::false_value();
|
| + SetProperty(stackFrame, eval_key, is_eval, NONE);
|
| + }
|
| +
|
| + if (options & StackTrace::kIsConstructor) {
|
| + Handle<Object> is_constructor = (frame->IsConstructor()) ?
|
| + Factory::true_value() : Factory::false_value();
|
| + SetProperty(stackFrame, constructor_key, is_constructor, NONE);
|
| + }
|
| +
|
| + frames->set(frames_seen, *stackFrame);
|
| + frames_seen++;
|
| + it.Advance();
|
| + }
|
| +
|
| + stackTrace->set_length(Smi::FromInt(frames_seen));
|
| + return scope.Close(Utils::StackTraceToLocal(stackTrace));
|
| +}
|
| +
|
| +
|
| void Top::PrintStack() {
|
| if (stack_trace_nesting_level == 0) {
|
| stack_trace_nesting_level++;
|
| @@ -786,7 +870,7 @@
|
| // traces while the bootstrapper is active since the infrastructure
|
| // may not have been properly initialized.
|
| Handle<String> stack_trace;
|
| - if (FLAG_trace_exception) stack_trace = StackTrace();
|
| + if (FLAG_trace_exception) stack_trace = StackTraceString();
|
| message_obj = MessageHandler::MakeMessageObject("uncaught_exception",
|
| location, HandleVector<Object>(&exception_handle, 1), stack_trace);
|
| }
|
|
|