bool is_json = (validate == Compiler::VALIDATE_JSON);
#ifdef ENABLE_DEBUGGER_SUPPORT
if (is_eval || is_json) {
- script->set_compilation_type(
- is_json ? Smi::FromInt(Script::COMPILATION_TYPE_JSON) :
- Smi::FromInt(Script::COMPILATION_TYPE_EVAL));
+ Script::CompilationType compilation_type = is_json
+ ? Script::COMPILATION_TYPE_JSON
+ : Script::COMPILATION_TYPE_EVAL;
+ script->set_compilation_type(Smi::FromInt(compilation_type));
// For eval scripts add information on the function from which eval was
// called.
if (is_eval) {
ASSERT(is_eval || is_global);
// Build AST.
+ EagerCompilationInfo info(script, is_eval);
FunctionLiteral* lit =
MakeAST(is_global, script, extension, pre_data, is_json);
- LiveEditFunctionTracker live_edit_tracker(lit);
-
// Check for parse errors.
if (lit == NULL) {
ASSERT(Top::has_pending_exception());
return Handle<SharedFunctionInfo>::null();
}
+ info.set_function(lit);
// Measure how long it takes to do the compilation; only take the
// rest of the function into account to avoid overlap with the
HistogramTimerScope timer(rate);
// Compile the code.
- CompilationInfo info(lit, script, is_eval);
+ LiveEditFunctionTracker live_edit_tracker(lit);
Handle<Code> code = MakeCode(context, &info);
// Check for stack-overflow exceptions.
// Generate code and return it. The way that the compilation mode
// is controlled by the command-line flags is described in
// the static helper function MakeCode.
- CompilationInfo info(literal, script, false);
+ EagerCompilationInfo info(script, false);
+ info.set_function(literal);
bool is_run_once = literal->try_full_codegen();
bool use_full = FLAG_full_compiler && !literal->contains_loops();
// is constructed based on the resources available at compile-time.
class CompilationInfo BASE_EMBEDDED {
public:
- // Lazy compilation of a JSFunction.
- CompilationInfo(Handle<JSFunction> closure, int loop_nesting)
- : closure_(closure),
- function_(NULL),
- is_eval_(false),
- loop_nesting_(loop_nesting) {
- ASSERT(!closure_.is_null() &&
- shared_info_.is_null() &&
- script_.is_null());
- }
+ virtual ~CompilationInfo() {}
+
+ // Dispatched behavior.
+ virtual Handle<SharedFunctionInfo> shared_info() const = 0;
- // Lazy compilation based on SharedFunctionInfo.
- explicit CompilationInfo(Handle<SharedFunctionInfo> shared_info)
- : shared_info_(shared_info),
- function_(NULL),
- is_eval_(false),
- loop_nesting_(0) {
- ASSERT(closure_.is_null() &&
- !shared_info_.is_null() &&
- script_.is_null());
+ virtual Handle<Script> script() const {
+ return Handle<Script>(Script::cast(shared_info()->script()));
}
- // Eager compilation.
- CompilationInfo(FunctionLiteral* literal, Handle<Script> script, bool is_eval)
- : script_(script),
- function_(literal),
- is_eval_(is_eval),
- loop_nesting_(0) {
- ASSERT(closure_.is_null() &&
- shared_info_.is_null() &&
- !script_.is_null());
+ virtual Handle<JSFunction> closure() const {
+ return Handle<JSFunction>::null();
}
- // We can only get a JSFunction if we actually have one.
- Handle<JSFunction> closure() { return closure_; }
+ virtual bool is_eval() const { return false; }
- // We can get a SharedFunctionInfo from a JSFunction or if we actually
- // have one.
- Handle<SharedFunctionInfo> shared_info() {
- if (!closure().is_null()) {
- return Handle<SharedFunctionInfo>(closure()->shared());
- } else {
- return shared_info_;
- }
- }
+ virtual int loop_nesting() const { return 0; }
- // We can always get a script. Either we have one or we can get a shared
- // function info.
- Handle<Script> script() {
- if (!script_.is_null()) {
- return script_;
- } else {
- ASSERT(shared_info()->script()->IsScript());
- return Handle<Script>(Script::cast(shared_info()->script()));
- }
- }
+ virtual bool has_global_object() const { return false; }
+ virtual GlobalObject* global_object() const { return NULL; }
// There should always be a function literal, but it may be set after
// construction (for lazy compilation).
FunctionLiteral* function() { return function_; }
void set_function(FunctionLiteral* literal) { function_ = literal; }
- // Simple accessors.
- bool is_eval() { return is_eval_; }
- int loop_nesting() { return loop_nesting_; }
+ // Derived accessors.
+ Scope* scope() { return function()->scope(); }
+
+ protected:
+ CompilationInfo() : function_(NULL) {}
+
+ private:
+ FunctionLiteral* function_;
- bool has_global_object() {
- return !closure().is_null() && (closure()->context()->global() != NULL);
+ DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
+};
+
+
+class EagerCompilationInfo: public CompilationInfo {
+ public:
+ EagerCompilationInfo(Handle<Script> script, bool is_eval)
+ : script_(script), is_eval_(is_eval) {
+ ASSERT(!script.is_null());
}
- GlobalObject* global_object() {
- return has_global_object() ? closure()->context()->global() : NULL;
+ // Overridden functions from the base class.
+ virtual Handle<SharedFunctionInfo> shared_info() const {
+ return Handle<SharedFunctionInfo>::null();
}
- // Derived accessors.
- Scope* scope() { return function()->scope(); }
+ virtual Handle<Script> script() const { return script_; }
+
+ virtual bool is_eval() const { return is_eval_; }
private:
- Handle<JSFunction> closure_;
- Handle<SharedFunctionInfo> shared_info_;
Handle<Script> script_;
+ bool is_eval_;
+};
- FunctionLiteral* function_;
- bool is_eval_;
- int loop_nesting_;
+class LazySharedCompilationInfo: public CompilationInfo {
+ public:
+ explicit LazySharedCompilationInfo(Handle<SharedFunctionInfo> shared_info)
+ : shared_info_(shared_info) {
+ ASSERT(!shared_info.is_null());
+ }
- DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
+ // Overridden functions from the base class.
+ virtual Handle<SharedFunctionInfo> shared_info() const {
+ return shared_info_;
+ }
+
+ private:
+ Handle<SharedFunctionInfo> shared_info_;
+};
+
+
+class LazyFunctionCompilationInfo: public CompilationInfo {
+ public:
+ LazyFunctionCompilationInfo(Handle<JSFunction> closure,
+ int loop_nesting)
+ : closure_(closure), loop_nesting_(loop_nesting) {
+ ASSERT(!closure.is_null());
+ }
+
+ // Overridden functions from the base class.
+ virtual Handle<SharedFunctionInfo> shared_info() const {
+ return Handle<SharedFunctionInfo>(closure_->shared());
+ }
+
+ virtual int loop_nesting() const { return loop_nesting_; }
+
+ virtual bool has_global_object() const {
+ return closure_->context()->global() != NULL;
+ }
+
+ virtual GlobalObject* global_object() const {
+ return closure_->context()->global();
+ }
+
+ private:
+ Handle<JSFunction> closure_;
+ int loop_nesting_;
};
bool CompileLazyShared(Handle<SharedFunctionInfo> shared,
ClearExceptionFlag flag) {
- CompilationInfo info(shared);
+ LazySharedCompilationInfo info(shared);
return CompileLazyHelper(&info, flag);
}
function->shared()->set_code_age(0);
return true;
} else {
- CompilationInfo info(function, 0);
+ LazyFunctionCompilationInfo info(function, 0);
bool result = CompileLazyHelper(&info, flag);
PROFILE(FunctionCreateEvent(*function));
return result;
function->shared()->set_code_age(0);
return true;
} else {
- CompilationInfo info(function, 1);
+ LazyFunctionCompilationInfo info(function, 1);
bool result = CompileLazyHelper(&info, flag);
PROFILE(FunctionCreateEvent(*function));
return result;