// Copyright 2015 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include "src/compilation-info.h" #include "src/compiler/pipeline.h" #include "src/debug/debug-interface.h" #include "src/execution.h" #include "src/handles.h" #include "src/interpreter/bytecode-array-builder.h" #include "src/interpreter/interpreter.h" #include "src/objects-inl.h" #include "src/parsing/parse-info.h" #include "test/cctest/cctest.h" namespace v8 { namespace internal { namespace compiler { #define SHARD_TEST_BY_2(x) \ TEST(x##_0) { Test##x(0); } \ TEST(x##_1) { Test##x(1); } #define SHARD_TEST_BY_4(x) \ TEST(x##_0) { Test##x(0); } \ TEST(x##_1) { Test##x(1); } \ TEST(x##_2) { Test##x(2); } \ TEST(x##_3) { Test##x(3); } static const char kFunctionName[] = "f"; static const Token::Value kCompareOperators[] = { Token::Value::EQ, Token::Value::NE, Token::Value::EQ_STRICT, Token::Value::NE_STRICT, Token::Value::LT, Token::Value::LTE, Token::Value::GT, Token::Value::GTE}; static const int SMI_MAX = (1 << 30) - 1; static const int SMI_MIN = -(1 << 30); static MaybeHandle CallFunction(Isolate* isolate, Handle function) { return Execution::Call(isolate, function, isolate->factory()->undefined_value(), 0, nullptr); } template static MaybeHandle CallFunction(Isolate* isolate, Handle function, A... args) { Handle argv[] = {args...}; return Execution::Call(isolate, function, isolate->factory()->undefined_value(), sizeof...(args), argv); } template class BytecodeGraphCallable { public: BytecodeGraphCallable(Isolate* isolate, Handle function) : isolate_(isolate), function_(function) {} virtual ~BytecodeGraphCallable() {} MaybeHandle operator()(A... args) { return CallFunction(isolate_, function_, args...); } private: Isolate* isolate_; Handle function_; }; class BytecodeGraphTester { public: BytecodeGraphTester(Isolate* isolate, const char* script, const char* filter = kFunctionName) : isolate_(isolate), script_(script) { i::FLAG_always_opt = false; i::FLAG_allow_natives_syntax = true; } virtual ~BytecodeGraphTester() {} template BytecodeGraphCallable GetCallable( const char* functionName = kFunctionName) { return BytecodeGraphCallable(isolate_, GetFunction(functionName)); } Local CheckThrowsReturnMessage() { TryCatch try_catch(reinterpret_cast(isolate_)); auto callable = GetCallable<>(); MaybeHandle 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 NewObject(const char* script) { return v8::Utils::OpenHandle(*CompileRun(script)); } private: Isolate* isolate_; const char* script_; Handle GetFunction(const char* functionName) { CompileRun(script_); Local api_function = Local::Cast( CcTest::global() ->Get(CcTest::isolate()->GetCurrentContext(), v8_str(functionName)) .ToLocalChecked()); Handle function = Handle::cast(v8::Utils::OpenHandle(*api_function)); CHECK(function->shared()->HasBytecodeArray()); Zone zone(function->GetIsolate()->allocator(), ZONE_NAME); Handle shared(function->shared()); Handle