blob: d6f4e69d525738a64084997d96e51f9a1157cc3b [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; }
52 bool is_json() const { return (flags_ & IsJson::mask()) != 0; }
53 bool is_in_loop() const { return (flags_ & IsInLoop::mask()) != 0; }
54 FunctionLiteral* function() const { return function_; }
55 Scope* scope() const { return scope_; }
56 Handle<Code> code() const { return code_; }
57 Handle<JSFunction> closure() const { return closure_; }
58 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
59 Handle<Script> script() const { return script_; }
60 v8::Extension* extension() const { return extension_; }
61 ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
62 Handle<Context> calling_context() const { return calling_context_; }
63
64 void MarkAsEval() {
65 ASSERT(!is_lazy());
66 flags_ |= IsEval::encode(true);
Leon Clarke4515c472010-02-03 11:58:03 +000067 }
Ben Murdochf87a2032010-10-22 12:50:53 +010068 void MarkAsGlobal() {
69 ASSERT(!is_lazy());
70 flags_ |= IsGlobal::encode(true);
Andrei Popescu31002712010-02-23 13:46:05 +000071 }
Ben Murdochf87a2032010-10-22 12:50:53 +010072 void MarkAsJson() {
73 ASSERT(!is_lazy());
74 flags_ |= IsJson::encode(true);
Andrei Popescu31002712010-02-23 13:46:05 +000075 }
Ben Murdochf87a2032010-10-22 12:50:53 +010076 void MarkAsInLoop() {
77 ASSERT(is_lazy());
78 flags_ |= IsInLoop::encode(true);
Andrei Popescu31002712010-02-23 13:46:05 +000079 }
Ben Murdochf87a2032010-10-22 12:50:53 +010080 void SetFunction(FunctionLiteral* literal) {
81 ASSERT(function_ == NULL);
82 function_ = literal;
Andrei Popescu31002712010-02-23 13:46:05 +000083 }
Ben Murdochf87a2032010-10-22 12:50:53 +010084 void SetScope(Scope* scope) {
85 ASSERT(scope_ == NULL);
86 scope_ = scope;
Andrei Popescu31002712010-02-23 13:46:05 +000087 }
Ben Murdochf87a2032010-10-22 12:50:53 +010088 void SetCode(Handle<Code> code) { code_ = code; }
89 void SetExtension(v8::Extension* extension) {
90 ASSERT(!is_lazy());
91 extension_ = extension;
Andrei Popescu31002712010-02-23 13:46:05 +000092 }
Ben Murdochf87a2032010-10-22 12:50:53 +010093 void SetPreParseData(ScriptDataImpl* pre_parse_data) {
94 ASSERT(!is_lazy());
95 pre_parse_data_ = pre_parse_data;
96 }
97 void SetCallingContext(Handle<Context> context) {
98 ASSERT(is_eval());
99 calling_context_ = context;
100 }
Andrei Popescu31002712010-02-23 13:46:05 +0000101
Leon Clarke4515c472010-02-03 11:58:03 +0000102 private:
Ben Murdochf87a2032010-10-22 12:50:53 +0100103 // Flags using template class BitField<type, start, length>. All are
104 // false by default.
105 //
106 // Compilation is either eager or lazy.
107 class IsLazy: public BitField<bool, 0, 1> {};
108 // Flags that can be set for eager compilation.
109 class IsEval: public BitField<bool, 1, 1> {};
110 class IsGlobal: public BitField<bool, 2, 1> {};
111 class IsJson: public BitField<bool, 3, 1> {};
112 // Flags that can be set for lazy compilation.
113 class IsInLoop: public BitField<bool, 4, 1> {};
Andrei Popescu31002712010-02-23 13:46:05 +0000114
Ben Murdochf87a2032010-10-22 12:50:53 +0100115 unsigned flags_;
116
117 // Fields filled in by the compilation pipeline.
118 // AST filled in by the parser.
119 FunctionLiteral* function_;
120 // The scope of the function literal as a convenience. Set to indidicate
121 // that scopes have been analyzed.
122 Scope* scope_;
123 // The compiled code.
124 Handle<Code> code_;
125
126 // Possible initial inputs to the compilation process.
Andrei Popescu31002712010-02-23 13:46:05 +0000127 Handle<JSFunction> closure_;
Leon Clarke4515c472010-02-03 11:58:03 +0000128 Handle<SharedFunctionInfo> shared_info_;
Andrei Popescu31002712010-02-23 13:46:05 +0000129 Handle<Script> script_;
130
Ben Murdochf87a2032010-10-22 12:50:53 +0100131 // Fields possibly needed for eager compilation, NULL by default.
132 v8::Extension* extension_;
133 ScriptDataImpl* pre_parse_data_;
Andrei Popescu31002712010-02-23 13:46:05 +0000134
Ben Murdochf87a2032010-10-22 12:50:53 +0100135 // The context of the caller is needed for eval code, and will be a null
136 // handle otherwise.
137 Handle<Context> calling_context_;
Andrei Popescu31002712010-02-23 13:46:05 +0000138
139 DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
Leon Clarke4515c472010-02-03 11:58:03 +0000140};
141
142
Steve Blocka7e24c12009-10-30 11:49:00 +0000143// The V8 compiler
144//
145// General strategy: Source code is translated into an anonymous function w/o
146// parameters which then can be executed. If the source code contains other
147// functions, they will be compiled and allocated as part of the compilation
148// of the source code.
149
Ben Murdochf87a2032010-10-22 12:50:53 +0100150// Please note this interface returns shared function infos. This means you
151// need to call Factory::NewFunctionFromSharedFunctionInfo before you have a
152// real function with a context.
Steve Blocka7e24c12009-10-30 11:49:00 +0000153
154class Compiler : public AllStatic {
155 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100156 enum ValidationState { DONT_VALIDATE_JSON, VALIDATE_JSON };
Steve Blocka7e24c12009-10-30 11:49:00 +0000157
158 // All routines return a JSFunction.
159 // If an error occurs an exception is raised and
160 // the return handle contains NULL.
161
162 // Compile a String source within a context.
Steve Block6ded16b2010-05-10 14:33:55 +0100163 static Handle<SharedFunctionInfo> Compile(Handle<String> source,
164 Handle<Object> script_name,
165 int line_offset,
166 int column_offset,
167 v8::Extension* extension,
168 ScriptDataImpl* pre_data,
169 Handle<Object> script_data,
170 NativesFlag is_natives_code);
Steve Blocka7e24c12009-10-30 11:49:00 +0000171
172 // Compile a String source within a context for Eval.
Steve Block6ded16b2010-05-10 14:33:55 +0100173 static Handle<SharedFunctionInfo> CompileEval(Handle<String> source,
174 Handle<Context> context,
175 bool is_global,
176 ValidationState validation);
Steve Blocka7e24c12009-10-30 11:49:00 +0000177
Ben Murdochf87a2032010-10-22 12:50:53 +0100178 // Compile from function info (used for lazy compilation). Returns true on
179 // success and false if the compilation resulted in a stack overflow.
Leon Clarke4515c472010-02-03 11:58:03 +0000180 static bool CompileLazy(CompilationInfo* info);
Steve Blockd0582a62009-12-15 09:54:21 +0000181
Ben Murdochf87a2032010-10-22 12:50:53 +0100182 // Compile a shared function info object (the function is possibly lazily
183 // compiled).
Steve Block6ded16b2010-05-10 14:33:55 +0100184 static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node,
Ben Murdochf87a2032010-10-22 12:50:53 +0100185 Handle<Script> script);
Steve Blockd0582a62009-12-15 09:54:21 +0000186
187 // Set the function info for a newly compiled function.
Steve Block6ded16b2010-05-10 14:33:55 +0100188 static void SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
Steve Blockd0582a62009-12-15 09:54:21 +0000189 FunctionLiteral* lit,
190 bool is_toplevel,
191 Handle<Script> script);
Andrei Popescu31002712010-02-23 13:46:05 +0000192
Ben Murdochf87a2032010-10-22 12:50:53 +0100193#ifdef ENABLE_DEBUGGER_SUPPORT
194 static bool MakeCodeForLiveEdit(CompilationInfo* info);
195#endif
196
Andrei Popescu31002712010-02-23 13:46:05 +0000197 private:
Steve Block6ded16b2010-05-10 14:33:55 +0100198 static void RecordFunctionCompilation(Logger::LogEventsAndTags tag,
199 Handle<String> name,
Steve Block6ded16b2010-05-10 14:33:55 +0100200 int start_position,
Ben Murdochf87a2032010-10-22 12:50:53 +0100201 CompilationInfo* info);
Steve Blocka7e24c12009-10-30 11:49:00 +0000202};
203
204
Steve Blocka7e24c12009-10-30 11:49:00 +0000205// During compilation we need a global list of handles to constants
206// for frame elements. When the zone gets deleted, we make sure to
207// clear this list of handles as well.
208class CompilationZoneScope : public ZoneScope {
209 public:
210 explicit CompilationZoneScope(ZoneScopeMode mode) : ZoneScope(mode) { }
211 virtual ~CompilationZoneScope() {
212 if (ShouldDeleteOnExit()) {
213 FrameElement::ClearConstantList();
214 Result::ClearConstantList();
215 }
216 }
217};
218
219
220} } // namespace v8::internal
221
222#endif // V8_COMPILER_H_