blob: 20868e54887d1ff279fc79306b7e103ab9a6b5f8 [file] [log] [blame]
Ben Murdochf87a2032010-10-22 12:50:53 +01001// Copyright 2010 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_COMPILER_H_
29#define V8_COMPILER_H_
30
Andrei Popescu402d9372010-02-26 13:31:12 +000031#include "ast.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000032#include "frame-element.h"
Andrei Popescu402d9372010-02-26 13:31:12 +000033#include "register-allocator.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000034#include "zone.h"
35
36namespace v8 {
37namespace internal {
38
Ben Murdochf87a2032010-10-22 12:50:53 +010039class ScriptDataImpl;
40
Andrei Popescu31002712010-02-23 13:46:05 +000041// CompilationInfo encapsulates some information known at compile time. It
42// is constructed based on the resources available at compile-time.
Leon Clarke4515c472010-02-03 11:58:03 +000043class CompilationInfo BASE_EMBEDDED {
44 public:
Ben Murdochf87a2032010-10-22 12:50:53 +010045 explicit CompilationInfo(Handle<Script> script);
46 explicit CompilationInfo(Handle<SharedFunctionInfo> shared_info);
47 explicit CompilationInfo(Handle<JSFunction> closure);
48
49 bool is_lazy() const { return (flags_ & IsLazy::mask()) != 0; }
50 bool is_eval() const { return (flags_ & IsEval::mask()) != 0; }
51 bool is_global() const { return (flags_ & IsGlobal::mask()) != 0; }
Ben Murdochf87a2032010-10-22 12:50:53 +010052 bool is_in_loop() const { return (flags_ & IsInLoop::mask()) != 0; }
53 FunctionLiteral* function() const { return function_; }
54 Scope* scope() const { return scope_; }
55 Handle<Code> code() const { return code_; }
56 Handle<JSFunction> closure() const { return closure_; }
57 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
58 Handle<Script> script() const { return script_; }
59 v8::Extension* extension() const { return extension_; }
60 ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
61 Handle<Context> calling_context() const { return calling_context_; }
62
63 void MarkAsEval() {
64 ASSERT(!is_lazy());
65 flags_ |= IsEval::encode(true);
Leon Clarke4515c472010-02-03 11:58:03 +000066 }
Ben Murdochf87a2032010-10-22 12:50:53 +010067 void MarkAsGlobal() {
68 ASSERT(!is_lazy());
69 flags_ |= IsGlobal::encode(true);
Andrei Popescu31002712010-02-23 13:46:05 +000070 }
Ben Murdochf87a2032010-10-22 12:50:53 +010071 void MarkAsInLoop() {
72 ASSERT(is_lazy());
73 flags_ |= IsInLoop::encode(true);
Andrei Popescu31002712010-02-23 13:46:05 +000074 }
Ben Murdochf87a2032010-10-22 12:50:53 +010075 void SetFunction(FunctionLiteral* literal) {
76 ASSERT(function_ == NULL);
77 function_ = literal;
Andrei Popescu31002712010-02-23 13:46:05 +000078 }
Ben Murdochf87a2032010-10-22 12:50:53 +010079 void SetScope(Scope* scope) {
80 ASSERT(scope_ == NULL);
81 scope_ = scope;
Andrei Popescu31002712010-02-23 13:46:05 +000082 }
Ben Murdochf87a2032010-10-22 12:50:53 +010083 void SetCode(Handle<Code> code) { code_ = code; }
84 void SetExtension(v8::Extension* extension) {
85 ASSERT(!is_lazy());
86 extension_ = extension;
Andrei Popescu31002712010-02-23 13:46:05 +000087 }
Ben Murdochf87a2032010-10-22 12:50:53 +010088 void SetPreParseData(ScriptDataImpl* pre_parse_data) {
89 ASSERT(!is_lazy());
90 pre_parse_data_ = pre_parse_data;
91 }
92 void SetCallingContext(Handle<Context> context) {
93 ASSERT(is_eval());
94 calling_context_ = context;
95 }
Andrei Popescu31002712010-02-23 13:46:05 +000096
Leon Clarke4515c472010-02-03 11:58:03 +000097 private:
Ben Murdochf87a2032010-10-22 12:50:53 +010098 // Flags using template class BitField<type, start, length>. All are
99 // false by default.
100 //
101 // Compilation is either eager or lazy.
102 class IsLazy: public BitField<bool, 0, 1> {};
103 // Flags that can be set for eager compilation.
104 class IsEval: public BitField<bool, 1, 1> {};
105 class IsGlobal: public BitField<bool, 2, 1> {};
Ben Murdochf87a2032010-10-22 12:50:53 +0100106 // Flags that can be set for lazy compilation.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800107 class IsInLoop: public BitField<bool, 3, 1> {};
Andrei Popescu31002712010-02-23 13:46:05 +0000108
Ben Murdochf87a2032010-10-22 12:50:53 +0100109 unsigned flags_;
110
111 // Fields filled in by the compilation pipeline.
112 // AST filled in by the parser.
113 FunctionLiteral* function_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800114 // The scope of the function literal as a convenience. Set to indicate
Ben Murdochf87a2032010-10-22 12:50:53 +0100115 // that scopes have been analyzed.
116 Scope* scope_;
117 // The compiled code.
118 Handle<Code> code_;
119
120 // Possible initial inputs to the compilation process.
Andrei Popescu31002712010-02-23 13:46:05 +0000121 Handle<JSFunction> closure_;
Leon Clarke4515c472010-02-03 11:58:03 +0000122 Handle<SharedFunctionInfo> shared_info_;
Andrei Popescu31002712010-02-23 13:46:05 +0000123 Handle<Script> script_;
124
Ben Murdochf87a2032010-10-22 12:50:53 +0100125 // Fields possibly needed for eager compilation, NULL by default.
126 v8::Extension* extension_;
127 ScriptDataImpl* pre_parse_data_;
Andrei Popescu31002712010-02-23 13:46:05 +0000128
Ben Murdochf87a2032010-10-22 12:50:53 +0100129 // The context of the caller is needed for eval code, and will be a null
130 // handle otherwise.
131 Handle<Context> calling_context_;
Andrei Popescu31002712010-02-23 13:46:05 +0000132
133 DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
Leon Clarke4515c472010-02-03 11:58:03 +0000134};
135
136
Steve Blocka7e24c12009-10-30 11:49:00 +0000137// The V8 compiler
138//
139// General strategy: Source code is translated into an anonymous function w/o
140// parameters which then can be executed. If the source code contains other
141// functions, they will be compiled and allocated as part of the compilation
142// of the source code.
143
Ben Murdochf87a2032010-10-22 12:50:53 +0100144// Please note this interface returns shared function infos. This means you
145// need to call Factory::NewFunctionFromSharedFunctionInfo before you have a
146// real function with a context.
Steve Blocka7e24c12009-10-30 11:49:00 +0000147
148class Compiler : public AllStatic {
149 public:
Steve Blocka7e24c12009-10-30 11:49:00 +0000150 // All routines return a JSFunction.
151 // If an error occurs an exception is raised and
152 // the return handle contains NULL.
153
154 // Compile a String source within a context.
Steve Block6ded16b2010-05-10 14:33:55 +0100155 static Handle<SharedFunctionInfo> Compile(Handle<String> source,
156 Handle<Object> script_name,
157 int line_offset,
158 int column_offset,
159 v8::Extension* extension,
160 ScriptDataImpl* pre_data,
161 Handle<Object> script_data,
162 NativesFlag is_natives_code);
Steve Blocka7e24c12009-10-30 11:49:00 +0000163
164 // Compile a String source within a context for Eval.
Steve Block6ded16b2010-05-10 14:33:55 +0100165 static Handle<SharedFunctionInfo> CompileEval(Handle<String> source,
166 Handle<Context> context,
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800167 bool is_global);
Steve Blocka7e24c12009-10-30 11:49:00 +0000168
Ben Murdochf87a2032010-10-22 12:50:53 +0100169 // Compile from function info (used for lazy compilation). Returns true on
170 // success and false if the compilation resulted in a stack overflow.
Leon Clarke4515c472010-02-03 11:58:03 +0000171 static bool CompileLazy(CompilationInfo* info);
Steve Blockd0582a62009-12-15 09:54:21 +0000172
Ben Murdochf87a2032010-10-22 12:50:53 +0100173 // Compile a shared function info object (the function is possibly lazily
174 // compiled).
Steve Block6ded16b2010-05-10 14:33:55 +0100175 static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node,
Ben Murdochf87a2032010-10-22 12:50:53 +0100176 Handle<Script> script);
Steve Blockd0582a62009-12-15 09:54:21 +0000177
178 // Set the function info for a newly compiled function.
Steve Block6ded16b2010-05-10 14:33:55 +0100179 static void SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
Steve Blockd0582a62009-12-15 09:54:21 +0000180 FunctionLiteral* lit,
181 bool is_toplevel,
182 Handle<Script> script);
Andrei Popescu31002712010-02-23 13:46:05 +0000183
Ben Murdochf87a2032010-10-22 12:50:53 +0100184#ifdef ENABLE_DEBUGGER_SUPPORT
185 static bool MakeCodeForLiveEdit(CompilationInfo* info);
186#endif
187
Andrei Popescu31002712010-02-23 13:46:05 +0000188 private:
Steve Block6ded16b2010-05-10 14:33:55 +0100189 static void RecordFunctionCompilation(Logger::LogEventsAndTags tag,
190 Handle<String> name,
Steve Block6ded16b2010-05-10 14:33:55 +0100191 int start_position,
Ben Murdochf87a2032010-10-22 12:50:53 +0100192 CompilationInfo* info);
Steve Blocka7e24c12009-10-30 11:49:00 +0000193};
194
195
Steve Blocka7e24c12009-10-30 11:49:00 +0000196// During compilation we need a global list of handles to constants
197// for frame elements. When the zone gets deleted, we make sure to
198// clear this list of handles as well.
199class CompilationZoneScope : public ZoneScope {
200 public:
201 explicit CompilationZoneScope(ZoneScopeMode mode) : ZoneScope(mode) { }
202 virtual ~CompilationZoneScope() {
203 if (ShouldDeleteOnExit()) {
204 FrameElement::ClearConstantList();
205 Result::ClearConstantList();
206 }
207 }
208};
209
210
211} } // namespace v8::internal
212
213#endif // V8_COMPILER_H_