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