17d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved. 27d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 37d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// found in the LICENSE file. 47d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 57d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifndef V8_CCTEST_COMPILER_FUNCTION_TESTER_H_ 67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define V8_CCTEST_COMPILER_FUNCTION_TESTER_H_ 77d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 87d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/v8.h" 97d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "test/cctest/cctest.h" 107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler.h" 127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/pipeline.h" 137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/execution.h" 147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/full-codegen.h" 157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/handles.h" 167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/objects-inl.h" 177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/parser.h" 187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/rewriter.h" 197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/scopes.h" 207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define USE_CRANKSHAFT 0 227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace v8 { 247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace internal { 257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace compiler { 267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass FunctionTester : public InitializedHandleScope { 287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 29c714f377950c6a8a80b90ddca93ad8bd23ce362amachenbach@chromium.org explicit FunctionTester(const char* source, uint32_t flags = 0) 307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : isolate(main_isolate()), 31a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org function((FLAG_allow_natives_syntax = true, NewFunction(source))), 32c714f377950c6a8a80b90ddca93ad8bd23ce362amachenbach@chromium.org flags_(flags) { 337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Compile(function); 34c714f377950c6a8a80b90ddca93ad8bd23ce362amachenbach@chromium.org const uint32_t supported_flags = CompilationInfo::kContextSpecializing | 35c6509d2e0fb825426296fbc357cf89f2c77ff434machenbach@chromium.org CompilationInfo::kInliningEnabled | 36c6509d2e0fb825426296fbc357cf89f2c77ff434machenbach@chromium.org CompilationInfo::kTypingEnabled; 37c714f377950c6a8a80b90ddca93ad8bd23ce362amachenbach@chromium.org CHECK_EQ(0, flags_ & ~supported_flags); 387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Isolate* isolate; 417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<JSFunction> function; 427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<JSFunction> Compile(Handle<JSFunction> function) { 447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#if V8_TURBOFAN_TARGET 457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CompilationInfoWithZone info(function); 467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(Parser::Parse(&info)); 487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code())); 49c714f377950c6a8a80b90ddca93ad8bd23ce362amachenbach@chromium.org if (flags_ & CompilationInfo::kContextSpecializing) { 50c714f377950c6a8a80b90ddca93ad8bd23ce362amachenbach@chromium.org info.MarkAsContextSpecializing(); 51c714f377950c6a8a80b90ddca93ad8bd23ce362amachenbach@chromium.org } 52c714f377950c6a8a80b90ddca93ad8bd23ce362amachenbach@chromium.org if (flags_ & CompilationInfo::kInliningEnabled) { 53c714f377950c6a8a80b90ddca93ad8bd23ce362amachenbach@chromium.org info.MarkAsInliningEnabled(); 54c714f377950c6a8a80b90ddca93ad8bd23ce362amachenbach@chromium.org } 55c6509d2e0fb825426296fbc357cf89f2c77ff434machenbach@chromium.org if (flags_ & CompilationInfo::kTypingEnabled) { 56c6509d2e0fb825426296fbc357cf89f2c77ff434machenbach@chromium.org info.MarkAsTypingEnabled(); 57c6509d2e0fb825426296fbc357cf89f2c77ff434machenbach@chromium.org } 587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(Rewriter::Rewrite(&info)); 597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(Scope::Analyze(&info)); 60a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org CHECK(Compiler::EnsureDeoptimizationSupport(&info)); 617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Pipeline pipeline(&info); 637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Code> code = pipeline.GenerateCode(); 649e2b466e4b4a2026caefa79afe6737f1bad83a19machenbach@chromium.org if (FLAG_turbo_deoptimization) { 659e2b466e4b4a2026caefa79afe6737f1bad83a19machenbach@chromium.org info.context()->native_context()->AddOptimizedCode(*code); 669e2b466e4b4a2026caefa79afe6737f1bad83a19machenbach@chromium.org } 677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(!code.is_null()); 697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org function->ReplaceCode(*code); 707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#elif USE_CRANKSHAFT 717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Code> unoptimized = Handle<Code>(function->code()); 727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Code> code = Compiler::GetOptimizedCode(function, unoptimized, 737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Compiler::NOT_CONCURRENT); 747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(!code.is_null()); 757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#if ENABLE_DISASSEMBLER 767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (FLAG_print_opt_code) { 777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CodeTracer::Scope tracing_scope(isolate->GetCodeTracer()); 787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org code->Disassemble("test code", tracing_scope.file()); 797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif 817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org function->ReplaceCode(*code); 827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif 837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return function; 847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org MaybeHandle<Object> Call(Handle<Object> a, Handle<Object> b) { 877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Object> args[] = {a, b}; 887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return Execution::Call(isolate, function, undefined(), 2, args, false); 897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void CheckThrows(Handle<Object> a, Handle<Object> b) { 927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org TryCatch try_catch; 937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org MaybeHandle<Object> no_result = Call(a, b); 947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(isolate->has_pending_exception()); 957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(try_catch.HasCaught()); 967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(no_result.is_null()); 977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // TODO(mstarzinger): Temporary workaround for issue chromium:362388. 987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org isolate->OptionalRescheduleException(true); 997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org v8::Handle<v8::Message> CheckThrowsReturnMessage(Handle<Object> a, 1027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Object> b) { 1037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org TryCatch try_catch; 1047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org MaybeHandle<Object> no_result = Call(a, b); 1057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(isolate->has_pending_exception()); 1067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(try_catch.HasCaught()); 1077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(no_result.is_null()); 1087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // TODO(mstarzinger): Calling OptionalRescheduleException is a dirty hack, 1097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // it's the only way to make Message() not to assert because an external 1107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // exception has been caught by the try_catch. 1117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org isolate->OptionalRescheduleException(true); 1127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return try_catch.Message(); 1137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void CheckCall(Handle<Object> expected, Handle<Object> a, Handle<Object> b) { 1167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Object> result = Call(a, b).ToHandleChecked(); 1177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(expected->SameValue(*result)); 1187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void CheckCall(Handle<Object> expected, Handle<Object> a) { 1217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CheckCall(expected, a, undefined()); 1227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void CheckCall(Handle<Object> expected) { 1257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CheckCall(expected, undefined(), undefined()); 1267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void CheckCall(double expected, double a, double b) { 1297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CheckCall(Val(expected), Val(a), Val(b)); 1307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void CheckTrue(Handle<Object> a, Handle<Object> b) { 1337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CheckCall(true_value(), a, b); 1347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void CheckTrue(Handle<Object> a) { CheckCall(true_value(), a, undefined()); } 1377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void CheckTrue(double a, double b) { 1397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CheckCall(true_value(), Val(a), Val(b)); 1407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void CheckFalse(Handle<Object> a, Handle<Object> b) { 1437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CheckCall(false_value(), a, b); 1447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void CheckFalse(Handle<Object> a) { 1477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CheckCall(false_value(), a, undefined()); 1487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void CheckFalse(double a, double b) { 1517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CheckCall(false_value(), Val(a), Val(b)); 1527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<JSFunction> NewFunction(const char* source) { 1557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return v8::Utils::OpenHandle( 1567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *v8::Handle<v8::Function>::Cast(CompileRun(source))); 1577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<JSObject> NewObject(const char* source) { 1607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return v8::Utils::OpenHandle( 1617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *v8::Handle<v8::Object>::Cast(CompileRun(source))); 1627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<String> Val(const char* string) { 1657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return isolate->factory()->InternalizeUtf8String(string); 1667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Object> Val(double value) { 1697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return isolate->factory()->NewNumber(value); 1707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Object> infinity() { return isolate->factory()->infinity_value(); } 1737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Object> minus_infinity() { return Val(-V8_INFINITY); } 1757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Object> nan() { return isolate->factory()->nan_value(); } 1777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Object> undefined() { return isolate->factory()->undefined_value(); } 1797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Object> null() { return isolate->factory()->null_value(); } 1817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Object> true_value() { return isolate->factory()->true_value(); } 1837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Object> false_value() { return isolate->factory()->false_value(); } 185a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 186a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org private: 187c714f377950c6a8a80b90ddca93ad8bd23ce362amachenbach@chromium.org uint32_t flags_; 1887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 1897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 1907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 1917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} // namespace v8::internal::compiler 1927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif // V8_CCTEST_COMPILER_FUNCTION_TESTER_H_ 194