// Copyright 2010 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "v8.h" #include "bootstrapper.h" #include "codegen-inl.h" #include "compilation-cache.h" #include "compiler.h" #include "data-flow.h" #include "debug.h" #include "full-codegen.h" #include "liveedit.h" #include "oprofile-agent.h" #include "rewriter.h" #include "scopes.h" #include "scopeinfo.h" namespace v8 { namespace internal { // For normal operation the syntax checker is used to determine whether to // use the full compiler for top level code or not. However if the flag // --always-full-compiler is specified or debugging is active the full // compiler will be used for all code. static bool AlwaysFullCompiler() { #ifdef ENABLE_DEBUGGER_SUPPORT return FLAG_always_full_compiler || Debugger::IsDebuggerActive(); #else return FLAG_always_full_compiler; #endif } static Handle MakeCode(Handle context, CompilationInfo* info) { FunctionLiteral* function = info->function(); ASSERT(function != NULL); // Rewrite the AST by introducing .result assignments where needed. if (!Rewriter::Process(function)) { // Signal a stack overflow by returning a null handle. The stack // overflow exception will be thrown by the caller. return Handle::null(); } { // Compute top scope and allocate variables. For lazy compilation // the top scope only contains the single lazily compiled function, // so this doesn't re-allocate variables repeatedly. HistogramTimerScope timer(&Counters::variable_allocation); Scope* top = info->scope(); while (top->outer_scope() != NULL) top = top->outer_scope(); top->AllocateVariables(context); } #ifdef DEBUG if (Bootstrapper::IsActive() ? FLAG_print_builtin_scopes : FLAG_print_scopes) { info->scope()->Print(); } #endif // Optimize the AST. if (!Rewriter::Optimize(function)) { // Signal a stack overflow by returning a null handle. The stack // overflow exception will be thrown by the caller. return Handle::null(); } // Generate code and return it. Code generator selection is governed by // which backends are enabled and whether the function is considered // run-once code or not: // // --full-compiler enables the dedicated backend for code we expect to be // run once // // The normal choice of backend can be overridden with the flags // --always-full-compiler. Handle shared = info->shared_info(); bool is_run_once = (shared.is_null()) ? info->scope()->is_global_scope() : (shared->is_toplevel() || shared->try_full_codegen()); bool use_full = FLAG_full_compiler && !function->contains_loops(); if (AlwaysFullCompiler() || (use_full && is_run_once)) { return FullCodeGenerator::MakeCode(info); } AssignedVariablesAnalyzer ava(function); if (!ava.Analyze()) return Handle::null(); return CodeGenerator::MakeCode(info); } #ifdef ENABLE_DEBUGGER_SUPPORT Handle MakeCodeForLiveEdit(CompilationInfo* info) { Handle context = Handle::null(); Handle code = MakeCode(context, info); if (!info->shared_info().is_null()) { info->shared_info()->set_scope_info( *SerializedScopeInfo::Create(info->scope())); } return code; } #endif static Handle MakeFunctionInfo(bool is_global, bool is_eval, Compiler::ValidationState validate, Handle