| 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;
 | 
| 
 |