v8/test/cctest/interpreter/bytecode-expectations-printer.h
ssanfilippo 6ae030590d [Interpreter] Refactor bytecode generator test suite.
Bytecode expectations have been moved to external (.golden) files,
one per test. Each test in the suite builds a representation of the
the compiled bytecode using BytecodeExpectationsPrinter. The output is
then compared to the golden file. If the comparision fails, a textual
diff can be used to identify the discrepancies.

Only the test snippets are left in the cc file, which also allows to
make it more compact and meaningful. Leaving the snippets in the cc
file was a deliberate choice to allow keeping the "truth" about the
tests in the cc file, which will rarely change, as opposed to golden
files.

Golden files can be generated and kept up to date using
generate-bytecode-expectations, which also means that the test suite
can be batch updated whenever the bytecode or golden format changes.

The golden format has been slightly amended (no more comments about
`void*`, add size of the bytecode array) following the consideration
made while converting the tests.

There is also a fix: BytecodeExpectationsPrinter::top_level_ was left
uninitialized, leading to undefined behaviour.

BUG=v8:4280
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#34285}
2016-02-25 12:07:19 +00:00

121 lines
4.2 KiB
C++

// Copyright 2016 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 TEST_CCTEST_INTERPRETER_BYTECODE_EXPECTATIONS_PRINTER_H_
#define TEST_CCTEST_INTERPRETER_BYTECODE_EXPECTATIONS_PRINTER_H_
#include <iostream>
#include <string>
#include <vector>
#include "src/interpreter/bytecodes.h"
#include "src/objects.h"
namespace v8 {
class Isolate;
namespace internal {
namespace interpreter {
class BytecodeArrayIterator;
class BytecodeExpectationsPrinter final {
public:
enum class ConstantPoolType {
kUnknown,
kString,
kNumber,
kMixed,
};
BytecodeExpectationsPrinter(v8::Isolate* i,
ConstantPoolType t = ConstantPoolType::kMixed)
: isolate_(i),
const_pool_type_(t),
execute_(true),
wrap_(true),
top_level_(false),
test_function_name_(kDefaultTopFunctionName) {}
void PrintExpectation(std::ostream& stream, // NOLINT
const std::string& snippet) const;
void set_constant_pool_type(ConstantPoolType const_pool_type) {
const_pool_type_ = const_pool_type;
}
ConstantPoolType const_pool_type() const { return const_pool_type_; }
void set_execute(bool execute) { execute_ = execute; }
bool execute() const { return execute_; }
void set_wrap(bool wrap) { wrap_ = wrap; }
bool wrap() const { return wrap_; }
void set_top_level(bool top_level) { top_level_ = top_level; }
bool top_level() const { return top_level_; }
void set_test_function_name(const std::string& test_function_name) {
test_function_name_ = test_function_name;
}
std::string test_function_name() const { return test_function_name_; }
private:
void PrintEscapedString(std::ostream& stream, // NOLINT
const std::string& string) const;
void PrintBytecodeOperand(std::ostream& stream, // NOLINT
const BytecodeArrayIterator& bytecode_iter,
const Bytecode& bytecode, int op_index,
int parameter_count) const;
void PrintBytecode(std::ostream& stream, // NOLINT
const BytecodeArrayIterator& bytecode_iter,
int parameter_count) const;
void PrintV8String(std::ostream& stream, // NOLINT
i::String* string) const;
void PrintConstant(std::ostream& stream, // NOLINT
i::Handle<i::Object> constant) const;
void PrintFrameSize(std::ostream& stream, // NOLINT
i::Handle<i::BytecodeArray> bytecode_array) const;
void PrintBytecodeSequence(std::ostream& stream, // NOLINT
i::Handle<i::BytecodeArray> bytecode_array) const;
void PrintConstantPool(std::ostream& stream, // NOLINT
i::FixedArray* constant_pool) const;
void PrintCodeSnippet(std::ostream& stream, // NOLINT
const std::string& body) const;
void PrintBytecodeArray(std::ostream& stream, // NOLINT
i::Handle<i::BytecodeArray> bytecode_array) const;
void PrintHandlers(std::ostream& stream, // NOLINT
i::Handle<i::BytecodeArray> bytecode_array) const;
v8::Local<v8::String> V8StringFromUTF8(const char* data) const;
std::string WrapCodeInFunction(const char* function_name,
const std::string& function_body) const;
v8::Local<v8::Script> Compile(const char* program) const;
void Run(v8::Local<v8::Script> script) const;
i::Handle<i::BytecodeArray> GetBytecodeArrayForGlobal(
const char* global_name) const;
i::Handle<v8::internal::BytecodeArray> GetBytecodeArrayForScript(
v8::Local<v8::Script> script) const;
i::Isolate* i_isolate() const {
return reinterpret_cast<i::Isolate*>(isolate_);
}
v8::Isolate* isolate_;
ConstantPoolType const_pool_type_;
bool execute_;
bool wrap_;
bool top_level_;
std::string test_function_name_;
static const char* const kDefaultTopFunctionName;
};
} // namespace interpreter
} // namespace internal
} // namespace v8
#endif // TEST_CCTEST_INTERPRETER_BYTECODE_EXPECTATIONS_PRINTER_H_