• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #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 
14 namespace v8 {
15 namespace internal {
16 namespace interpreter {
17 
18 MaybeHandle<Object> CallInterpreter(Isolate* isolate,
19                                     Handle<JSFunction> function);
20 template <class... A>
CallInterpreter(Isolate * isolate,Handle<JSFunction> function,A...args)21 static 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 
30 template <class... A>
31 class InterpreterCallable {
32  public:
InterpreterCallable(Isolate * isolate,Handle<JSFunction> function)33   InterpreterCallable(Isolate* isolate, Handle<JSFunction> function)
34       : isolate_(isolate), function_(function) {}
~InterpreterCallable()35   virtual ~InterpreterCallable() {}
36 
operator()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 
46 namespace {
47 const char kFunctionName[] = "f";
48 }  // namespace
49 
50 class 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>
GetCallable()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>
GetBytecodeFunction()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()) {
117       function->literals()->set_feedback_vector(
118           *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
129