Line data Source code
1 : // Copyright 2015 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_TEST_CCTEST_INTERPRETER_INTERPRETER_TESTER_H_
6 : #define V8_TEST_CCTEST_INTERPRETER_INTERPRETER_TESTER_H_
7 :
8 : #include "src/v8.h"
9 :
10 : #include "src/api.h"
11 : #include "src/execution.h"
12 : #include "src/handles.h"
13 : #include "src/interpreter/bytecode-array-builder.h"
14 : #include "src/interpreter/interpreter.h"
15 : #include "src/objects/feedback-cell.h"
16 : #include "test/cctest/cctest.h"
17 : #include "test/cctest/test-feedback-vector.h"
18 :
19 : namespace v8 {
20 : namespace internal {
21 : namespace interpreter {
22 :
23 : MaybeHandle<Object> CallInterpreter(Isolate* isolate,
24 : Handle<JSFunction> function);
25 : template <class... A>
26 150 : static MaybeHandle<Object> CallInterpreter(Isolate* isolate,
27 : Handle<JSFunction> function,
28 : A... args) {
29 3875 : Handle<Object> argv[] = {args...};
30 3875 : return Execution::Call(isolate, function,
31 : isolate->factory()->undefined_value(), sizeof...(args),
32 4025 : argv);
33 : }
34 :
35 : template <class... A>
36 : class InterpreterCallable {
37 : public:
38 : InterpreterCallable(Isolate* isolate, Handle<JSFunction> function)
39 10985 : : isolate_(isolate), function_(function) {}
40 21950 : virtual ~InterpreterCallable() = default;
41 :
42 3785 : MaybeHandle<Object> operator()(A... args) {
43 28535 : return CallInterpreter(isolate_, function_, args...);
44 : }
45 :
46 : FeedbackVector vector() const { return function_->feedback_vector(); }
47 :
48 : private:
49 : Isolate* isolate_;
50 : Handle<JSFunction> function_;
51 : };
52 :
53 22025 : class InterpreterTester {
54 : public:
55 : InterpreterTester(Isolate* isolate, const char* source,
56 : MaybeHandle<BytecodeArray> bytecode,
57 : MaybeHandle<FeedbackMetadata> feedback_metadata,
58 : const char* filter);
59 :
60 : InterpreterTester(Isolate* isolate, Handle<BytecodeArray> bytecode,
61 : MaybeHandle<FeedbackMetadata> feedback_metadata =
62 : MaybeHandle<FeedbackMetadata>(),
63 : const char* filter = kFunctionName);
64 :
65 : InterpreterTester(Isolate* isolate, const char* source,
66 : const char* filter = kFunctionName);
67 :
68 : virtual ~InterpreterTester();
69 :
70 : template <class... A>
71 : InterpreterCallable<A...> GetCallable() {
72 22025 : return InterpreterCallable<A...>(isolate_, GetBytecodeFunction<A...>());
73 : }
74 :
75 : Local<Message> CheckThrowsReturnMessage();
76 :
77 : static Handle<Object> NewObject(const char* script);
78 :
79 : static Handle<String> GetName(Isolate* isolate, const char* name);
80 :
81 : static std::string SourceForBody(const char* body);
82 :
83 : static std::string function_name();
84 :
85 : static const char kFunctionName[];
86 :
87 : // Expose raw RegisterList construction to tests.
88 : static RegisterList NewRegisterList(int first_reg_index, int register_count) {
89 : return RegisterList(first_reg_index, register_count);
90 : }
91 :
92 : inline bool HasFeedbackMetadata() { return !feedback_metadata_.is_null(); }
93 :
94 : private:
95 : Isolate* isolate_;
96 : const char* source_;
97 : MaybeHandle<BytecodeArray> bytecode_;
98 : MaybeHandle<FeedbackMetadata> feedback_metadata_;
99 :
100 : template <class... A>
101 22025 : Handle<JSFunction> GetBytecodeFunction() {
102 : Handle<JSFunction> function;
103 22025 : if (source_) {
104 : CompileRun(source_);
105 : v8::Local<v8::Context> context =
106 2625 : v8::Isolate::GetCurrent()->GetCurrentContext();
107 : Local<Function> api_function =
108 2625 : Local<Function>::Cast(CcTest::global()
109 7875 : ->Get(context, v8_str(kFunctionName))
110 : .ToLocalChecked());
111 : function = Handle<JSFunction>::cast(v8::Utils::OpenHandle(*api_function));
112 : } else {
113 : int arg_count = sizeof...(A);
114 58200 : std::string source("(function " + function_name() + "(");
115 1570 : for (int i = 0; i < arg_count; i++) {
116 600 : source += i == 0 ? "a" : ", a";
117 : }
118 : source += "){})";
119 : function = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
120 : *v8::Local<v8::Function>::Cast(CompileRun(source.c_str()))));
121 58200 : function->set_code(*BUILTIN_CODE(isolate_, InterpreterEntryTrampoline));
122 : }
123 :
124 22025 : if (!bytecode_.is_null()) {
125 38800 : function->shared()->set_function_data(*bytecode_.ToHandleChecked());
126 : }
127 22025 : if (HasFeedbackMetadata()) {
128 34110 : function->set_raw_feedback_cell(isolate_->heap()->many_closures_cell());
129 : // Set the raw feedback metadata to circumvent checks that we are not
130 : // overwriting existing metadata.
131 34110 : function->shared()->set_raw_outer_scope_info_or_feedback_metadata(
132 : *feedback_metadata_.ToHandleChecked());
133 17055 : JSFunction::EnsureFeedbackVector(function);
134 : }
135 22025 : return function;
136 : }
137 :
138 : DISALLOW_COPY_AND_ASSIGN(InterpreterTester);
139 : };
140 :
141 : } // namespace interpreter
142 : } // namespace internal
143 : } // namespace v8
144 :
145 : #endif // V8_TEST_CCTEST_INTERPRETER_INTERPRETER_TESTER_H_
|