600f6a32ee1dc1ae4b9416e950ce2d1dbedcdbd1
[platform/framework/web/crosswalk.git] / src / v8 / test / cctest / compiler / function-tester.h
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_CCTEST_COMPILER_FUNCTION_TESTER_H_
6 #define V8_CCTEST_COMPILER_FUNCTION_TESTER_H_
7
8 #include "src/v8.h"
9 #include "test/cctest/cctest.h"
10
11 #include "src/ast-numbering.h"
12 #include "src/compiler.h"
13 #include "src/compiler/linkage.h"
14 #include "src/compiler/pipeline.h"
15 #include "src/execution.h"
16 #include "src/full-codegen.h"
17 #include "src/handles.h"
18 #include "src/objects-inl.h"
19 #include "src/parser.h"
20 #include "src/rewriter.h"
21 #include "src/scopes.h"
22
23 #define USE_CRANKSHAFT 0
24
25 namespace v8 {
26 namespace internal {
27 namespace compiler {
28
29 class FunctionTester : public InitializedHandleScope {
30  public:
31   explicit FunctionTester(const char* source, uint32_t flags = 0)
32       : isolate(main_isolate()),
33         function((FLAG_allow_natives_syntax = true, NewFunction(source))),
34         flags_(flags) {
35     Compile(function);
36     const uint32_t supported_flags = CompilationInfo::kContextSpecializing |
37                                      CompilationInfo::kInliningEnabled |
38                                      CompilationInfo::kTypingEnabled;
39     CHECK_EQ(0, flags_ & ~supported_flags);
40   }
41
42   explicit FunctionTester(Graph* graph)
43       : isolate(main_isolate()),
44         function(NewFunction("(function(a,b){})")),
45         flags_(0) {
46     CompileGraph(graph);
47   }
48
49   Isolate* isolate;
50   Handle<JSFunction> function;
51
52   MaybeHandle<Object> Call(Handle<Object> a, Handle<Object> b) {
53     Handle<Object> args[] = {a, b};
54     return Execution::Call(isolate, function, undefined(), 2, args, false);
55   }
56
57   void CheckThrows(Handle<Object> a, Handle<Object> b) {
58     TryCatch try_catch;
59     MaybeHandle<Object> no_result = Call(a, b);
60     CHECK(isolate->has_pending_exception());
61     CHECK(try_catch.HasCaught());
62     CHECK(no_result.is_null());
63     // TODO(mstarzinger): Temporary workaround for issue chromium:362388.
64     isolate->OptionalRescheduleException(true);
65   }
66
67   v8::Handle<v8::Message> CheckThrowsReturnMessage(Handle<Object> a,
68                                                    Handle<Object> b) {
69     TryCatch try_catch;
70     MaybeHandle<Object> no_result = Call(a, b);
71     CHECK(isolate->has_pending_exception());
72     CHECK(try_catch.HasCaught());
73     CHECK(no_result.is_null());
74     // TODO(mstarzinger): Calling OptionalRescheduleException is a dirty hack,
75     // it's the only way to make Message() not to assert because an external
76     // exception has been caught by the try_catch.
77     isolate->OptionalRescheduleException(true);
78     return try_catch.Message();
79   }
80
81   void CheckCall(Handle<Object> expected, Handle<Object> a, Handle<Object> b) {
82     Handle<Object> result = Call(a, b).ToHandleChecked();
83     CHECK(expected->SameValue(*result));
84   }
85
86   void CheckCall(Handle<Object> expected, Handle<Object> a) {
87     CheckCall(expected, a, undefined());
88   }
89
90   void CheckCall(Handle<Object> expected) {
91     CheckCall(expected, undefined(), undefined());
92   }
93
94   void CheckCall(double expected, double a, double b) {
95     CheckCall(Val(expected), Val(a), Val(b));
96   }
97
98   void CheckTrue(Handle<Object> a, Handle<Object> b) {
99     CheckCall(true_value(), a, b);
100   }
101
102   void CheckTrue(Handle<Object> a) { CheckCall(true_value(), a, undefined()); }
103
104   void CheckTrue(double a, double b) {
105     CheckCall(true_value(), Val(a), Val(b));
106   }
107
108   void CheckFalse(Handle<Object> a, Handle<Object> b) {
109     CheckCall(false_value(), a, b);
110   }
111
112   void CheckFalse(Handle<Object> a) {
113     CheckCall(false_value(), a, undefined());
114   }
115
116   void CheckFalse(double a, double b) {
117     CheckCall(false_value(), Val(a), Val(b));
118   }
119
120   Handle<JSFunction> NewFunction(const char* source) {
121     return v8::Utils::OpenHandle(
122         *v8::Handle<v8::Function>::Cast(CompileRun(source)));
123   }
124
125   Handle<JSObject> NewObject(const char* source) {
126     return v8::Utils::OpenHandle(
127         *v8::Handle<v8::Object>::Cast(CompileRun(source)));
128   }
129
130   Handle<String> Val(const char* string) {
131     return isolate->factory()->InternalizeUtf8String(string);
132   }
133
134   Handle<Object> Val(double value) {
135     return isolate->factory()->NewNumber(value);
136   }
137
138   Handle<Object> infinity() { return isolate->factory()->infinity_value(); }
139
140   Handle<Object> minus_infinity() { return Val(-V8_INFINITY); }
141
142   Handle<Object> nan() { return isolate->factory()->nan_value(); }
143
144   Handle<Object> undefined() { return isolate->factory()->undefined_value(); }
145
146   Handle<Object> null() { return isolate->factory()->null_value(); }
147
148   Handle<Object> true_value() { return isolate->factory()->true_value(); }
149
150   Handle<Object> false_value() { return isolate->factory()->false_value(); }
151
152   Handle<JSFunction> Compile(Handle<JSFunction> function) {
153 // TODO(titzer): make this method private.
154 #if V8_TURBOFAN_TARGET
155     CompilationInfoWithZone info(function);
156
157     CHECK(Parser::Parse(&info));
158     info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
159     if (flags_ & CompilationInfo::kContextSpecializing) {
160       info.MarkAsContextSpecializing();
161     }
162     if (flags_ & CompilationInfo::kInliningEnabled) {
163       info.MarkAsInliningEnabled();
164     }
165     if (flags_ & CompilationInfo::kTypingEnabled) {
166       info.MarkAsTypingEnabled();
167     }
168     CHECK(Compiler::Analyze(&info));
169     CHECK(Compiler::EnsureDeoptimizationSupport(&info));
170
171     Pipeline pipeline(&info);
172     Handle<Code> code = pipeline.GenerateCode();
173     if (FLAG_turbo_deoptimization) {
174       info.context()->native_context()->AddOptimizedCode(*code);
175     }
176
177     CHECK(!code.is_null());
178     function->ReplaceCode(*code);
179 #elif USE_CRANKSHAFT
180     Handle<Code> unoptimized = Handle<Code>(function->code());
181     Handle<Code> code = Compiler::GetOptimizedCode(function, unoptimized,
182                                                    Compiler::NOT_CONCURRENT);
183     CHECK(!code.is_null());
184 #if ENABLE_DISASSEMBLER
185     if (FLAG_print_opt_code) {
186       CodeTracer::Scope tracing_scope(isolate->GetCodeTracer());
187       code->Disassemble("test code", tracing_scope.file());
188     }
189 #endif
190     function->ReplaceCode(*code);
191 #endif
192     return function;
193   }
194
195   static Handle<JSFunction> ForMachineGraph(Graph* graph) {
196     JSFunction* p = NULL;
197     {  // because of the implicit handle scope of FunctionTester.
198       FunctionTester f(graph);
199       p = *f.function;
200     }
201     return Handle<JSFunction>(p);  // allocated in outer handle scope.
202   }
203
204  private:
205   uint32_t flags_;
206
207   // Compile the given machine graph instead of the source of the function
208   // and replace the JSFunction's code with the result.
209   Handle<JSFunction> CompileGraph(Graph* graph) {
210     CHECK(Pipeline::SupportedTarget());
211     CompilationInfoWithZone info(function);
212
213     CHECK(Parser::Parse(&info));
214     info.SetOptimizing(BailoutId::None(),
215                        Handle<Code>(function->shared()->code()));
216     CHECK(Compiler::Analyze(&info));
217     CHECK(Compiler::EnsureDeoptimizationSupport(&info));
218
219     Pipeline pipeline(&info);
220     Linkage linkage(info.zone(), &info);
221     Handle<Code> code = pipeline.GenerateCodeForMachineGraph(&linkage, graph);
222     CHECK(!code.is_null());
223     function->ReplaceCode(*code);
224     return function;
225   }
226 };
227 }
228 }
229 }  // namespace v8::internal::compiler
230
231 #endif  // V8_CCTEST_COMPILER_FUNCTION_TESTER_H_