blob: 4e202eada58a2e9e703195d464e2e4a50787890c [file] [log] [blame]
Ben Murdochda12d292016-06-02 14:46:10 +01001// 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#include "src/v8.h"
6
7#include "src/execution.h"
8#include "src/handles.h"
9#include "src/interpreter/bytecode-array-builder.h"
10#include "src/interpreter/interpreter.h"
11#include "test/cctest/cctest.h"
12#include "test/cctest/test-feedback-vector.h"
13
14namespace v8 {
15namespace internal {
16namespace interpreter {
17
18MaybeHandle<Object> CallInterpreter(Isolate* isolate,
19 Handle<JSFunction> function);
20template <class... A>
21static MaybeHandle<Object> CallInterpreter(Isolate* isolate,
22 Handle<JSFunction> function,
23 A... args) {
24 Handle<Object> argv[] = {args...};
25 return Execution::Call(isolate, function,
26 isolate->factory()->undefined_value(), sizeof...(args),
27 argv);
28}
29
30template <class... A>
31class InterpreterCallable {
32 public:
33 InterpreterCallable(Isolate* isolate, Handle<JSFunction> function)
34 : isolate_(isolate), function_(function) {}
35 virtual ~InterpreterCallable() {}
36
37 MaybeHandle<Object> operator()(A... args) {
38 return CallInterpreter(isolate_, function_, args...);
39 }
40
41 private:
42 Isolate* isolate_;
43 Handle<JSFunction> function_;
44};
45
46namespace {
47const char kFunctionName[] = "f";
48} // namespace
49
50class InterpreterTester {
51 public:
52 InterpreterTester(Isolate* isolate, const char* source,
53 MaybeHandle<BytecodeArray> bytecode,
54 MaybeHandle<TypeFeedbackVector> feedback_vector,
55 const char* filter);
56
57 InterpreterTester(Isolate* isolate, Handle<BytecodeArray> bytecode,
58 MaybeHandle<TypeFeedbackVector> feedback_vector =
59 MaybeHandle<TypeFeedbackVector>(),
60 const char* filter = kFunctionName);
61
62 InterpreterTester(Isolate* isolate, const char* source,
63 const char* filter = kFunctionName);
64
65 virtual ~InterpreterTester();
66
67 template <class... A>
68 InterpreterCallable<A...> GetCallable() {
69 return InterpreterCallable<A...>(isolate_, GetBytecodeFunction<A...>());
70 }
71
72 Local<Message> CheckThrowsReturnMessage();
73
74 static Handle<Object> NewObject(const char* script);
75
76 static Handle<String> GetName(Isolate* isolate, const char* name);
77
78 static std::string SourceForBody(const char* body);
79
80 static std::string function_name();
81
82 private:
83 Isolate* isolate_;
84 const char* source_;
85 MaybeHandle<BytecodeArray> bytecode_;
86 MaybeHandle<TypeFeedbackVector> feedback_vector_;
87
88 template <class... A>
89 Handle<JSFunction> GetBytecodeFunction() {
90 Handle<JSFunction> function;
91 if (source_) {
92 CompileRun(source_);
93 v8::Local<v8::Context> context =
94 v8::Isolate::GetCurrent()->GetCurrentContext();
95 Local<Function> api_function =
96 Local<Function>::Cast(CcTest::global()
97 ->Get(context, v8_str(kFunctionName))
98 .ToLocalChecked());
99 function = Handle<JSFunction>::cast(v8::Utils::OpenHandle(*api_function));
100 } else {
101 int arg_count = sizeof...(A);
102 std::string source("(function " + function_name() + "(");
103 for (int i = 0; i < arg_count; i++) {
104 source += i == 0 ? "a" : ", a";
105 }
106 source += "){})";
107 function = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
108 *v8::Local<v8::Function>::Cast(CompileRun(source.c_str()))));
109 function->ReplaceCode(
110 *isolate_->builtins()->InterpreterEntryTrampoline());
111 }
112
113 if (!bytecode_.is_null()) {
114 function->shared()->set_function_data(*bytecode_.ToHandleChecked());
115 }
116 if (!feedback_vector_.is_null()) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100117 function->literals()->set_feedback_vector(
Ben Murdochda12d292016-06-02 14:46:10 +0100118 *feedback_vector_.ToHandleChecked());
119 }
120 return function;
121 }
122
123 DISALLOW_COPY_AND_ASSIGN(InterpreterTester);
124};
125
126} // namespace interpreter
127} // namespace internal
128} // namespace v8