// Copyright 2014 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_CCTEST_COMPILER_FUNCTION_TESTER_H_ #define V8_CCTEST_COMPILER_FUNCTION_TESTER_H_ #include "src/execution/execution.h" #include "src/handles/handles.h" #include "test/cctest/cctest.h" namespace v8 { namespace internal { class CallInterfaceDescriptor; class Isolate; namespace compiler { class Graph; class FunctionTester : public InitializedHandleScope { public: explicit FunctionTester(const char* source, uint32_t flags = 0); FunctionTester(Graph* graph, int param_count); FunctionTester(Handle<Code> code, int param_count); // Assumes VoidDescriptor call interface. explicit FunctionTester(Handle<Code> code); Isolate* isolate; CanonicalHandleScope canonical; Handle<JSFunction> function; MaybeHandle<Object> Call() { return Execution::Call(isolate, function, undefined(), 0, nullptr); } template <typename Arg1, typename... Args> MaybeHandle<Object> Call(Arg1 arg1, Args... args) { const int nof_args = sizeof...(Args) + 1; Handle<Object> call_args[] = {arg1, args...}; return Execution::Call(isolate, function, undefined(), nof_args, call_args); } template <typename T, typename... Args> Handle<T> CallChecked(Args... args) { Handle<Object> result = Call(args...).ToHandleChecked(); return Handle<T>::cast(result); } void CheckThrows(Handle<Object> a); void CheckThrows(Handle<Object> a, Handle<Object> b); v8::Local<v8::Message> CheckThrowsReturnMessage(Handle<Object> a, Handle<Object> b); void CheckCall(Handle<Object> expected, Handle<Object> a, Handle<Object> b, Handle<Object> c, Handle<Object> d); void CheckCall(Handle<Object> expected, Handle<Object> a, Handle<Object> b, Handle<Object> c) { return CheckCall(expected, a, b, c, undefined()); } void CheckCall(Handle<Object> expected, Handle<Object> a, Handle<Object> b) { return CheckCall(expected, a, b, undefined()); } void CheckCall(Handle<Object> expected, Handle<Object> a) { CheckCall(expected, a, undefined()); } void CheckCall(Handle<Object> expected) { CheckCall(expected, undefined()); } void CheckCall(double expected, double a, double b) { CheckCall(Val(expected), Val(a), Val(b)); } void CheckTrue(Handle<Object> a) { CheckCall(true_value(), a); } void CheckTrue(Handle<Object> a, Handle<Object> b) { CheckCall(true_value(), a, b); } void CheckTrue(Handle<Object> a, Handle<Object> b, Handle<Object> c) { CheckCall(true_value(), a, b, c); } void CheckTrue(Handle<Object> a, Handle<Object> b, Handle<Object> c, Handle<Object> d) { CheckCall(true_value(), a, b, c, d); } void CheckTrue(double a, double b) { CheckCall(true_value(), Val(a), Val(b)); } void CheckFalse(Handle<Object> a) { CheckCall(false_value(), a); } void CheckFalse(Handle<Object> a, Handle<Object> b) { CheckCall(false_value(), a, b); } void CheckFalse(double a, double b) { CheckCall(false_value(), Val(a), Val(b)); } Handle<JSFunction> NewFunction(const char* source); Handle<JSObject> NewObject(const char* source); Handle<String> Val(const char* string); Handle<Object> Val(double value); Handle<Object> infinity(); Handle<Object> minus_infinity(); Handle<Object> nan(); Handle<Object> undefined(); Handle<Object> null(); Handle<Object> true_value(); Handle<Object> false_value(); static Handle<JSFunction> ForMachineGraph(Graph* graph, int param_count); private: uint32_t flags_; Handle<JSFunction> Compile(Handle<JSFunction> function); std::string BuildFunction(int param_count) { std::string function_string = "(function("; if (param_count > 0) { function_string += 'a'; for (int i = 1; i < param_count; i++) { function_string += ','; function_string += static_cast<char>('a' + i); } } function_string += "){})"; return function_string; } // Compile the given machine graph instead of the source of the function // and replace the JSFunction's code with the result. Handle<JSFunction> CompileGraph(Graph* graph); }; } // namespace compiler } // namespace internal } // namespace v8 #endif // V8_CCTEST_COMPILER_FUNCTION_TESTER_H_