// Copyright 2009 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 "debug.h" #include "fast-codegen.h" #include "full-codegen.h" #include "oprofile-agent.h" #include "rewriter.h" #include "scopes.h" #include "usage-analyzer.h" #include "liveedit.h" namespace v8 { namespace internal { 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) || !AnalyzeVariableUsage(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 // --fast-compiler enables a speculative optimizing backend (for // non-run-once code) // // The normal choice of backend can be overridden with the flags // --always-full-compiler and --always-fast-compiler, which are mutually // incompatible. CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_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()); if (FLAG_always_full_compiler || (FLAG_full_compiler && is_run_once)) { FullCodeGenSyntaxChecker checker; checker.Check(function); if (checker.has_supported_syntax()) { return FullCodeGenerator::MakeCode(info); } } else if (FLAG_always_fast_compiler || (FLAG_fast_compiler && !is_run_once)) { FastCodeGenSyntaxChecker checker; checker.Check(info); if (checker.has_supported_syntax()) { return FastCodeGenerator::MakeCode(info); } } return CodeGenerator::MakeCode(info); } #ifdef ENABLE_DEBUGGER_SUPPORT Handle MakeCodeForLiveEdit(CompilationInfo* info) { Handle context = Handle::null(); return MakeCode(context, info); } #endif static Handle MakeFunction(bool is_global, bool is_eval, Compiler::ValidationState validate, Handle