OLD | NEW |
(Empty) | |
| 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 #include "test/cctest/compiler/function-tester.h" |
| 6 |
| 7 #include "src/ast/ast-numbering.h" |
| 8 #include "src/compiler.h" |
| 9 #include "src/compiler/linkage.h" |
| 10 #include "src/compiler/pipeline.h" |
| 11 #include "src/execution.h" |
| 12 #include "src/full-codegen/full-codegen.h" |
| 13 #include "src/handles.h" |
| 14 #include "src/objects-inl.h" |
| 15 #include "src/parsing/parse-info.h" |
| 16 #include "src/parsing/parser.h" |
| 17 #include "test/cctest/cctest.h" |
| 18 |
| 19 namespace v8 { |
| 20 namespace internal { |
| 21 namespace compiler { |
| 22 |
| 23 FunctionTester::FunctionTester(const char* source, uint32_t flags) |
| 24 : isolate(main_isolate()), |
| 25 function((FLAG_allow_natives_syntax = true, NewFunction(source))), |
| 26 flags_(flags) { |
| 27 Compile(function); |
| 28 const uint32_t supported_flags = CompilationInfo::kNativeContextSpecializing | |
| 29 CompilationInfo::kInliningEnabled; |
| 30 CHECK_EQ(0u, flags_ & ~supported_flags); |
| 31 } |
| 32 |
| 33 FunctionTester::FunctionTester(Graph* graph, int param_count) |
| 34 : isolate(main_isolate()), |
| 35 function(NewFunction(BuildFunction(param_count).c_str())), |
| 36 flags_(0) { |
| 37 CompileGraph(graph); |
| 38 } |
| 39 |
| 40 FunctionTester::FunctionTester(Handle<Code> code, int param_count) |
| 41 : isolate(main_isolate()), |
| 42 function((FLAG_allow_natives_syntax = true, |
| 43 NewFunction(BuildFunction(param_count).c_str()))), |
| 44 flags_(0) { |
| 45 Compile(function); |
| 46 function->ReplaceCode(*code); |
| 47 } |
| 48 |
| 49 FunctionTester::FunctionTester(const CallInterfaceDescriptor& descriptor, |
| 50 Handle<Code> code) |
| 51 : FunctionTester(code, descriptor.GetParameterCount()) {} |
| 52 |
| 53 MaybeHandle<Object> FunctionTester::Call() { |
| 54 return Execution::Call(isolate, function, undefined(), 0, nullptr); |
| 55 } |
| 56 |
| 57 MaybeHandle<Object> FunctionTester::Call(Handle<Object> a) { |
| 58 Handle<Object> args[] = {a}; |
| 59 return Execution::Call(isolate, function, undefined(), 1, args); |
| 60 } |
| 61 |
| 62 MaybeHandle<Object> FunctionTester::Call(Handle<Object> a, Handle<Object> b) { |
| 63 Handle<Object> args[] = {a, b}; |
| 64 return Execution::Call(isolate, function, undefined(), 2, args); |
| 65 } |
| 66 |
| 67 MaybeHandle<Object> FunctionTester::Call(Handle<Object> a, Handle<Object> b, |
| 68 Handle<Object> c) { |
| 69 Handle<Object> args[] = {a, b, c}; |
| 70 return Execution::Call(isolate, function, undefined(), 3, args); |
| 71 } |
| 72 |
| 73 MaybeHandle<Object> FunctionTester::Call(Handle<Object> a, Handle<Object> b, |
| 74 Handle<Object> c, Handle<Object> d) { |
| 75 Handle<Object> args[] = {a, b, c, d}; |
| 76 return Execution::Call(isolate, function, undefined(), 4, args); |
| 77 } |
| 78 |
| 79 void FunctionTester::CheckThrows(Handle<Object> a, Handle<Object> b) { |
| 80 TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate)); |
| 81 MaybeHandle<Object> no_result = Call(a, b); |
| 82 CHECK(isolate->has_pending_exception()); |
| 83 CHECK(try_catch.HasCaught()); |
| 84 CHECK(no_result.is_null()); |
| 85 isolate->OptionalRescheduleException(true); |
| 86 } |
| 87 |
| 88 v8::Local<v8::Message> FunctionTester::CheckThrowsReturnMessage( |
| 89 Handle<Object> a, Handle<Object> b) { |
| 90 TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate)); |
| 91 MaybeHandle<Object> no_result = Call(a, b); |
| 92 CHECK(isolate->has_pending_exception()); |
| 93 CHECK(try_catch.HasCaught()); |
| 94 CHECK(no_result.is_null()); |
| 95 isolate->OptionalRescheduleException(true); |
| 96 CHECK(!try_catch.Message().IsEmpty()); |
| 97 return try_catch.Message(); |
| 98 } |
| 99 |
| 100 Handle<String> FunctionTester::Val(const char* string) { |
| 101 return isolate->factory()->InternalizeUtf8String(string); |
| 102 } |
| 103 |
| 104 Handle<Object> FunctionTester::Val(double value) { |
| 105 return isolate->factory()->NewNumber(value); |
| 106 } |
| 107 |
| 108 Handle<Object> FunctionTester::infinity() { |
| 109 return isolate->factory()->infinity_value(); |
| 110 } |
| 111 |
| 112 Handle<Object> FunctionTester::minus_infinity() { return Val(-V8_INFINITY); } |
| 113 |
| 114 Handle<Object> FunctionTester::nan() { return isolate->factory()->nan_value(); } |
| 115 |
| 116 Handle<Object> FunctionTester::undefined() { |
| 117 return isolate->factory()->undefined_value(); |
| 118 } |
| 119 |
| 120 Handle<Object> FunctionTester::null() { |
| 121 return isolate->factory()->null_value(); |
| 122 } |
| 123 |
| 124 Handle<Object> FunctionTester::true_value() { |
| 125 return isolate->factory()->true_value(); |
| 126 } |
| 127 |
| 128 Handle<Object> FunctionTester::false_value() { |
| 129 return isolate->factory()->false_value(); |
| 130 } |
| 131 |
| 132 Handle<JSFunction> FunctionTester::Compile(Handle<JSFunction> function) { |
| 133 Zone zone(function->GetIsolate()->allocator()); |
| 134 ParseInfo parse_info(&zone, function); |
| 135 CompilationInfo info(&parse_info, function); |
| 136 info.MarkAsDeoptimizationEnabled(); |
| 137 |
| 138 if (!FLAG_turbo_from_bytecode) { |
| 139 CHECK(Parser::ParseStatic(info.parse_info())); |
| 140 } |
| 141 info.SetOptimizing(); |
| 142 if (flags_ & CompilationInfo::kNativeContextSpecializing) { |
| 143 info.MarkAsNativeContextSpecializing(); |
| 144 } |
| 145 if (flags_ & CompilationInfo::kInliningEnabled) { |
| 146 info.MarkAsInliningEnabled(); |
| 147 } |
| 148 if (FLAG_turbo_from_bytecode) { |
| 149 CHECK(Compiler::EnsureBytecode(&info)); |
| 150 info.MarkAsOptimizeFromBytecode(); |
| 151 } else { |
| 152 CHECK(Compiler::Analyze(info.parse_info())); |
| 153 CHECK(Compiler::EnsureDeoptimizationSupport(&info)); |
| 154 } |
| 155 JSFunction::EnsureLiterals(function); |
| 156 |
| 157 Handle<Code> code = Pipeline::GenerateCodeForTesting(&info); |
| 158 CHECK(!code.is_null()); |
| 159 info.dependencies()->Commit(code); |
| 160 info.context()->native_context()->AddOptimizedCode(*code); |
| 161 function->ReplaceCode(*code); |
| 162 return function; |
| 163 } |
| 164 |
| 165 // Compile the given machine graph instead of the source of the function |
| 166 // and replace the JSFunction's code with the result. |
| 167 Handle<JSFunction> FunctionTester::CompileGraph(Graph* graph) { |
| 168 Zone zone(function->GetIsolate()->allocator()); |
| 169 ParseInfo parse_info(&zone, function); |
| 170 CompilationInfo info(&parse_info, function); |
| 171 |
| 172 CHECK(Parser::ParseStatic(info.parse_info())); |
| 173 info.SetOptimizing(); |
| 174 |
| 175 Handle<Code> code = Pipeline::GenerateCodeForTesting(&info, graph); |
| 176 CHECK(!code.is_null()); |
| 177 function->ReplaceCode(*code); |
| 178 return function; |
| 179 } |
| 180 |
| 181 } // namespace compiler |
| 182 } // namespace internal |
| 183 } // namespace v8 |
OLD | NEW |