From 85f5afb717a19a1213782db749563c17a38d750d Mon Sep 17 00:00:00 2001 From: "ager@chromium.org" Date: Tue, 19 Jul 2011 08:19:31 +0000 Subject: [PATCH] Correctly mark functions from our natives files during compilation. When creating a CompilationInfo we always have the script and can determine if it is a natives script. Now that all natives functions are recognized as such, many of them are called with undefined as the receiver. We have to use different filtering for builtins functions when printing stack traces. Also, fixed one call of CALL_NON_FUNCTION to be correctly marked as a method call (with fixed receiver). Now that CALL_NON_FUNCTION is marked as a native function this caused the receiver to be undefined. R=svenpanne@chromium.org BUG= TEST= Review URL: http://codereview.chromium.org/7395030 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8680 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/code-stubs-arm.cc | 1 + src/compiler.cc | 2 -- src/compiler.h | 9 ++++++--- src/ia32/code-stubs-ia32.cc | 1 + src/messages.js | 16 +++++++++------- src/mips/code-stubs-mips.cc | 1 + src/runtime.cc | 29 ++++++++++++++++++++++------- src/x64/code-stubs-x64.cc | 1 + test/mjsunit/regress/regress-798.js | 1 - 9 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index ab7c6f2..eaad9f2 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -4722,6 +4722,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { __ mov(r0, Operand(argc_)); // Setup the number of arguments. __ mov(r2, Operand(0, RelocInfo::NONE)); __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); + __ SetCallKind(r5, CALL_AS_METHOD); __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), RelocInfo::CODE_TARGET); } diff --git a/src/compiler.cc b/src/compiler.cc index e09b72f..c265b95 100755 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -511,7 +511,6 @@ Handle Compiler::Compile(Handle source, info.SetPreParseData(pre_data); if (natives == NATIVES_CODE) { info.MarkAsAllowingNativesSyntax(); - info.MarkAsNative(); } result = MakeFunctionInfo(&info); if (extension == NULL && !result.is_null()) { @@ -679,7 +678,6 @@ Handle Compiler::BuildFunctionInfo(FunctionLiteral* literal, info.SetFunction(literal); info.SetScope(literal->scope()); if (literal->scope()->is_strict_mode()) info.MarkAsStrictMode(); - if (script->type()->value() == Script::TYPE_NATIVE) info.MarkAsNative(); LiveEditFunctionTracker live_edit_tracker(info.isolate(), literal); // Determine if the function can be lazily compiled. This is necessary to diff --git a/src/compiler.h b/src/compiler.h index a77fc8e..8e92cf5 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -173,9 +173,12 @@ class CompilationInfo BASE_EMBEDDED { void Initialize(Mode mode) { mode_ = V8::UseCrankshaft() ? mode : NONOPT; - if (!shared_info_.is_null()) { - if (shared_info_->strict_mode()) MarkAsStrictMode(); - if (shared_info_->native()) MarkAsNative(); + ASSERT(!script_.is_null()); + if (script_->type()->value() == Script::TYPE_NATIVE) { + MarkAsNative(); + } + if (!shared_info_.is_null() && shared_info_->strict_mode()) { + MarkAsStrictMode(); } } diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index 48bd8b1..71aacf9 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -4158,6 +4158,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); Handle adaptor = masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); + __ SetCallKind(ecx, CALL_AS_METHOD); __ jmp(adaptor, RelocInfo::CODE_TARGET); } diff --git a/src/messages.js b/src/messages.js index 98f2440..aaa98ed 100644 --- a/src/messages.js +++ b/src/messages.js @@ -1051,13 +1051,15 @@ function captureStackTrace(obj, cons_opt) { $Math.__proto__ = global.Object.prototype; -DefineError(function Error() { }); -DefineError(function TypeError() { }); -DefineError(function RangeError() { }); -DefineError(function SyntaxError() { }); -DefineError(function ReferenceError() { }); -DefineError(function EvalError() { }); -DefineError(function URIError() { }); +// DefineError is a native function. Use explicit receiver. Otherwise +// the receiver will be 'undefined'. +this.DefineError(function Error() { }); +this.DefineError(function TypeError() { }); +this.DefineError(function RangeError() { }); +this.DefineError(function SyntaxError() { }); +this.DefineError(function ReferenceError() { }); +this.DefineError(function EvalError() { }); +this.DefineError(function URIError() { }); $Error.captureStackTrace = captureStackTrace; diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index d03443f..d89d3e5 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -4913,6 +4913,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { __ li(a0, Operand(argc_)); // Setup the number of arguments. __ mov(a2, zero_reg); __ GetBuiltinEntry(a3, Builtins::CALL_NON_FUNCTION); + __ SetCallKind(t1, CALL_AS_METHOD); __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), RelocInfo::CODE_TARGET); } diff --git a/src/runtime.cc b/src/runtime.cc index da20e8a..bba06d9 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -12284,8 +12284,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScript) { // call to this function is encountered it is skipped. The seen_caller // in/out parameter is used to remember if the caller has been seen // yet. -static bool ShowFrameInStackTrace(StackFrame* raw_frame, Object* caller, - bool* seen_caller) { +static bool ShowFrameInStackTrace(StackFrame* raw_frame, + Object* caller, + bool* seen_caller) { // Only display JS frames. if (!raw_frame->is_java_script()) return false; @@ -12298,11 +12299,25 @@ static bool ShowFrameInStackTrace(StackFrame* raw_frame, Object* caller, *seen_caller = true; return false; } - // Skip all frames until we've seen the caller. Also, skip the most - // obvious builtin calls. Some builtin calls (such as Number.ADD - // which is invoked using 'call') are very difficult to recognize - // so we're leaving them in for now. - return *seen_caller && !frame->receiver()->IsJSBuiltinsObject(); + // Skip all frames until we've seen the caller. + if (!(*seen_caller)) return false; + // Also, skip the most obvious builtin calls. We recognize builtins + // as (1) functions called with the builtins object as the receiver and + // as (2) functions from native scripts called with undefined as the + // receiver (direct calls to helper functions in the builtins + // code). Some builtin calls (such as Number.ADD which is invoked + // using 'call') are very difficult to recognize so we're leaving + // them in for now. + if (frame->receiver()->IsJSBuiltinsObject()) { + return false; + } + JSFunction* fun = JSFunction::cast(raw_fun); + Object* raw_script = fun->shared()->script(); + if (frame->receiver()->IsUndefined() && raw_script->IsScript()) { + int script_type = Script::cast(raw_script)->type()->value(); + return script_type != Script::TYPE_NATIVE; + } + return true; } diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 3cf7840..fd0f910 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -3198,6 +3198,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); Handle adaptor = Isolate::Current()->builtins()->ArgumentsAdaptorTrampoline(); + __ SetCallKind(rcx, CALL_AS_METHOD); __ Jump(adaptor, RelocInfo::CODE_TARGET); } diff --git a/test/mjsunit/regress/regress-798.js b/test/mjsunit/regress/regress-798.js index 423c883..ffee5da 100644 --- a/test/mjsunit/regress/regress-798.js +++ b/test/mjsunit/regress/regress-798.js @@ -106,4 +106,3 @@ xx.c; xx.a = 1; xx.b = 1; xx.c = 1; - -- 2.7.4