diff --git a/src/frames.cc b/src/frames.cc index 2f90a316e1..f6c07bd971 100644 --- a/src/frames.cc +++ b/src/frames.cc @@ -176,7 +176,7 @@ StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type) { StackTraceFrameIterator::StackTraceFrameIterator() { - if (!done() && !frame()->function()->IsJSFunction()) Advance(); + if (!done() && !IsValidFrame()) Advance(); } @@ -184,10 +184,18 @@ void StackTraceFrameIterator::Advance() { while (true) { JavaScriptFrameIterator::Advance(); if (done()) return; - if (frame()->function()->IsJSFunction()) return; + if (IsValidFrame()) return; } } +bool StackTraceFrameIterator::IsValidFrame() { + if (!frame()->function()->IsJSFunction()) return false; + Object* script = JSFunction::cast(frame()->function())->shared()->script(); + // Don't show functions from native scripts to user. + return (script->IsScript() && + Script::TYPE_NATIVE != Script::cast(script)->type()->value()); +} + // ------------------------------------------------------------------------- diff --git a/src/frames.h b/src/frames.h index 19860adba7..8cbbc62679 100644 --- a/src/frames.h +++ b/src/frames.h @@ -589,6 +589,9 @@ class StackTraceFrameIterator: public JavaScriptFrameIterator { public: StackTraceFrameIterator(); void Advance(); + + private: + bool IsValidFrame(); }; diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 02b4dbbab4..e47855196b 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -3602,6 +3602,37 @@ TEST(ApiUncaughtException) { v8::V8::RemoveMessageListeners(ApiUncaughtExceptionTestListener); } +static const char* script_resource_name = "ExceptionInNativeScript.js"; +static void ExceptionInNativeScriptTestListener(v8::Handle message, + v8::Handle) { + v8::Handle name_val = message->GetScriptResourceName(); + CHECK(!name_val.IsEmpty() && name_val->IsString()); + v8::String::AsciiValue name(message->GetScriptResourceName()); + CHECK_EQ(script_resource_name, *name); + CHECK_EQ(3, message->GetLineNumber()); + v8::String::AsciiValue source_line(message->GetSourceLine()); + CHECK_EQ(" new o.foo();", *source_line); +} + +TEST(ExceptionInNativeScript) { + v8::HandleScope scope; + LocalContext env; + v8::V8::AddMessageListener(ExceptionInNativeScriptTestListener); + + Local fun = v8::FunctionTemplate::New(TroubleCallback); + v8::Local global = env->Global(); + global->Set(v8_str("trouble"), fun->GetFunction()); + + Script::Compile(v8_str("function trouble() {\n" + " var o = {};\n" + " new o.foo();\n" + "};"), v8::String::New(script_resource_name))->Run(); + Local trouble = global->Get(v8_str("trouble")); + CHECK(trouble->IsFunction()); + Function::Cast(*trouble)->Call(global, 0, NULL); + v8::V8::RemoveMessageListeners(ExceptionInNativeScriptTestListener); +} + TEST(CompilationErrorUsingTryCatchHandler) { v8::HandleScope scope;