| Index: test/cctest/interpreter/test-interpreter.cc
|
| diff --git a/test/cctest/interpreter/test-interpreter.cc b/test/cctest/interpreter/test-interpreter.cc
|
| index 67191caabafe758598abd458bfef1ee08a8049b4..8f236a14392962ed508da3658c2ef6d9de24c220 100644
|
| --- a/test/cctest/interpreter/test-interpreter.cc
|
| +++ b/test/cctest/interpreter/test-interpreter.cc
|
| @@ -9,6 +9,7 @@
|
| #include "src/interpreter/bytecode-array-builder.h"
|
| #include "src/interpreter/interpreter.h"
|
| #include "test/cctest/cctest.h"
|
| +#include "test/cctest/interpreter/interpreter-tester.h"
|
| #include "test/cctest/test-feedback-vector.h"
|
|
|
| namespace v8 {
|
| @@ -16,160 +17,6 @@ namespace internal {
|
| namespace interpreter {
|
|
|
|
|
| -static MaybeHandle<Object> CallInterpreter(Isolate* isolate,
|
| - Handle<JSFunction> function) {
|
| - return Execution::Call(isolate, function,
|
| - isolate->factory()->undefined_value(), 0, nullptr);
|
| -}
|
| -
|
| -
|
| -template <class... A>
|
| -static MaybeHandle<Object> CallInterpreter(Isolate* isolate,
|
| - Handle<JSFunction> function,
|
| - A... args) {
|
| - Handle<Object> argv[] = { args... };
|
| - return Execution::Call(isolate, function,
|
| - isolate->factory()->undefined_value(), sizeof...(args),
|
| - argv);
|
| -}
|
| -
|
| -
|
| -template <class... A>
|
| -class InterpreterCallable {
|
| - public:
|
| - InterpreterCallable(Isolate* isolate, Handle<JSFunction> function)
|
| - : isolate_(isolate), function_(function) {}
|
| - virtual ~InterpreterCallable() {}
|
| -
|
| - MaybeHandle<Object> operator()(A... args) {
|
| - return CallInterpreter(isolate_, function_, args...);
|
| - }
|
| -
|
| - private:
|
| - Isolate* isolate_;
|
| - Handle<JSFunction> function_;
|
| -};
|
| -
|
| -
|
| -static const char* kFunctionName = "f";
|
| -
|
| -
|
| -class InterpreterTester {
|
| - public:
|
| - InterpreterTester(Isolate* isolate, const char* source,
|
| - MaybeHandle<BytecodeArray> bytecode,
|
| - MaybeHandle<TypeFeedbackVector> feedback_vector,
|
| - const char* filter)
|
| - : isolate_(isolate),
|
| - source_(source),
|
| - bytecode_(bytecode),
|
| - feedback_vector_(feedback_vector) {
|
| - i::FLAG_ignition = true;
|
| - i::FLAG_always_opt = false;
|
| - // Set ignition filter flag via SetFlagsFromString to avoid double-free
|
| - // (or potential leak with StrDup() based on ownership confusion).
|
| - ScopedVector<char> ignition_filter(64);
|
| - SNPrintF(ignition_filter, "--ignition-filter=%s", filter);
|
| - FlagList::SetFlagsFromString(ignition_filter.start(),
|
| - ignition_filter.length());
|
| - // Ensure handler table is generated.
|
| - isolate->interpreter()->Initialize();
|
| - }
|
| -
|
| - InterpreterTester(Isolate* isolate, Handle<BytecodeArray> bytecode,
|
| - MaybeHandle<TypeFeedbackVector> feedback_vector =
|
| - MaybeHandle<TypeFeedbackVector>(),
|
| - const char* filter = kFunctionName)
|
| - : InterpreterTester(isolate, nullptr, bytecode, feedback_vector, filter) {
|
| - }
|
| -
|
| -
|
| - InterpreterTester(Isolate* isolate, const char* source,
|
| - const char* filter = kFunctionName)
|
| - : InterpreterTester(isolate, source, MaybeHandle<BytecodeArray>(),
|
| - MaybeHandle<TypeFeedbackVector>(), filter) {}
|
| -
|
| - virtual ~InterpreterTester() {}
|
| -
|
| - template <class... A>
|
| - InterpreterCallable<A...> GetCallable() {
|
| - return InterpreterCallable<A...>(isolate_, GetBytecodeFunction<A...>());
|
| - }
|
| -
|
| - Local<Message> CheckThrowsReturnMessage() {
|
| - TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate_));
|
| - auto callable = GetCallable<>();
|
| - MaybeHandle<Object> no_result = callable();
|
| - CHECK(isolate_->has_pending_exception());
|
| - CHECK(try_catch.HasCaught());
|
| - CHECK(no_result.is_null());
|
| - isolate_->OptionalRescheduleException(true);
|
| - CHECK(!try_catch.Message().IsEmpty());
|
| - return try_catch.Message();
|
| - }
|
| -
|
| - static Handle<Object> NewObject(const char* script) {
|
| - return v8::Utils::OpenHandle(*CompileRun(script));
|
| - }
|
| -
|
| - static Handle<String> GetName(Isolate* isolate, const char* name) {
|
| - Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(name);
|
| - return isolate->factory()->string_table()->LookupString(isolate, result);
|
| - }
|
| -
|
| - static std::string SourceForBody(const char* body) {
|
| - return "function " + function_name() + "() {\n" + std::string(body) + "\n}";
|
| - }
|
| -
|
| - static std::string function_name() {
|
| - return std::string(kFunctionName);
|
| - }
|
| -
|
| - private:
|
| - Isolate* isolate_;
|
| - const char* source_;
|
| - MaybeHandle<BytecodeArray> bytecode_;
|
| - MaybeHandle<TypeFeedbackVector> feedback_vector_;
|
| -
|
| - template <class... A>
|
| - Handle<JSFunction> GetBytecodeFunction() {
|
| - Handle<JSFunction> function;
|
| - if (source_) {
|
| - CompileRun(source_);
|
| - v8::Local<v8::Context> context =
|
| - v8::Isolate::GetCurrent()->GetCurrentContext();
|
| - Local<Function> api_function =
|
| - Local<Function>::Cast(CcTest::global()
|
| - ->Get(context, v8_str(kFunctionName))
|
| - .ToLocalChecked());
|
| - function = Handle<JSFunction>::cast(v8::Utils::OpenHandle(*api_function));
|
| - } else {
|
| - int arg_count = sizeof...(A);
|
| - std::string source("(function " + function_name() + "(");
|
| - for (int i = 0; i < arg_count; i++) {
|
| - source += i == 0 ? "a" : ", a";
|
| - }
|
| - source += "){})";
|
| - function = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
|
| - *v8::Local<v8::Function>::Cast(CompileRun(source.c_str()))));
|
| - function->ReplaceCode(
|
| - *isolate_->builtins()->InterpreterEntryTrampoline());
|
| - }
|
| -
|
| - if (!bytecode_.is_null()) {
|
| - function->shared()->set_function_data(*bytecode_.ToHandleChecked());
|
| - }
|
| - if (!feedback_vector_.is_null()) {
|
| - function->shared()->set_feedback_vector(
|
| - *feedback_vector_.ToHandleChecked());
|
| - }
|
| - return function;
|
| - }
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(InterpreterTester);
|
| -};
|
| -
|
| -
|
| TEST(InterpreterReturn) {
|
| HandleAndZoneScope handles;
|
| Handle<Object> undefined_value =
|
| @@ -1639,6 +1486,24 @@ TEST(InterpreterCallRuntime) {
|
| CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(55));
|
| }
|
|
|
| +TEST(InterpreterInvokeIntrinsic) {
|
| + HandleAndZoneScope handles;
|
| +
|
| + BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1,
|
| + 0, 2);
|
| + builder.LoadLiteral(Smi::FromInt(15))
|
| + .StoreAccumulatorInRegister(Register(0))
|
| + .CallRuntime(Runtime::kInlineIsArray, Register(0), 1)
|
| + .Return();
|
| + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
|
| +
|
| + InterpreterTester tester(handles.main_isolate(), bytecode_array);
|
| + auto callable = tester.GetCallable<>();
|
| +
|
| + Handle<Object> return_val = callable().ToHandleChecked();
|
| + CHECK(return_val->IsBoolean());
|
| + CHECK_EQ(return_val->BooleanValue(), false);
|
| +}
|
|
|
| TEST(InterpreterFunctionLiteral) {
|
| HandleAndZoneScope handles;
|
|
|