Index: src/compiler.cc |
=================================================================== |
--- src/compiler.cc (revision 3211) |
+++ src/compiler.cc (working copy) |
@@ -258,7 +258,7 @@ |
code); |
ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position()); |
- CodeGenerator::SetFunctionInfo(fun, lit, true, script); |
+ Compiler::SetFunctionInfo(fun, lit, true, script); |
// Hint to the runtime system used when allocating space for initial |
// property space by setting the expected number of properties for |
@@ -475,6 +475,110 @@ |
} |
+Handle<JSFunction> Compiler::BuildBoilerplate(FunctionLiteral* literal, |
+ Handle<Script> script, |
+ AstVisitor* caller) { |
+#ifdef DEBUG |
+ // We should not try to compile the same function literal more than |
+ // once. |
+ literal->mark_as_compiled(); |
+#endif |
+ |
+ // Determine if the function can be lazily compiled. This is |
+ // necessary to allow some of our builtin JS files to be lazily |
+ // compiled. These builtins cannot be handled lazily by the parser, |
+ // since we have to know if a function uses the special natives |
+ // syntax, which is something the parser records. |
+ bool allow_lazy = literal->AllowsLazyCompilation(); |
+ |
+ // Generate code |
+ Handle<Code> code; |
+ if (FLAG_lazy && allow_lazy) { |
+ code = ComputeLazyCompile(literal->num_parameters()); |
+ } else { |
+ // The bodies of function literals have not yet been visited by |
+ // the AST optimizer/analyzer. |
+ if (!Rewriter::Optimize(literal)) { |
+ return Handle<JSFunction>::null(); |
+ } |
+ |
+ // Generate code and return it. |
+ if (FLAG_fast_compiler && literal->try_fast_codegen()) { |
+ CodeGenSelector selector; |
+ CodeGenSelector::CodeGenTag code_gen = selector.Select(literal); |
+ if (code_gen == CodeGenSelector::FAST) { |
+ code = FastCodeGenerator::MakeCode(literal, |
+ script, |
+ false); // Not eval. |
+ } |
+ ASSERT(code_gen == CodeGenSelector::NORMAL); |
+ } else { |
+ code = CodeGenerator::MakeCode(literal, |
+ script, |
+ false); // Not eval. |
+ } |
+ |
+ // Check for stack-overflow exception. |
+ if (code.is_null()) { |
+ caller->SetStackOverflow(); |
+ return Handle<JSFunction>::null(); |
+ } |
+ |
+ // Function compilation complete. |
+ LOG(CodeCreateEvent(Logger::FUNCTION_TAG, *code, *literal->name())); |
+ |
+#ifdef ENABLE_OPROFILE_AGENT |
+ OProfileAgent::CreateNativeCodeRegion(*node->name(), |
+ code->instruction_start(), |
+ code->instruction_size()); |
+#endif |
+ } |
+ |
+ // Create a boilerplate function. |
+ Handle<JSFunction> function = |
+ Factory::NewFunctionBoilerplate(literal->name(), |
+ literal->materialized_literal_count(), |
+ code); |
+ SetFunctionInfo(function, literal, false, script); |
+ |
+#ifdef ENABLE_DEBUGGER_SUPPORT |
+ // Notify debugger that a new function has been added. |
+ Debugger::OnNewFunction(function); |
+#endif |
+ |
+ // Set the expected number of properties for instances and return |
+ // the resulting function. |
+ SetExpectedNofPropertiesFromEstimate(function, |
+ literal->expected_property_count()); |
+ return function; |
+} |
+ |
+ |
+// Sets the function info on a function. |
+// The start_position points to the first '(' character after the function name |
+// in the full script source. When counting characters in the script source the |
+// the first character is number 0 (not 1). |
+void Compiler::SetFunctionInfo(Handle<JSFunction> fun, |
+ FunctionLiteral* lit, |
+ bool is_toplevel, |
+ Handle<Script> script) { |
+ fun->shared()->set_length(lit->num_parameters()); |
+ fun->shared()->set_formal_parameter_count(lit->num_parameters()); |
+ fun->shared()->set_script(*script); |
+ fun->shared()->set_function_token_position(lit->function_token_position()); |
+ fun->shared()->set_start_position(lit->start_position()); |
+ fun->shared()->set_end_position(lit->end_position()); |
+ fun->shared()->set_is_expression(lit->is_expression()); |
+ fun->shared()->set_is_toplevel(is_toplevel); |
+ fun->shared()->set_inferred_name(*lit->inferred_name()); |
+ fun->shared()->SetThisPropertyAssignmentsInfo( |
+ lit->has_only_this_property_assignments(), |
+ lit->has_only_simple_this_property_assignments(), |
+ *lit->this_property_assignments()); |
+ fun->shared()->set_try_fast_codegen(lit->try_fast_codegen()); |
+} |
+ |
+ |
CodeGenSelector::CodeGenTag CodeGenSelector::Select(FunctionLiteral* fun) { |
Scope* scope = fun->scope(); |
if (scope->num_heap_slots() != 0) { |