v8/test/cctest/compiler/function-tester.h
mstarzinger@chromium.org cc8cec354c Preliminary lowering of typed array loads in TF.
R=titzer@chromium.org
TEST=cctest/test-run-properties/TypedArrayLoad

Review URL: https://codereview.chromium.org/516853002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23492 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2014-08-28 14:35:11 +00:00

214 lines
6.8 KiB
C++

// Copyright 2014 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.
#ifndef V8_CCTEST_COMPILER_FUNCTION_TESTER_H_
#define V8_CCTEST_COMPILER_FUNCTION_TESTER_H_
#include "src/v8.h"
#include "test/cctest/cctest.h"
#include "src/compiler.h"
#include "src/compiler/pipeline.h"
#include "src/execution.h"
#include "src/full-codegen.h"
#include "src/handles.h"
#include "src/objects-inl.h"
#include "src/parser.h"
#include "src/rewriter.h"
#include "src/scopes.h"
#define USE_CRANKSHAFT 0
namespace v8 {
namespace internal {
namespace compiler {
class FunctionTester : public InitializedHandleScope {
public:
explicit FunctionTester(const char* source, uint32_t flags = 0)
: isolate(main_isolate()),
function((FLAG_allow_natives_syntax = true, NewFunction(source))),
flags_(flags) {
Compile(function);
const uint32_t supported_flags = CompilationInfo::kContextSpecializing |
CompilationInfo::kInliningEnabled |
CompilationInfo::kTypingEnabled;
CHECK_EQ(0, flags_ & ~supported_flags);
}
Isolate* isolate;
Handle<JSFunction> function;
Handle<JSFunction> Compile(Handle<JSFunction> function) {
#if V8_TURBOFAN_TARGET
CompilationInfoWithZone info(function);
CHECK(Parser::Parse(&info));
StrictMode strict_mode = info.function()->strict_mode();
info.SetStrictMode(strict_mode);
info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
if (flags_ & CompilationInfo::kContextSpecializing) {
info.MarkAsContextSpecializing();
}
if (flags_ & CompilationInfo::kInliningEnabled) {
info.MarkAsInliningEnabled();
}
if (flags_ & CompilationInfo::kTypingEnabled) {
info.MarkAsTypingEnabled();
}
CHECK(Rewriter::Rewrite(&info));
CHECK(Scope::Analyze(&info));
CHECK_NE(NULL, info.scope());
Handle<ScopeInfo> scope_info = ScopeInfo::Create(info.scope(), info.zone());
info.shared_info()->set_scope_info(*scope_info);
EnsureDeoptimizationSupport(&info);
Pipeline pipeline(&info);
Handle<Code> code = pipeline.GenerateCode();
CHECK(!code.is_null());
function->ReplaceCode(*code);
#elif USE_CRANKSHAFT
Handle<Code> unoptimized = Handle<Code>(function->code());
Handle<Code> code = Compiler::GetOptimizedCode(function, unoptimized,
Compiler::NOT_CONCURRENT);
CHECK(!code.is_null());
#if ENABLE_DISASSEMBLER
if (FLAG_print_opt_code) {
CodeTracer::Scope tracing_scope(isolate->GetCodeTracer());
code->Disassemble("test code", tracing_scope.file());
}
#endif
function->ReplaceCode(*code);
#endif
return function;
}
static void EnsureDeoptimizationSupport(CompilationInfo* info) {
bool should_recompile = !info->shared_info()->has_deoptimization_support();
if (should_recompile) {
CompilationInfoWithZone unoptimized(info->shared_info());
// Note that we use the same AST that we will use for generating the
// optimized code.
unoptimized.SetFunction(info->function());
unoptimized.PrepareForCompilation(info->scope());
unoptimized.SetContext(info->context());
if (should_recompile) unoptimized.EnableDeoptimizationSupport();
bool succeeded = FullCodeGenerator::MakeCode(&unoptimized);
CHECK(succeeded);
Handle<SharedFunctionInfo> shared = info->shared_info();
shared->EnableDeoptimizationSupport(*unoptimized.code());
}
}
MaybeHandle<Object> Call(Handle<Object> a, Handle<Object> b) {
Handle<Object> args[] = {a, b};
return Execution::Call(isolate, function, undefined(), 2, args, false);
}
void CheckThrows(Handle<Object> a, Handle<Object> b) {
TryCatch try_catch;
MaybeHandle<Object> no_result = Call(a, b);
CHECK(isolate->has_pending_exception());
CHECK(try_catch.HasCaught());
CHECK(no_result.is_null());
// TODO(mstarzinger): Temporary workaround for issue chromium:362388.
isolate->OptionalRescheduleException(true);
}
v8::Handle<v8::Message> CheckThrowsReturnMessage(Handle<Object> a,
Handle<Object> b) {
TryCatch try_catch;
MaybeHandle<Object> no_result = Call(a, b);
CHECK(isolate->has_pending_exception());
CHECK(try_catch.HasCaught());
CHECK(no_result.is_null());
// TODO(mstarzinger): Calling OptionalRescheduleException is a dirty hack,
// it's the only way to make Message() not to assert because an external
// exception has been caught by the try_catch.
isolate->OptionalRescheduleException(true);
return try_catch.Message();
}
void CheckCall(Handle<Object> expected, Handle<Object> a, Handle<Object> b) {
Handle<Object> result = Call(a, b).ToHandleChecked();
CHECK(expected->SameValue(*result));
}
void CheckCall(Handle<Object> expected, Handle<Object> a) {
CheckCall(expected, a, undefined());
}
void CheckCall(Handle<Object> expected) {
CheckCall(expected, undefined(), undefined());
}
void CheckCall(double expected, double a, double b) {
CheckCall(Val(expected), Val(a), Val(b));
}
void CheckTrue(Handle<Object> a, Handle<Object> b) {
CheckCall(true_value(), a, b);
}
void CheckTrue(Handle<Object> a) { CheckCall(true_value(), a, undefined()); }
void CheckTrue(double a, double b) {
CheckCall(true_value(), Val(a), Val(b));
}
void CheckFalse(Handle<Object> a, Handle<Object> b) {
CheckCall(false_value(), a, b);
}
void CheckFalse(Handle<Object> a) {
CheckCall(false_value(), a, undefined());
}
void CheckFalse(double a, double b) {
CheckCall(false_value(), Val(a), Val(b));
}
Handle<JSFunction> NewFunction(const char* source) {
return v8::Utils::OpenHandle(
*v8::Handle<v8::Function>::Cast(CompileRun(source)));
}
Handle<JSObject> NewObject(const char* source) {
return v8::Utils::OpenHandle(
*v8::Handle<v8::Object>::Cast(CompileRun(source)));
}
Handle<String> Val(const char* string) {
return isolate->factory()->InternalizeUtf8String(string);
}
Handle<Object> Val(double value) {
return isolate->factory()->NewNumber(value);
}
Handle<Object> infinity() { return isolate->factory()->infinity_value(); }
Handle<Object> minus_infinity() { return Val(-V8_INFINITY); }
Handle<Object> nan() { return isolate->factory()->nan_value(); }
Handle<Object> undefined() { return isolate->factory()->undefined_value(); }
Handle<Object> null() { return isolate->factory()->null_value(); }
Handle<Object> true_value() { return isolate->factory()->true_value(); }
Handle<Object> false_value() { return isolate->factory()->false_value(); }
private:
uint32_t flags_;
};
}
}
} // namespace v8::internal::compiler
#endif // V8_CCTEST_COMPILER_FUNCTION_TESTER_H_