blob: ed26603f42c538f084392b3045448a490504d1a1 [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
2// 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"
33#include "parser.h"
Andrei Popescu402d9372010-02-26 13:31:12 +000034#include "register-allocator.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000035#include "zone.h"
36
37namespace v8 {
38namespace internal {
39
Andrei Popescu31002712010-02-23 13:46:05 +000040// CompilationInfo encapsulates some information known at compile time. It
41// is constructed based on the resources available at compile-time.
Leon Clarke4515c472010-02-03 11:58:03 +000042class CompilationInfo BASE_EMBEDDED {
43 public:
Andrei Popescu31002712010-02-23 13:46:05 +000044 // Lazy compilation of a JSFunction.
45 CompilationInfo(Handle<JSFunction> closure,
46 int loop_nesting,
47 Handle<Object> receiver)
48 : closure_(closure),
49 function_(NULL),
50 is_eval_(false),
Leon Clarke4515c472010-02-03 11:58:03 +000051 loop_nesting_(loop_nesting),
Andrei Popescu31002712010-02-23 13:46:05 +000052 receiver_(receiver) {
53 Initialize();
54 ASSERT(!closure_.is_null() &&
55 shared_info_.is_null() &&
56 script_.is_null());
Leon Clarke4515c472010-02-03 11:58:03 +000057 }
58
Andrei Popescu31002712010-02-23 13:46:05 +000059 // Lazy compilation based on SharedFunctionInfo.
60 explicit CompilationInfo(Handle<SharedFunctionInfo> shared_info)
61 : shared_info_(shared_info),
62 function_(NULL),
63 is_eval_(false),
64 loop_nesting_(0) {
65 Initialize();
66 ASSERT(closure_.is_null() &&
67 !shared_info_.is_null() &&
68 script_.is_null());
69 }
Leon Clarke4515c472010-02-03 11:58:03 +000070
Andrei Popescu31002712010-02-23 13:46:05 +000071 // Eager compilation.
72 CompilationInfo(FunctionLiteral* literal, Handle<Script> script, bool is_eval)
73 : script_(script),
74 function_(literal),
75 is_eval_(is_eval),
76 loop_nesting_(0) {
77 Initialize();
78 ASSERT(closure_.is_null() &&
79 shared_info_.is_null() &&
80 !script_.is_null());
81 }
82
83 // We can only get a JSFunction if we actually have one.
84 Handle<JSFunction> closure() { return closure_; }
85
86 // We can get a SharedFunctionInfo from a JSFunction or if we actually
87 // have one.
88 Handle<SharedFunctionInfo> shared_info() {
89 if (!closure().is_null()) {
90 return Handle<SharedFunctionInfo>(closure()->shared());
91 } else {
92 return shared_info_;
93 }
94 }
95
96 // We can always get a script. Either we have one or we can get a shared
97 // function info.
98 Handle<Script> script() {
99 if (!script_.is_null()) {
100 return script_;
101 } else {
102 ASSERT(shared_info()->script()->IsScript());
103 return Handle<Script>(Script::cast(shared_info()->script()));
104 }
105 }
106
107 // There should always be a function literal, but it may be set after
108 // construction (for lazy compilation).
109 FunctionLiteral* function() { return function_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100110 void set_function(FunctionLiteral* literal) { function_ = literal; }
Andrei Popescu31002712010-02-23 13:46:05 +0000111
112 // Simple accessors.
113 bool is_eval() { return is_eval_; }
114 int loop_nesting() { return loop_nesting_; }
Leon Clarke4515c472010-02-03 11:58:03 +0000115 bool has_receiver() { return !receiver_.is_null(); }
116 Handle<Object> receiver() { return receiver_; }
Andrei Popescu402d9372010-02-26 13:31:12 +0000117
Leon Clarke4515c472010-02-03 11:58:03 +0000118 bool has_this_properties() { return has_this_properties_; }
119 void set_has_this_properties(bool flag) { has_this_properties_ = flag; }
120
Andrei Popescu31002712010-02-23 13:46:05 +0000121 bool has_global_object() {
122 return !closure().is_null() && (closure()->context()->global() != NULL);
123 }
124
125 GlobalObject* global_object() {
126 return has_global_object() ? closure()->context()->global() : NULL;
127 }
128
Leon Clarke4515c472010-02-03 11:58:03 +0000129 bool has_globals() { return has_globals_; }
130 void set_has_globals(bool flag) { has_globals_ = flag; }
131
Andrei Popescu31002712010-02-23 13:46:05 +0000132 // Derived accessors.
133 Scope* scope() { return function()->scope(); }
134
Leon Clarke4515c472010-02-03 11:58:03 +0000135 private:
Andrei Popescu31002712010-02-23 13:46:05 +0000136 void Initialize() {
137 has_this_properties_ = false;
138 has_globals_ = false;
139 }
140
141 Handle<JSFunction> closure_;
Leon Clarke4515c472010-02-03 11:58:03 +0000142 Handle<SharedFunctionInfo> shared_info_;
Andrei Popescu31002712010-02-23 13:46:05 +0000143 Handle<Script> script_;
144
145 FunctionLiteral* function_;
146
147 bool is_eval_;
Leon Clarke4515c472010-02-03 11:58:03 +0000148 int loop_nesting_;
Andrei Popescu31002712010-02-23 13:46:05 +0000149
150 Handle<Object> receiver_;
151
Leon Clarke4515c472010-02-03 11:58:03 +0000152 bool has_this_properties_;
153 bool has_globals_;
Andrei Popescu31002712010-02-23 13:46:05 +0000154
155 DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
Leon Clarke4515c472010-02-03 11:58:03 +0000156};
157
158
Steve Blocka7e24c12009-10-30 11:49:00 +0000159// The V8 compiler
160//
161// General strategy: Source code is translated into an anonymous function w/o
162// parameters which then can be executed. If the source code contains other
163// functions, they will be compiled and allocated as part of the compilation
164// of the source code.
165
Steve Block6ded16b2010-05-10 14:33:55 +0100166// Please note this interface returns shared function infos.
167// This means you need to call Factory::NewFunctionFromSharedFunctionInfo
168// before you have a real function with a context.
Steve Blocka7e24c12009-10-30 11:49:00 +0000169
170class Compiler : public AllStatic {
171 public:
172 enum ValidationState { VALIDATE_JSON, DONT_VALIDATE_JSON };
173
174 // All routines return a JSFunction.
175 // If an error occurs an exception is raised and
176 // the return handle contains NULL.
177
178 // Compile a String source within a context.
Steve Block6ded16b2010-05-10 14:33:55 +0100179 static Handle<SharedFunctionInfo> Compile(Handle<String> source,
180 Handle<Object> script_name,
181 int line_offset,
182 int column_offset,
183 v8::Extension* extension,
184 ScriptDataImpl* pre_data,
185 Handle<Object> script_data,
186 NativesFlag is_natives_code);
Steve Blocka7e24c12009-10-30 11:49:00 +0000187
188 // Compile a String source within a context for Eval.
Steve Block6ded16b2010-05-10 14:33:55 +0100189 static Handle<SharedFunctionInfo> CompileEval(Handle<String> source,
190 Handle<Context> context,
191 bool is_global,
192 ValidationState validation);
Steve Blocka7e24c12009-10-30 11:49:00 +0000193
194 // Compile from function info (used for lazy compilation). Returns
195 // true on success and false if the compilation resulted in a stack
196 // overflow.
Leon Clarke4515c472010-02-03 11:58:03 +0000197 static bool CompileLazy(CompilationInfo* info);
Steve Blockd0582a62009-12-15 09:54:21 +0000198
Steve Block6ded16b2010-05-10 14:33:55 +0100199 // Compile a shared function info object (the function is possibly
Steve Blockd0582a62009-12-15 09:54:21 +0000200 // lazily compiled). Called recursively from a backend code
Steve Block6ded16b2010-05-10 14:33:55 +0100201 // generator 'caller' to build the shared function info.
202 static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node,
203 Handle<Script> script,
204 AstVisitor* caller);
Steve Blockd0582a62009-12-15 09:54:21 +0000205
206 // Set the function info for a newly compiled function.
Steve Block6ded16b2010-05-10 14:33:55 +0100207 static void SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
Steve Blockd0582a62009-12-15 09:54:21 +0000208 FunctionLiteral* lit,
209 bool is_toplevel,
210 Handle<Script> script);
Andrei Popescu31002712010-02-23 13:46:05 +0000211
212 private:
Steve Block6ded16b2010-05-10 14:33:55 +0100213 static void RecordFunctionCompilation(Logger::LogEventsAndTags tag,
214 Handle<String> name,
215 Handle<String> inferred_name,
216 int start_position,
217 Handle<Script> script,
218 Handle<Code> code);
Steve Blocka7e24c12009-10-30 11:49:00 +0000219};
220
221
Steve Block6ded16b2010-05-10 14:33:55 +0100222#ifdef ENABLE_DEBUGGER_SUPPORT
223
224Handle<Code> MakeCodeForLiveEdit(CompilationInfo* info);
225
226#endif
227
228
Steve Blocka7e24c12009-10-30 11:49:00 +0000229// During compilation we need a global list of handles to constants
230// for frame elements. When the zone gets deleted, we make sure to
231// clear this list of handles as well.
232class CompilationZoneScope : public ZoneScope {
233 public:
234 explicit CompilationZoneScope(ZoneScopeMode mode) : ZoneScope(mode) { }
235 virtual ~CompilationZoneScope() {
236 if (ShouldDeleteOnExit()) {
237 FrameElement::ClearConstantList();
238 Result::ClearConstantList();
239 }
240 }
241};
242
243
244} } // namespace v8::internal
245
246#endif // V8_COMPILER_H_