Revert "Revert "Upgrade to 5.0.71.48"" DO NOT MERGE
This reverts commit f2e3994fa5148cc3d9946666f0b0596290192b0e,
and updates the x64 makefile properly so it doesn't break that
build.
FPIIM-449
Change-Id: Ib83e35bfbae6af627451c926a9650ec57c045605
(cherry picked from commit 109988c7ccb6f3fd1a58574fa3dfb88beaef6632)
diff --git a/test/cctest/compiler/c-signature.h b/test/cctest/compiler/c-signature.h
index 13ef38a..1c2f963 100644
--- a/test/cctest/compiler/c-signature.h
+++ b/test/cctest/compiler/c-signature.h
@@ -53,16 +53,16 @@
public:
template <typename P1 = void, typename P2 = void, typename P3 = void,
typename P4 = void, typename P5 = void>
- void VerifyParams() {
+ static void VerifyParams(MachineSignature* sig) {
// Verifies the C signature against the machine types. Maximum {5} params.
- CHECK_LT(parameter_count(), 6u);
+ CHECK_LT(sig->parameter_count(), 6u);
const int kMax = 5;
MachineType params[] = {MachineTypeForC<P1>(), MachineTypeForC<P2>(),
MachineTypeForC<P3>(), MachineTypeForC<P4>(),
MachineTypeForC<P5>()};
for (int p = kMax - 1; p >= 0; p--) {
- if (p < static_cast<int>(parameter_count())) {
- CHECK_EQ(GetParam(p), params[p]);
+ if (p < static_cast<int>(sig->parameter_count())) {
+ CHECK_EQ(sig->GetParam(p), params[p]);
} else {
CHECK_EQ(MachineType::None(), params[p]);
}
diff --git a/test/cctest/compiler/call-tester.h b/test/cctest/compiler/call-tester.h
index e60f717..8ee6b99 100644
--- a/test/cctest/compiler/call-tester.h
+++ b/test/cctest/compiler/call-tester.h
@@ -119,7 +119,7 @@
template <typename R>
class CallHelper {
public:
- explicit CallHelper(Isolate* isolate, CSignature* csig)
+ explicit CallHelper(Isolate* isolate, MachineSignature* csig)
: csig_(csig), isolate_(isolate) {
USE(isolate_);
}
@@ -127,47 +127,47 @@
R Call() {
typedef R V8_CDECL FType();
- csig_->VerifyParams();
+ CSignature::VerifyParams(csig_);
return DoCall(FUNCTION_CAST<FType*>(Generate()));
}
template <typename P1>
R Call(P1 p1) {
typedef R V8_CDECL FType(P1);
- csig_->VerifyParams<P1>();
+ CSignature::VerifyParams<P1>(csig_);
return DoCall(FUNCTION_CAST<FType*>(Generate()), p1);
}
template <typename P1, typename P2>
R Call(P1 p1, P2 p2) {
typedef R V8_CDECL FType(P1, P2);
- csig_->VerifyParams<P1, P2>();
+ CSignature::VerifyParams<P1, P2>(csig_);
return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2);
}
template <typename P1, typename P2, typename P3>
R Call(P1 p1, P2 p2, P3 p3) {
typedef R V8_CDECL FType(P1, P2, P3);
- csig_->VerifyParams<P1, P2, P3>();
+ CSignature::VerifyParams<P1, P2, P3>(csig_);
return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3);
}
template <typename P1, typename P2, typename P3, typename P4>
R Call(P1 p1, P2 p2, P3 p3, P4 p4) {
typedef R V8_CDECL FType(P1, P2, P3, P4);
- csig_->VerifyParams<P1, P2, P3, P4>();
+ CSignature::VerifyParams<P1, P2, P3, P4>(csig_);
return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3, p4);
}
template <typename P1, typename P2, typename P3, typename P4, typename P5>
R Call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
typedef R V8_CDECL FType(P1, P2, P3, P4, P5);
- csig_->VerifyParams<P1, P2, P3, P4, P5>();
+ CSignature::VerifyParams<P1, P2, P3, P4, P5>(csig_);
return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3, p4, p5);
}
protected:
- CSignature* csig_;
+ MachineSignature* csig_;
virtual byte* Generate() = 0;
@@ -342,7 +342,7 @@
template <typename T>
class CodeRunner : public CallHelper<T> {
public:
- CodeRunner(Isolate* isolate, Handle<Code> code, CSignature* csig)
+ CodeRunner(Isolate* isolate, Handle<Code> code, MachineSignature* csig)
: CallHelper<T>(isolate, csig), code_(code) {}
virtual ~CodeRunner() {}
diff --git a/test/cctest/compiler/codegen-tester.h b/test/cctest/compiler/codegen-tester.h
index 56e90c6..5d670bf 100644
--- a/test/cctest/compiler/codegen-tester.h
+++ b/test/cctest/compiler/codegen-tester.h
@@ -35,10 +35,13 @@
Linkage::GetSimplifiedCDescriptor(
main_zone(),
CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0,
- p1, p2, p3, p4)),
+ p1, p2, p3, p4),
+ true),
MachineType::PointerRepresentation(),
InstructionSelector::SupportedMachineOperatorFlags()) {}
+ virtual ~RawMachineAssemblerTester() {}
+
void CheckNumber(double expected, Object* number) {
CHECK(this->isolate()->factory()->NewNumber(expected)->SameValue(number));
}
@@ -85,6 +88,7 @@
: BufferedRawMachineAssemblerTester(ComputeParameterCount(p0, p1, p2, p3),
p0, p1, p2, p3) {}
+ virtual byte* Generate() { return RawMachineAssemblerTester::Generate(); }
// The BufferedRawMachineAssemblerTester does not pass parameters directly
// to the constructed IR graph. Instead it passes a pointer to the parameter
@@ -92,11 +96,10 @@
// parameters from memory. Thereby it is possible to pass 64 bit parameters
// to the IR graph.
Node* Parameter(size_t index) {
- CHECK(index >= 0 && index < 4);
+ CHECK(index < 4);
return parameter_nodes_[index];
}
-
// The BufferedRawMachineAssemblerTester adds a Store node to the IR graph
// to store the graph's return value in memory. The memory address for the
// Store node is provided as a parameter. By storing the return value in
@@ -110,7 +113,7 @@
ReturnType Call() {
ReturnType return_value;
- test_graph_signature_->VerifyParams();
+ CSignature::VerifyParams(test_graph_signature_);
CallHelper<int32_t>::Call(reinterpret_cast<void*>(&return_value));
return return_value;
}
@@ -118,7 +121,7 @@
template <typename P0>
ReturnType Call(P0 p0) {
ReturnType return_value;
- test_graph_signature_->VerifyParams<P0>();
+ CSignature::VerifyParams<P0>(test_graph_signature_);
CallHelper<int32_t>::Call(reinterpret_cast<void*>(&p0),
reinterpret_cast<void*>(&return_value));
return return_value;
@@ -127,7 +130,7 @@
template <typename P0, typename P1>
ReturnType Call(P0 p0, P1 p1) {
ReturnType return_value;
- test_graph_signature_->VerifyParams<P0, P1>();
+ CSignature::VerifyParams<P0, P1>(test_graph_signature_);
CallHelper<int32_t>::Call(reinterpret_cast<void*>(&p0),
reinterpret_cast<void*>(&p1),
reinterpret_cast<void*>(&return_value));
@@ -137,7 +140,7 @@
template <typename P0, typename P1, typename P2>
ReturnType Call(P0 p0, P1 p1, P2 p2) {
ReturnType return_value;
- test_graph_signature_->VerifyParams<P0, P1, P2>();
+ CSignature::VerifyParams<P0, P1, P2>(test_graph_signature_);
CallHelper<int32_t>::Call(
reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&return_value));
@@ -147,7 +150,7 @@
template <typename P0, typename P1, typename P2, typename P3>
ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) {
ReturnType return_value;
- test_graph_signature_->VerifyParams<P0, P1, P2, P3>();
+ CSignature::VerifyParams<P0, P1, P2, P3>(test_graph_signature_);
CallHelper<int32_t>::Call(
reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&p3),
@@ -245,6 +248,7 @@
: Load(p3, RawMachineAssembler::Parameter(3));
}
+ virtual byte* Generate() { return RawMachineAssemblerTester::Generate(); }
// The BufferedRawMachineAssemblerTester does not pass parameters directly
// to the constructed IR graph. Instead it passes a pointer to the parameter
@@ -258,26 +262,26 @@
void Call() {
- test_graph_signature_->VerifyParams();
+ CSignature::VerifyParams(test_graph_signature_);
CallHelper<void>::Call();
}
template <typename P0>
void Call(P0 p0) {
- test_graph_signature_->VerifyParams<P0>();
+ CSignature::VerifyParams<P0>(test_graph_signature_);
CallHelper<void>::Call(reinterpret_cast<void*>(&p0));
}
template <typename P0, typename P1>
void Call(P0 p0, P1 p1) {
- test_graph_signature_->VerifyParams<P0, P1>();
+ CSignature::VerifyParams<P0, P1>(test_graph_signature_);
CallHelper<void>::Call(reinterpret_cast<void*>(&p0),
reinterpret_cast<void*>(&p1));
}
template <typename P0, typename P1, typename P2>
void Call(P0 p0, P1 p1, P2 p2) {
- test_graph_signature_->VerifyParams<P0, P1, P2>();
+ CSignature::VerifyParams<P0, P1, P2>(test_graph_signature_);
CallHelper<void>::Call(reinterpret_cast<void*>(&p0),
reinterpret_cast<void*>(&p1),
reinterpret_cast<void*>(&p2));
@@ -285,7 +289,7 @@
template <typename P0, typename P1, typename P2, typename P3>
void Call(P0 p0, P1 p1, P2 p2, P3 p3) {
- test_graph_signature_->VerifyParams<P0, P1, P2, P3>();
+ CSignature::VerifyParams<P0, P1, P2, P3>(test_graph_signature_);
CallHelper<void>::Call(
reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&p3));
@@ -397,7 +401,6 @@
// A helper class for testing code sequences that take two float parameters and
// return a float value.
-// TODO(titzer): figure out how to return floats correctly on ia32.
class Float32BinopTester : public BinopTester<float, USE_RESULT_BUFFER> {
public:
explicit Float32BinopTester(RawMachineAssemblerTester<int32_t>* tester)
@@ -407,7 +410,6 @@
// A helper class for testing code sequences that take two double parameters and
// return a double value.
-// TODO(titzer): figure out how to return doubles correctly on ia32.
class Float64BinopTester : public BinopTester<double, USE_RESULT_BUFFER> {
public:
explicit Float64BinopTester(RawMachineAssemblerTester<int32_t>* tester)
@@ -524,7 +526,8 @@
// and run the generated code to ensure it produces the correct results.
class Int32BinopInputShapeTester {
public:
- explicit Int32BinopInputShapeTester(BinopGen<int32_t>* g) : gen(g) {}
+ explicit Int32BinopInputShapeTester(BinopGen<int32_t>* g)
+ : gen(g), input_a(0), input_b(0) {}
void TestAllInputShapes();
@@ -537,24 +540,6 @@
void RunLeft(RawMachineAssemblerTester<int32_t>* m);
void RunRight(RawMachineAssemblerTester<int32_t>* m);
};
-
-// TODO(bmeurer): Drop this crap once we switch to GTest/Gmock.
-static inline void CheckFloatEq(volatile float x, volatile float y) {
- if (std::isnan(x)) {
- CHECK(std::isnan(y));
- } else {
- CHECK_EQ(x, y);
- }
-}
-
-static inline void CheckDoubleEq(volatile double x, volatile double y) {
- if (std::isnan(x)) {
- CHECK(std::isnan(y));
- } else {
- CHECK_EQ(x, y);
- }
-}
-
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/test/cctest/compiler/function-tester.h b/test/cctest/compiler/function-tester.h
index 2fcd353..c6093ce 100644
--- a/test/cctest/compiler/function-tester.h
+++ b/test/cctest/compiler/function-tester.h
@@ -162,15 +162,26 @@
Handle<Object> false_value() { return isolate->factory()->false_value(); }
+ static Handle<JSFunction> ForMachineGraph(Graph* graph, int param_count) {
+ JSFunction* p = NULL;
+ { // because of the implicit handle scope of FunctionTester.
+ FunctionTester f(graph, param_count);
+ p = *f.function;
+ }
+ return Handle<JSFunction>(p); // allocated in outer handle scope.
+ }
+
+ private:
+ uint32_t flags_;
+
Handle<JSFunction> Compile(Handle<JSFunction> function) {
-// TODO(titzer): make this method private.
Zone zone;
ParseInfo parse_info(&zone, function);
CompilationInfo info(&parse_info);
info.MarkAsDeoptimizationEnabled();
CHECK(Parser::ParseStatic(info.parse_info()));
- info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
+ info.SetOptimizing();
if (flags_ & CompilationInfo::kFunctionContextSpecializing) {
info.MarkAsFunctionContextSpecializing();
}
@@ -192,26 +203,13 @@
return function;
}
- static Handle<JSFunction> ForMachineGraph(Graph* graph, int param_count) {
- JSFunction* p = NULL;
- { // because of the implicit handle scope of FunctionTester.
- FunctionTester f(graph, param_count);
- p = *f.function;
- }
- return Handle<JSFunction>(p); // allocated in outer handle scope.
- }
-
- private:
- uint32_t flags_;
-
std::string BuildFunction(int param_count) {
std::string function_string = "(function(";
if (param_count > 0) {
- char next = 'a';
- function_string += next;
- while (param_count-- > 0) {
+ function_string += 'a';
+ for (int i = 1; i < param_count; i++) {
function_string += ',';
- function_string += ++next;
+ function_string += static_cast<char>('a' + i);
}
}
function_string += "){})";
@@ -231,8 +229,7 @@
CompilationInfo info(&parse_info);
CHECK(Parser::ParseStatic(info.parse_info()));
- info.SetOptimizing(BailoutId::None(),
- Handle<Code>(function->shared()->code()));
+ info.SetOptimizing();
CHECK(Compiler::Analyze(info.parse_info()));
CHECK(Compiler::EnsureDeoptimizationSupport(&info));
diff --git a/test/cctest/compiler/test-code-stub-assembler.cc b/test/cctest/compiler/test-code-stub-assembler.cc
index d7a7a81..0306561 100644
--- a/test/cctest/compiler/test-code-stub-assembler.cc
+++ b/test/cctest/compiler/test-code-stub-assembler.cc
@@ -16,7 +16,7 @@
CodeStubAssemblerTester(Isolate* isolate,
const CallInterfaceDescriptor& descriptor)
: CodeStubAssembler(isolate, isolate->runtime_zone(), descriptor,
- Code::STUB, "test"),
+ Code::ComputeFlags(Code::STUB), "test"),
scope_(isolate) {}
private:
@@ -120,6 +120,133 @@
CHECK_EQ(16, Handle<Smi>::cast(result.ToHandleChecked())->value());
}
+TEST(VariableMerge1) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ VoidDescriptor descriptor(isolate);
+ CodeStubAssemblerTester m(isolate, descriptor);
+ CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged);
+ CodeStubAssembler::Label l1(&m), l2(&m), merge(&m);
+ Node* temp = m.Int32Constant(0);
+ var1.Bind(temp);
+ m.Branch(m.Int32Constant(1), &l1, &l2);
+ m.Bind(&l1);
+ CHECK_EQ(var1.value(), temp);
+ m.Goto(&merge);
+ m.Bind(&l2);
+ CHECK_EQ(var1.value(), temp);
+ m.Goto(&merge);
+ m.Bind(&merge);
+ CHECK_EQ(var1.value(), temp);
+}
+
+TEST(VariableMerge2) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ VoidDescriptor descriptor(isolate);
+ CodeStubAssemblerTester m(isolate, descriptor);
+ CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged);
+ CodeStubAssembler::Label l1(&m), l2(&m), merge(&m);
+ Node* temp = m.Int32Constant(0);
+ var1.Bind(temp);
+ m.Branch(m.Int32Constant(1), &l1, &l2);
+ m.Bind(&l1);
+ CHECK_EQ(var1.value(), temp);
+ m.Goto(&merge);
+ m.Bind(&l2);
+ Node* temp2 = m.Int32Constant(2);
+ var1.Bind(temp2);
+ CHECK_EQ(var1.value(), temp2);
+ m.Goto(&merge);
+ m.Bind(&merge);
+ CHECK_NE(var1.value(), temp);
+}
+
+TEST(VariableMerge3) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ VoidDescriptor descriptor(isolate);
+ CodeStubAssemblerTester m(isolate, descriptor);
+ CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged);
+ CodeStubAssembler::Variable var2(&m, MachineRepresentation::kTagged);
+ CodeStubAssembler::Label l1(&m), l2(&m), merge(&m);
+ Node* temp = m.Int32Constant(0);
+ var1.Bind(temp);
+ var2.Bind(temp);
+ m.Branch(m.Int32Constant(1), &l1, &l2);
+ m.Bind(&l1);
+ CHECK_EQ(var1.value(), temp);
+ m.Goto(&merge);
+ m.Bind(&l2);
+ Node* temp2 = m.Int32Constant(2);
+ var1.Bind(temp2);
+ CHECK_EQ(var1.value(), temp2);
+ m.Goto(&merge);
+ m.Bind(&merge);
+ CHECK_NE(var1.value(), temp);
+ CHECK_NE(var1.value(), temp2);
+ CHECK_EQ(var2.value(), temp);
+}
+
+TEST(VariableMergeBindFirst) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ VoidDescriptor descriptor(isolate);
+ CodeStubAssemblerTester m(isolate, descriptor);
+ CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged);
+ CodeStubAssembler::Label l1(&m), l2(&m), merge(&m, &var1), end(&m);
+ Node* temp = m.Int32Constant(0);
+ var1.Bind(temp);
+ m.Branch(m.Int32Constant(1), &l1, &l2);
+ m.Bind(&l1);
+ CHECK_EQ(var1.value(), temp);
+ m.Goto(&merge);
+ m.Bind(&merge);
+ CHECK(var1.value() != temp);
+ CHECK(var1.value() != nullptr);
+ m.Goto(&end);
+ m.Bind(&l2);
+ Node* temp2 = m.Int32Constant(2);
+ var1.Bind(temp2);
+ CHECK_EQ(var1.value(), temp2);
+ m.Goto(&merge);
+ m.Bind(&end);
+ CHECK(var1.value() != temp);
+ CHECK(var1.value() != nullptr);
+}
+
+TEST(VariableMergeSwitch) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ VoidDescriptor descriptor(isolate);
+ CodeStubAssemblerTester m(isolate, descriptor);
+ CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged);
+ CodeStubAssembler::Label l1(&m), l2(&m), default_label(&m);
+ CodeStubAssembler::Label* labels[] = {&l1, &l2};
+ int32_t values[] = {1, 2};
+ Node* temp = m.Int32Constant(0);
+ var1.Bind(temp);
+ m.Switch(m.Int32Constant(2), &default_label, values, labels, 2);
+ m.Bind(&l1);
+ DCHECK_EQ(temp, var1.value());
+ m.Return(temp);
+ m.Bind(&l2);
+ DCHECK_EQ(temp, var1.value());
+ m.Return(temp);
+ m.Bind(&default_label);
+ DCHECK_EQ(temp, var1.value());
+ m.Return(temp);
+}
+
+TEST(FixedArrayAccessSmiIndex) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ VoidDescriptor descriptor(isolate);
+ CodeStubAssemblerTester m(isolate, descriptor);
+ Handle<FixedArray> array = isolate->factory()->NewFixedArray(5);
+ array->set(4, Smi::FromInt(733));
+ m.Return(m.LoadFixedArrayElementSmiIndex(m.HeapConstant(array),
+ m.SmiTag(m.Int32Constant(4))));
+ Handle<Code> code = m.GenerateCode();
+ FunctionTester ft(descriptor, code);
+ MaybeHandle<Object> result = ft.Call();
+ CHECK_EQ(733, Handle<Smi>::cast(result.ToHandleChecked())->value());
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/test/cctest/compiler/test-js-context-specialization.cc b/test/cctest/compiler/test-js-context-specialization.cc
index 43b7665..c7cd47a 100644
--- a/test/cctest/compiler/test-js-context-specialization.cc
+++ b/test/cctest/compiler/test-js-context-specialization.cc
@@ -225,8 +225,8 @@
t.graph()->NewNode(t.simplified()->ChangeTaggedToInt32(), other_load);
Node* add = t.graph()->NewNode(
- t.javascript()->Add(LanguageMode::SLOPPY, BinaryOperationHints::Any()),
- value_use, other_use, param_context, t.jsgraph()->EmptyFrameState(),
+ t.javascript()->Add(BinaryOperationHints::Any()), value_use, other_use,
+ param_context, t.jsgraph()->EmptyFrameState(),
t.jsgraph()->EmptyFrameState(), other_load, start);
Node* ret =
diff --git a/test/cctest/compiler/test-js-typed-lowering.cc b/test/cctest/compiler/test-js-typed-lowering.cc
index c8b7734..24db6a5 100644
--- a/test/cctest/compiler/test-js-typed-lowering.cc
+++ b/test/cctest/compiler/test-js-typed-lowering.cc
@@ -17,19 +17,6 @@
namespace internal {
namespace compiler {
-#ifndef TEST_WITH_STRONG
-#define TEST_WITH_STRONG(Name) \
- static void Test##Name(); \
- static void TestWithStrong##Name(LanguageMode language_mode); \
- CcTest register_test_##Name(Test##Name, __FILE__, #Name, NULL, true, true); \
- static void Test##Name() { \
- TestWithStrong##Name(LanguageMode::SLOPPY); \
- TestWithStrong##Name(LanguageMode::STRONG); \
- } \
- static void TestWithStrong##Name(LanguageMode language_mode)
-#endif
-
-
class JSTypedLoweringTester : public HandleAndZoneScope {
public:
explicit JSTypedLoweringTester(int num_parameters = 0)
@@ -163,17 +150,8 @@
}
Node* UseForEffect(Node* node) {
- // TODO(titzer): use EffectPhi after fixing EffectCount
- if (OperatorProperties::GetFrameStateInputCount(javascript.ToNumber()) >
- 0) {
- CHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(
- javascript.ToNumber()));
- return graph.NewNode(javascript.ToNumber(), node, context(),
- EmptyFrameState(context()), node, control());
- } else {
- return graph.NewNode(javascript.ToNumber(), node, context(), node,
- control());
- }
+ Node* merge = graph.NewNode(common.Merge(1), start());
+ return graph.NewNode(common.EffectPhi(1), node, merge);
}
void CheckEffectInput(Node* effect, Node* use) {
@@ -240,7 +218,7 @@
// TODO(turbofan): Lowering of StringAdd is disabled for now.
#if 0
-TEST_WITH_STRONG(StringBinops) {
+TEST(StringBinops) {
JSTypedLoweringTester R;
for (size_t i = 0; i < arraysize(kStringTypes); ++i) {
@@ -249,7 +227,7 @@
for (size_t j = 0; j < arraysize(kStringTypes); ++j) {
Node* p1 = R.Parameter(kStringTypes[j], 1);
- Node* add = R.Binop(R.javascript.Add(language_mode), p0, p1);
+ Node* add = R.Binop(R.javascript.Add(), p0, p1);
Node* r = R.reduce(add);
R.CheckBinop(IrOpcode::kStringAdd, r);
@@ -260,14 +238,12 @@
}
#endif
-
-TEST_WITH_STRONG(AddNumber1) {
+TEST(AddNumber1) {
JSTypedLoweringTester R;
for (size_t i = 0; i < arraysize(kNumberTypes); ++i) {
Node* p0 = R.Parameter(kNumberTypes[i], 0);
Node* p1 = R.Parameter(kNumberTypes[i], 1);
- Node* add = R.Binop(
- R.javascript.Add(language_mode, BinaryOperationHints::Any()), p0, p1);
+ Node* add = R.Binop(R.javascript.Add(BinaryOperationHints::Any()), p0, p1);
Node* r = R.reduce(add);
R.CheckBinop(IrOpcode::kNumberAdd, r);
@@ -276,20 +252,14 @@
}
}
-
-TEST_WITH_STRONG(NumberBinops) {
+TEST(NumberBinops) {
JSTypedLoweringTester R;
const Operator* ops[] = {
- R.javascript.Add(language_mode, R.hints),
- R.simplified.NumberAdd(),
- R.javascript.Subtract(language_mode, R.hints),
- R.simplified.NumberSubtract(),
- R.javascript.Multiply(language_mode, R.hints),
- R.simplified.NumberMultiply(),
- R.javascript.Divide(language_mode, R.hints),
- R.simplified.NumberDivide(),
- R.javascript.Modulus(language_mode, R.hints),
- R.simplified.NumberModulus(),
+ R.javascript.Add(R.hints), R.simplified.NumberAdd(),
+ R.javascript.Subtract(R.hints), R.simplified.NumberSubtract(),
+ R.javascript.Multiply(R.hints), R.simplified.NumberMultiply(),
+ R.javascript.Divide(R.hints), R.simplified.NumberDivide(),
+ R.javascript.Modulus(R.hints), R.simplified.NumberModulus(),
};
for (size_t i = 0; i < arraysize(kNumberTypes); ++i) {
@@ -329,14 +299,13 @@
// A helper class for testing lowering of bitwise shift operators.
class JSBitwiseShiftTypedLoweringTester : public JSTypedLoweringTester {
public:
- explicit JSBitwiseShiftTypedLoweringTester(LanguageMode language_mode)
- : JSTypedLoweringTester(), language_mode_(language_mode) {
+ JSBitwiseShiftTypedLoweringTester() : JSTypedLoweringTester() {
int i = 0;
- set(i++, javascript.ShiftLeft(language_mode_, hints), true);
+ set(i++, javascript.ShiftLeft(hints), true);
set(i++, simplified.NumberShiftLeft(), false);
- set(i++, javascript.ShiftRight(language_mode_, hints), true);
+ set(i++, javascript.ShiftRight(hints), true);
set(i++, simplified.NumberShiftRight(), false);
- set(i++, javascript.ShiftRightLogical(language_mode_, hints), false);
+ set(i++, javascript.ShiftRightLogical(hints), false);
set(i++, simplified.NumberShiftRightLogical(), false);
}
static const int kNumberOps = 6;
@@ -344,7 +313,6 @@
bool signedness[kNumberOps];
private:
- LanguageMode language_mode_;
void set(int idx, const Operator* op, bool s) {
ops[idx] = op;
signedness[idx] = s;
@@ -353,7 +321,7 @@
TEST(Int32BitwiseShifts) {
- JSBitwiseShiftTypedLoweringTester R(LanguageMode::SLOPPY);
+ JSBitwiseShiftTypedLoweringTester R;
Type* types[] = {
Type::SignedSmall(), Type::UnsignedSmall(), Type::Negative32(),
@@ -387,14 +355,13 @@
// A helper class for testing lowering of bitwise operators.
class JSBitwiseTypedLoweringTester : public JSTypedLoweringTester {
public:
- explicit JSBitwiseTypedLoweringTester(LanguageMode language_mode)
- : JSTypedLoweringTester(), language_mode_(language_mode) {
+ JSBitwiseTypedLoweringTester() : JSTypedLoweringTester() {
int i = 0;
- set(i++, javascript.BitwiseOr(language_mode_, hints), true);
+ set(i++, javascript.BitwiseOr(hints), true);
set(i++, simplified.NumberBitwiseOr(), true);
- set(i++, javascript.BitwiseXor(language_mode_, hints), true);
+ set(i++, javascript.BitwiseXor(hints), true);
set(i++, simplified.NumberBitwiseXor(), true);
- set(i++, javascript.BitwiseAnd(language_mode_, hints), true);
+ set(i++, javascript.BitwiseAnd(hints), true);
set(i++, simplified.NumberBitwiseAnd(), true);
}
static const int kNumberOps = 6;
@@ -402,7 +369,6 @@
bool signedness[kNumberOps];
private:
- LanguageMode language_mode_;
void set(int idx, const Operator* op, bool s) {
ops[idx] = op;
signedness[idx] = s;
@@ -411,7 +377,7 @@
TEST(Int32BitwiseBinops) {
- JSBitwiseTypedLoweringTester R(LanguageMode::SLOPPY);
+ JSBitwiseTypedLoweringTester R;
Type* types[] = {
Type::SignedSmall(), Type::UnsignedSmall(), Type::Unsigned32(),
@@ -558,7 +524,6 @@
{ // ToString(number)
Node* r = R.ReduceUnop(op, Type::Number());
- // TODO(titzer): could remove effects
CHECK_EQ(IrOpcode::kJSToString, r->opcode());
}
@@ -602,17 +567,14 @@
}
}
-
-TEST_WITH_STRONG(StringComparison) {
+TEST(StringComparison) {
JSTypedLoweringTester R;
const Operator* ops[] = {
- R.javascript.LessThan(language_mode), R.simplified.StringLessThan(),
- R.javascript.LessThanOrEqual(language_mode),
- R.simplified.StringLessThanOrEqual(),
- R.javascript.GreaterThan(language_mode), R.simplified.StringLessThan(),
- R.javascript.GreaterThanOrEqual(language_mode),
- R.simplified.StringLessThanOrEqual()};
+ R.javascript.LessThan(), R.simplified.StringLessThan(),
+ R.javascript.LessThanOrEqual(), R.simplified.StringLessThanOrEqual(),
+ R.javascript.GreaterThan(), R.simplified.StringLessThan(),
+ R.javascript.GreaterThanOrEqual(), R.simplified.StringLessThanOrEqual()};
for (size_t i = 0; i < arraysize(kStringTypes); i++) {
Node* p0 = R.Parameter(kStringTypes[i], 0);
@@ -652,17 +614,14 @@
}
}
-
-TEST_WITH_STRONG(NumberComparison) {
+TEST(NumberComparison) {
JSTypedLoweringTester R;
const Operator* ops[] = {
- R.javascript.LessThan(language_mode), R.simplified.NumberLessThan(),
- R.javascript.LessThanOrEqual(language_mode),
- R.simplified.NumberLessThanOrEqual(),
- R.javascript.GreaterThan(language_mode), R.simplified.NumberLessThan(),
- R.javascript.GreaterThanOrEqual(language_mode),
- R.simplified.NumberLessThanOrEqual()};
+ R.javascript.LessThan(), R.simplified.NumberLessThan(),
+ R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
+ R.javascript.GreaterThan(), R.simplified.NumberLessThan(),
+ R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual()};
Node* const p0 = R.Parameter(Type::Number(), 0);
Node* const p1 = R.Parameter(Type::Number(), 1);
@@ -684,8 +643,7 @@
}
}
-
-TEST_WITH_STRONG(MixedComparison1) {
+TEST(MixedComparison1) {
JSTypedLoweringTester R;
Type* types[] = {Type::Number(), Type::String(),
@@ -697,16 +655,15 @@
for (size_t j = 0; j < arraysize(types); j++) {
Node* p1 = R.Parameter(types[j], 1);
{
- const Operator* less_than = R.javascript.LessThan(language_mode);
+ const Operator* less_than = R.javascript.LessThan();
Node* cmp = R.Binop(less_than, p0, p1);
Node* r = R.reduce(cmp);
if (types[i]->Is(Type::String()) && types[j]->Is(Type::String())) {
R.CheckBinop(R.simplified.StringLessThan(), r);
} else if ((types[i]->Is(Type::Number()) &&
types[j]->Is(Type::Number())) ||
- (!is_strong(language_mode) &&
- (!types[i]->Maybe(Type::String()) ||
- !types[j]->Maybe(Type::String())))) {
+ (!types[i]->Maybe(Type::String()) ||
+ !types[j]->Maybe(Type::String()))) {
R.CheckBinop(R.simplified.NumberLessThan(), r);
} else {
// No reduction of mixed types.
@@ -717,8 +674,7 @@
}
}
-
-TEST_WITH_STRONG(RemoveToNumberEffects) {
+TEST(RemoveToNumberEffects) {
JSTypedLoweringTester R;
Node* effect_use = NULL;
@@ -744,14 +700,14 @@
case 2:
effect_use = R.graph.NewNode(R.common.EffectPhi(1), ton, R.start());
case 3:
- effect_use = R.graph.NewNode(R.javascript.Add(language_mode, R.hints),
- ton, ton, R.context(), frame_state,
- frame_state, ton, R.start());
+ effect_use =
+ R.graph.NewNode(R.javascript.Add(R.hints), ton, ton, R.context(),
+ frame_state, frame_state, ton, R.start());
break;
case 4:
- effect_use = R.graph.NewNode(R.javascript.Add(language_mode, R.hints),
- p0, p0, R.context(), frame_state,
- frame_state, ton, R.start());
+ effect_use =
+ R.graph.NewNode(R.javascript.Add(R.hints), p0, p0, R.context(),
+ frame_state, frame_state, ton, R.start());
break;
case 5:
effect_use = R.graph.NewNode(R.common.Return(), p0, ton, R.start());
@@ -896,9 +852,16 @@
Node* p1 = R.Parameter(types[i]);
CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kReferenceEqual);
}
- // TODO(titzer): Equal(RefEqualTypes)
}
+TEST(StrictEqualityForUnique) {
+ JSTypedLoweringTester R;
+
+ Node* p0 = R.Parameter(Type::Unique());
+ Node* p1 = R.Parameter(Type::Unique());
+ CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kReferenceEqual);
+ CheckEqualityReduction(&R, true, p1, p0, IrOpcode::kReferenceEqual);
+}
TEST(StringEquality) {
JSTypedLoweringTester R;
@@ -909,27 +872,18 @@
CheckEqualityReduction(&R, false, p0, p1, IrOpcode::kStringEqual);
}
-
-TEST_WITH_STRONG(RemovePureNumberBinopEffects) {
+TEST(RemovePureNumberBinopEffects) {
JSTypedLoweringTester R;
const Operator* ops[] = {
- R.javascript.Equal(),
- R.simplified.NumberEqual(),
- R.javascript.Add(language_mode, R.hints),
- R.simplified.NumberAdd(),
- R.javascript.Subtract(language_mode, R.hints),
- R.simplified.NumberSubtract(),
- R.javascript.Multiply(language_mode, R.hints),
- R.simplified.NumberMultiply(),
- R.javascript.Divide(language_mode, R.hints),
- R.simplified.NumberDivide(),
- R.javascript.Modulus(language_mode, R.hints),
- R.simplified.NumberModulus(),
- R.javascript.LessThan(language_mode),
- R.simplified.NumberLessThan(),
- R.javascript.LessThanOrEqual(language_mode),
- R.simplified.NumberLessThanOrEqual(),
+ R.javascript.Equal(), R.simplified.NumberEqual(),
+ R.javascript.Add(R.hints), R.simplified.NumberAdd(),
+ R.javascript.Subtract(R.hints), R.simplified.NumberSubtract(),
+ R.javascript.Multiply(R.hints), R.simplified.NumberMultiply(),
+ R.javascript.Divide(R.hints), R.simplified.NumberDivide(),
+ R.javascript.Modulus(R.hints), R.simplified.NumberModulus(),
+ R.javascript.LessThan(), R.simplified.NumberLessThan(),
+ R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
};
for (size_t j = 0; j < arraysize(ops); j += 2) {
@@ -950,12 +904,9 @@
JSTypedLoweringTester R;
const Operator* ops[] = {
- R.javascript.Subtract(LanguageMode::SLOPPY, R.hints),
- R.simplified.NumberSubtract(),
- R.javascript.Multiply(LanguageMode::SLOPPY, R.hints),
- R.simplified.NumberMultiply(),
- R.javascript.Divide(LanguageMode::SLOPPY, R.hints),
- R.simplified.NumberDivide(),
+ R.javascript.Subtract(R.hints), R.simplified.NumberSubtract(),
+ R.javascript.Multiply(R.hints), R.simplified.NumberMultiply(),
+ R.javascript.Divide(R.hints), R.simplified.NumberDivide(),
};
for (size_t j = 0; j < arraysize(ops); j += 2) {
@@ -978,14 +929,10 @@
JSTypedLoweringTester R;
const Operator* ops[] = {
- R.javascript.Add(LanguageMode::SLOPPY, R.hints),
- R.simplified.NumberAdd(),
- R.javascript.Subtract(LanguageMode::SLOPPY, R.hints),
- R.simplified.NumberSubtract(),
- R.javascript.Multiply(LanguageMode::SLOPPY, R.hints),
- R.simplified.NumberMultiply(),
- R.javascript.Divide(LanguageMode::SLOPPY, R.hints),
- R.simplified.NumberDivide(),
+ R.javascript.Add(R.hints), R.simplified.NumberAdd(),
+ R.javascript.Subtract(R.hints), R.simplified.NumberSubtract(),
+ R.javascript.Multiply(R.hints), R.simplified.NumberMultiply(),
+ R.javascript.Divide(R.hints), R.simplified.NumberDivide(),
};
for (size_t j = 0; j < arraysize(ops); j += 2) {
@@ -1020,10 +967,8 @@
JSTypedLoweringTester R;
const Operator* ops[] = {
- R.javascript.GreaterThan(LanguageMode::SLOPPY),
- R.simplified.NumberLessThan(),
- R.javascript.GreaterThanOrEqual(LanguageMode::SLOPPY),
- R.simplified.NumberLessThanOrEqual(),
+ R.javascript.GreaterThan(), R.simplified.NumberLessThan(),
+ R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
};
for (size_t j = 0; j < arraysize(ops); j += 2) {
@@ -1070,7 +1015,7 @@
TEST(Int32BinopEffects) {
- JSBitwiseTypedLoweringTester R(LanguageMode::SLOPPY);
+ JSBitwiseTypedLoweringTester R;
for (int j = 0; j < R.kNumberOps; j += 2) {
bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1];
BinopEffectsTester B(R.ops[j], I32Type(signed_left), I32Type(signed_right));
@@ -1150,10 +1095,9 @@
}
}
-
-TEST_WITH_STRONG(Int32AddNarrowing) {
+TEST(Int32AddNarrowing) {
{
- JSBitwiseTypedLoweringTester R(language_mode);
+ JSBitwiseTypedLoweringTester R;
for (int o = 0; o < R.kNumberOps; o += 2) {
for (size_t i = 0; i < arraysize(kInt32Types); i++) {
@@ -1176,7 +1120,7 @@
}
}
{
- JSBitwiseShiftTypedLoweringTester R(language_mode);
+ JSBitwiseShiftTypedLoweringTester R;
for (int o = 0; o < R.kNumberOps; o += 2) {
for (size_t i = 0; i < arraysize(kInt32Types); i++) {
@@ -1199,7 +1143,7 @@
}
}
{
- JSBitwiseTypedLoweringTester R(language_mode);
+ JSBitwiseTypedLoweringTester R;
for (int o = 0; o < R.kNumberOps; o += 2) {
Node* n0 = R.Parameter(I32Type(R.signedness[o]));
@@ -1222,8 +1166,7 @@
}
}
-
-TEST_WITH_STRONG(Int32Comparisons) {
+TEST(Int32Comparisons) {
JSTypedLoweringTester R;
struct Entry {
@@ -1235,17 +1178,16 @@
};
Entry ops[] = {
- {R.javascript.LessThan(language_mode), R.machine.Uint32LessThan(),
+ {R.javascript.LessThan(), R.machine.Uint32LessThan(),
R.machine.Int32LessThan(), R.simplified.NumberLessThan(), false},
- {R.javascript.LessThanOrEqual(language_mode),
- R.machine.Uint32LessThanOrEqual(), R.machine.Int32LessThanOrEqual(),
- R.simplified.NumberLessThanOrEqual(), false},
- {R.javascript.GreaterThan(language_mode), R.machine.Uint32LessThan(),
+ {R.javascript.LessThanOrEqual(), R.machine.Uint32LessThanOrEqual(),
+ R.machine.Int32LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
+ false},
+ {R.javascript.GreaterThan(), R.machine.Uint32LessThan(),
R.machine.Int32LessThan(), R.simplified.NumberLessThan(), true},
- {R.javascript.GreaterThanOrEqual(language_mode),
- R.machine.Uint32LessThanOrEqual(), R.machine.Int32LessThanOrEqual(),
- R.simplified.NumberLessThanOrEqual(), true}
- };
+ {R.javascript.GreaterThanOrEqual(), R.machine.Uint32LessThanOrEqual(),
+ R.machine.Int32LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
+ true}};
for (size_t o = 0; o < arraysize(ops); o++) {
for (size_t i = 0; i < arraysize(kNumberTypes); i++) {
diff --git a/test/cctest/compiler/test-jump-threading.cc b/test/cctest/compiler/test-jump-threading.cc
index 8c02012..71f774f 100644
--- a/test/cctest/compiler/test-jump-threading.cc
+++ b/test/cctest/compiler/test-jump-threading.cc
@@ -108,7 +108,7 @@
void VerifyForwarding(TestCode& code, int count, int* expected) {
Zone local_zone;
ZoneVector<RpoNumber> result(&local_zone);
- JumpThreading::ComputeForwarding(&local_zone, result, &code.sequence_);
+ JumpThreading::ComputeForwarding(&local_zone, result, &code.sequence_, true);
CHECK(count == static_cast<int>(result.size()));
for (int i = 0; i < count; i++) {
diff --git a/test/cctest/compiler/test-linkage.cc b/test/cctest/compiler/test-linkage.cc
index 939b144..6722f59 100644
--- a/test/cctest/compiler/test-linkage.cc
+++ b/test/cctest/compiler/test-linkage.cc
@@ -71,20 +71,6 @@
}
-TEST(TestLinkageCodeStubIncoming) {
- Isolate* isolate = CcTest::InitIsolateOnce();
- Zone zone;
- ToNumberStub stub(isolate);
- CompilationInfo info(&stub, isolate, &zone);
- CallDescriptor* descriptor = Linkage::ComputeIncoming(&zone, &info);
- CHECK(descriptor);
- CHECK_EQ(0, static_cast<int>(descriptor->StackParameterCount()));
- CHECK_EQ(1, static_cast<int>(descriptor->ReturnCount()));
- CHECK_EQ(Operator::kNoProperties, descriptor->properties());
- CHECK_EQ(false, descriptor->IsJSFunctionCall());
-}
-
-
TEST(TestLinkageJSCall) {
HandleAndZoneScope handles;
Handle<JSFunction> function = Compile("a + c");
@@ -109,6 +95,20 @@
TEST(TestLinkageStubCall) {
+ Isolate* isolate = CcTest::InitIsolateOnce();
+ Zone zone;
+ ToNumberStub stub(isolate);
+ CompilationInfo info("test", isolate, &zone, Code::ComputeFlags(Code::STUB));
+ CallInterfaceDescriptor interface_descriptor =
+ stub.GetCallInterfaceDescriptor();
+ CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
+ isolate, &zone, interface_descriptor, stub.GetStackParameterCount(),
+ CallDescriptor::kNoFlags, Operator::kNoProperties);
+ CHECK(descriptor);
+ CHECK_EQ(0, static_cast<int>(descriptor->StackParameterCount()));
+ CHECK_EQ(1, static_cast<int>(descriptor->ReturnCount()));
+ CHECK_EQ(Operator::kNoProperties, descriptor->properties());
+ CHECK_EQ(false, descriptor->IsJSFunctionCall());
// TODO(titzer): test linkage creation for outgoing stub calls.
}
diff --git a/test/cctest/compiler/test-pipeline.cc b/test/cctest/compiler/test-pipeline.cc
index f4ffd02..35e3427 100644
--- a/test/cctest/compiler/test-pipeline.cc
+++ b/test/cctest/compiler/test-pipeline.cc
@@ -18,7 +18,7 @@
ParseInfo parse_info(zone, function);
CHECK(Compiler::ParseAndAnalyze(&parse_info));
CompilationInfo info(&parse_info);
- info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
+ info.SetOptimizing();
Pipeline pipeline(&info);
Handle<Code> code = pipeline.GenerateCode();
diff --git a/test/cctest/compiler/test-run-bytecode-graph-builder.cc b/test/cctest/compiler/test-run-bytecode-graph-builder.cc
index 88555b7..9a03822 100644
--- a/test/cctest/compiler/test-run-bytecode-graph-builder.cc
+++ b/test/cctest/compiler/test-run-bytecode-graph-builder.cc
@@ -16,6 +16,14 @@
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";
@@ -70,7 +78,7 @@
i::FLAG_ignition = true;
i::FLAG_always_opt = false;
i::FLAG_allow_natives_syntax = true;
- i::FLAG_ignition_fallback_on_eval_and_catch = false;
+ i::FLAG_loop_assignment_analysis = 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);
@@ -119,13 +127,13 @@
Handle<JSFunction>::cast(v8::Utils::OpenHandle(*api_function));
CHECK(function->shared()->HasBytecodeArray());
+ // TODO(mstarzinger): We should be able to prime CompilationInfo without
+ // having to instantiate a ParseInfo first. Fix this!
ParseInfo parse_info(zone_, function);
CompilationInfo compilation_info(&parse_info);
- compilation_info.SetOptimizing(BailoutId::None(), Handle<Code>());
+ compilation_info.SetOptimizing();
compilation_info.MarkAsDeoptimizationEnabled();
- // TODO(mythria): Remove this step once parse_info is not needed.
- CHECK(Compiler::ParseAndAnalyze(&parse_info));
compiler::Pipeline pipeline(&compilation_info);
Handle<Code> code = pipeline.GenerateCode();
function->ReplaceCode(*code);
@@ -205,8 +213,7 @@
{"return 'catfood';", {factory->NewStringFromStaticChars("catfood")}},
{"return NaN;", {factory->nan_value()}}};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -233,8 +240,7 @@
{"return 25 % 7;", {factory->NewNumberFromInt(4)}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -292,8 +298,7 @@
factory->NewStringFromStaticChars("abc"),
factory->NewStringFromStaticChars("def")}}};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "function %s(p1, p2) { %s }\n%s(0, 0);", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -337,8 +342,7 @@
BytecodeGraphTester::NewObject("({ name : 'abc'})")}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(2048);
SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -394,8 +398,7 @@
factory->NewNumberFromInt(100)}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(2048);
SNPrintF(script, "function %s(p1, p2) { %s };\n%s(0);", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -409,8 +412,7 @@
}
}
-
-TEST(BytecodeGraphBuilderNamedStore) {
+void TestBytecodeGraphBuilderNamedStore(size_t shard) {
HandleAndZoneScope scope;
Isolate* isolate = scope.main_isolate();
Zone* zone = scope.main_zone();
@@ -445,8 +447,8 @@
BytecodeGraphTester::NewObject("({ name : 'abc'})")}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
+ if ((i % 2) != shard) continue;
ScopedVector<char> script(3072);
SNPrintF(script, "function %s(p1) { %s };\n%s({});", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -459,8 +461,9 @@
}
}
+SHARD_TEST_BY_2(BytecodeGraphBuilderNamedStore)
-TEST(BytecodeGraphBuilderKeyedStore) {
+void TestBytecodeGraphBuilderKeyedStore(size_t shard) {
HandleAndZoneScope scope;
Isolate* isolate = scope.main_isolate();
Zone* zone = scope.main_zone();
@@ -503,8 +506,8 @@
factory->NewNumberFromInt(100)}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
+ if ((i % 2) != shard) continue;
ScopedVector<char> script(2048);
SNPrintF(script, "function %s(p1, p2) { %s };\n%s({});", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -517,6 +520,7 @@
}
}
+SHARD_TEST_BY_2(BytecodeGraphBuilderKeyedStore)
TEST(BytecodeGraphBuilderPropertyCall) {
HandleAndZoneScope scope;
@@ -538,8 +542,7 @@
" return a + b + c + d + e + f + g + h;}})")}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(2048);
SNPrintF(script, "function %s(p1) { %s };\n%s({func() {}});", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -582,8 +585,7 @@
{factory->NewNumberFromInt(25)}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
auto callable = tester.GetCallable<>();
Handle<Object> return_value = callable().ToHandleChecked();
@@ -621,8 +623,7 @@
{factory->NewNumberFromInt(25)}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
auto callable = tester.GetCallable<>();
Handle<Object> return_value = callable().ToHandleChecked();
@@ -649,8 +650,7 @@
BytecodeGraphTester::NewObject("[1, 2, 3]")}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
auto callable = tester.GetCallable<Handle<Object>>();
Handle<Object> return_value =
@@ -659,8 +659,7 @@
}
}
-
-TEST(BytecodeGraphBuilderGlobals) {
+void TestBytecodeGraphBuilderGlobals(size_t shard) {
HandleAndZoneScope scope;
Isolate* isolate = scope.main_isolate();
Zone* zone = scope.main_zone();
@@ -700,8 +699,8 @@
{factory->NewStringFromStaticChars("number")}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
+ if ((i % 2) != shard) continue;
BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
auto callable = tester.GetCallable<>();
Handle<Object> return_value = callable().ToHandleChecked();
@@ -709,6 +708,7 @@
}
}
+SHARD_TEST_BY_2(BytecodeGraphBuilderGlobals)
TEST(BytecodeGraphBuilderToObject) {
// TODO(mythria): tests for ToObject. Needs ForIn.
@@ -746,8 +746,7 @@
{factory->NewNumberFromInt(10)}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "function %s() { %s }\n%s({});", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -778,8 +777,7 @@
{factory->false_value(), factory->NewStringFromStaticChars("abc")}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -816,8 +814,7 @@
factory->NewStringFromStaticChars("abc")}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -871,8 +868,7 @@
{factory->nan_value(), factory->NewStringFromStaticChars("String")}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -911,8 +907,7 @@
BytecodeGraphTester::NewObject("({val : 10, name:'abc'})")}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -966,8 +961,7 @@
{factory->true_value()}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "%s %s({});", snippets[i].code_snippet, kFunctionName);
@@ -1003,8 +997,7 @@
{"return delete z;", {factory->false_value()}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "%s %s %s", function_prologue, snippets[i].code_snippet,
function_epilogue);
@@ -1045,8 +1038,7 @@
{"'use strict'; obj.val = 23.456; return obj.val;",
{factory->NewNumber(23.456)}}};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "%s %s %s", function_prologue, snippets[i].code_snippet,
function_epilogue);
@@ -1089,8 +1081,7 @@
{"'use strict';" REPEAT_256(SPACE, "y = 2.3;") "return obj.val = 23.456;",
{factory->NewNumber(23.456)}}};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(3072);
SNPrintF(script, "%s %s %s", function_prologue, snippets[i].code_snippet,
function_epilogue);
@@ -1120,8 +1111,7 @@
{handle(Smi::FromInt(30), isolate)}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -1173,8 +1163,7 @@
{factory->NewStringFromStaticChars("object")}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -1202,8 +1191,7 @@
{handle(Smi::FromInt(30), isolate), handle(Smi::FromInt(20), isolate)}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "function %s(p1) { %s }\n%s(0);", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -1234,8 +1222,7 @@
{factory->NewStringFromStaticChars("undefined")}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
auto callable = tester.GetCallable<>();
Handle<Object> return_value = callable().ToHandleChecked();
@@ -1366,8 +1353,7 @@
factory->NewNumberFromInt(1)}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "function %s(p1, p2) { %s }\n%s({}, {});", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -1399,8 +1385,7 @@
{factory->true_value(), factory->undefined_value()}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -1413,6 +1398,98 @@
}
}
+TEST(BytecodeGraphBuilderTryCatch) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Zone* zone = scope.main_zone();
+
+ ExpectedSnippet<0> snippets[] = {
+ {"var a = 1; try { a = 2 } catch(e) { a = 3 }; return a;",
+ {handle(Smi::FromInt(2), isolate)}},
+ {"var a; try { undef.x } catch(e) { a = 2 }; return a;",
+ {handle(Smi::FromInt(2), isolate)}},
+ {"var a; try { throw 1 } catch(e) { a = e + 2 }; return a;",
+ {handle(Smi::FromInt(3), isolate)}},
+ {"var a; try { throw 1 } catch(e) { a = e + 2 };"
+ " try { throw a } catch(e) { a = e + 3 }; return a;",
+ {handle(Smi::FromInt(6), isolate)}},
+ };
+
+ for (size_t i = 0; i < arraysize(snippets); i++) {
+ ScopedVector<char> script(1024);
+ SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+ snippets[i].code_snippet, kFunctionName);
+
+ BytecodeGraphTester tester(isolate, zone, script.start());
+ auto callable = tester.GetCallable<>();
+ Handle<Object> return_value = callable().ToHandleChecked();
+ CHECK(return_value->SameValue(*snippets[i].return_value()));
+ }
+}
+
+TEST(BytecodeGraphBuilderTryFinally1) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Zone* zone = scope.main_zone();
+
+ ExpectedSnippet<0> snippets[] = {
+ {"var a = 1; try { a = a + 1; } finally { a = a + 2; }; return a;",
+ {handle(Smi::FromInt(4), isolate)}},
+ {"var a = 1; try { a = 2; return 23; } finally { a = 3 }; return a;",
+ {handle(Smi::FromInt(23), isolate)}},
+ {"var a = 1; try { a = 2; throw 23; } finally { return a; };",
+ {handle(Smi::FromInt(2), isolate)}},
+ {"var a = 1; for (var i = 10; i < 20; i += 5) {"
+ " try { a = 2; break; } finally { a = 3; }"
+ "} return a + i;",
+ {handle(Smi::FromInt(13), isolate)}},
+ {"var a = 1; for (var i = 10; i < 20; i += 5) {"
+ " try { a = 2; continue; } finally { a = 3; }"
+ "} return a + i;",
+ {handle(Smi::FromInt(23), isolate)}},
+ {"var a = 1; try { a = 2;"
+ " try { a = 3; throw 23; } finally { a = 4; }"
+ "} catch(e) { a = a + e; } return a;",
+ {handle(Smi::FromInt(27), isolate)}},
+ };
+
+ for (size_t i = 0; i < arraysize(snippets); i++) {
+ ScopedVector<char> script(1024);
+ SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+ snippets[i].code_snippet, kFunctionName);
+
+ BytecodeGraphTester tester(isolate, zone, script.start());
+ auto callable = tester.GetCallable<>();
+ Handle<Object> return_value = callable().ToHandleChecked();
+ CHECK(return_value->SameValue(*snippets[i].return_value()));
+ }
+}
+
+TEST(BytecodeGraphBuilderTryFinally2) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Zone* zone = scope.main_zone();
+
+ ExpectedSnippet<0, const char*> snippets[] = {
+ {"var a = 1; try { a = 2; throw 23; } finally { a = 3 }; return a;",
+ {"Uncaught 23"}},
+ {"var a = 1; try { a = 2; throw 23; } finally { throw 42; };",
+ {"Uncaught 42"}},
+ };
+
+ for (size_t i = 0; i < arraysize(snippets); i++) {
+ ScopedVector<char> script(1024);
+ SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+ snippets[i].code_snippet, kFunctionName);
+
+ BytecodeGraphTester tester(isolate, zone, script.start());
+ v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get();
+ v8::Local<v8::String> expected_string = v8_str(snippets[i].return_value());
+ CHECK(
+ message->Equals(CcTest::isolate()->GetCurrentContext(), expected_string)
+ .FromJust());
+ }
+}
TEST(BytecodeGraphBuilderThrow) {
HandleAndZoneScope scope;
@@ -1426,15 +1503,14 @@
{"throw 1;", {"Uncaught 1"}},
{"throw 'Error';", {"Uncaught Error"}},
{"throw 'Error1'; throw 'Error2'", {"Uncaught Error1"}},
- // TODO(mythria): Enable these tests when JumpIfTrue is supported.
- // {"var a = true; if (a) { throw 'Error'; }", {"Error"}},
+ {"var a = true; if (a) { throw 'Error'; }", {"Uncaught Error"}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
snippets[i].code_snippet, kFunctionName);
+
BytecodeGraphTester tester(isolate, zone, script.start());
v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get();
v8::Local<v8::String> expected_string = v8_str(snippets[i].return_value());
@@ -1492,8 +1568,7 @@
{factory->NewStringFromStaticChars("innermost inner_changed outer")}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "%s", snippets[i].code_snippet);
@@ -1558,8 +1633,7 @@
"f(0);",
{factory->NewNumberFromInt(24), factory->NewNumberFromInt(4)}}};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "%s", snippets[i].code_snippet);
@@ -1585,10 +1659,13 @@
{factory->undefined_value()}},
{"function f(a) {'use strict'; return arguments[0];}",
{factory->undefined_value()}},
+ {"function f(...restArgs) {return restArgs[0];}",
+ {factory->undefined_value()}},
+ {"function f(a, ...restArgs) {return restArgs[0];}",
+ {factory->undefined_value()}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "%s\n%s();", snippets[i].code_snippet, kFunctionName);
@@ -1631,8 +1708,7 @@
factory->NewNumberFromInt(2), factory->NewNumberFromInt(30)}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "%s\n%s();", snippets[i].code_snippet, kFunctionName);
@@ -1647,6 +1723,48 @@
}
}
+TEST(BytecodeGraphBuilderCreateRestArguments) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Zone* zone = scope.main_zone();
+ Factory* factory = isolate->factory();
+
+ ExpectedSnippet<3> snippets[] = {
+ {"function f(...restArgs) {return restArgs[0];}",
+ {factory->NewNumberFromInt(1), factory->NewNumberFromInt(1),
+ factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+ {"function f(a, b, ...restArgs) {return restArgs[0];}",
+ {factory->NewNumberFromInt(3), factory->NewNumberFromInt(1),
+ factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+ {"function f(a, b, ...restArgs) {return arguments[2];}",
+ {factory->NewNumberFromInt(3), factory->NewNumberFromInt(1),
+ factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+ {"function f(a, ...restArgs) { return restArgs[2];}",
+ {factory->undefined_value(), factory->NewNumberFromInt(1),
+ factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+ {"function f(a, ...restArgs) { return arguments[0] + restArgs[1];}",
+ {factory->NewNumberFromInt(4), factory->NewNumberFromInt(1),
+ factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+ {"function inline_func(a, ...restArgs) { return restArgs[0] }"
+ "function f(a, b, c) {return inline_func(b, c) + arguments[0];}",
+ {factory->NewNumberFromInt(31), factory->NewNumberFromInt(1),
+ factory->NewNumberFromInt(2), factory->NewNumberFromInt(30)}},
+ };
+
+ for (size_t i = 0; i < arraysize(snippets); i++) {
+ ScopedVector<char> script(1024);
+ SNPrintF(script, "%s\n%s();", snippets[i].code_snippet, kFunctionName);
+
+ BytecodeGraphTester tester(isolate, zone, script.start());
+ auto callable =
+ tester.GetCallable<Handle<Object>, Handle<Object>, Handle<Object>>();
+ Handle<Object> return_value =
+ callable(snippets[i].parameter(0), snippets[i].parameter(1),
+ snippets[i].parameter(2))
+ .ToHandleChecked();
+ CHECK(return_value->SameValue(*snippets[i].return_value()));
+ }
+}
TEST(BytecodeGraphBuilderRegExpLiterals) {
HandleAndZoneScope scope;
@@ -1671,8 +1789,7 @@
{factory->NewStringFromStaticChars("AbC")}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(4096);
SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -1712,8 +1829,7 @@
{"var t = 't'; return [[t, t + 'est'], [1 + t]][1][0];",
{factory->NewStringFromStaticChars("1t")}}};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(4096);
SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -1778,8 +1894,7 @@
{factory->NewNumberFromInt(987)}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(4096);
SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -1856,10 +1971,38 @@
" if (p1 < -10) { return -2; } else { return -1; }\n"
"}",
{factory->NewNumberFromInt(-1), factory->NewNumberFromInt(-10)}},
+ {"var b = 20, c;"
+ "if (p1 >= 0) {\n"
+ " if (b > 0) { c = 2; } else { c = 3; }\n"
+ "} else {\n"
+ " if (b < -10) { c = -2; } else { c = -1; }\n"
+ "}"
+ "return c;",
+ {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(-1)}},
+ {"var b = 20, c = 10;"
+ "if (p1 >= 0) {\n"
+ " if (b < 0) { c = 2; }\n"
+ "} else {\n"
+ " if (b < -10) { c = -2; } else { c = -1; }\n"
+ "}"
+ "return c;",
+ {factory->NewNumberFromInt(10), factory->NewNumberFromInt(1)}},
+ {"var x = 2, a = 10, b = 20, c, d;"
+ "x = 0;"
+ "if (a) {\n"
+ " b = x;"
+ " if (b > 0) { c = 2; } else { c = 3; }\n"
+ " x = 4; d = 2;"
+ "} else {\n"
+ " d = 3;\n"
+ "}"
+ "x = d;"
+ "function f1() {x}"
+ "return x + c;",
+ {factory->NewNumberFromInt(5), factory->NewNumberFromInt(-1)}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(2048);
SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -1890,8 +2033,7 @@
{factory->NewNumberFromInt(-10), factory->NewNumberFromInt(20)}},
};
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
- for (size_t i = 0; i < num_snippets; i++) {
+ for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(2048);
SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName,
snippets[i].code_snippet, kFunctionName);
@@ -1952,6 +2094,54 @@
}
}
+TEST(BytecodeGraphBuilderSwitchMerge) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Zone* zone = scope.main_zone();
+ Factory* factory = isolate->factory();
+
+ const char* switch_code =
+ "var x = 10;"
+ "switch (p1) {\n"
+ " case 1: x = 0;\n"
+ " case 2: x = 1;\n"
+ " case 3:\n"
+ " case 4: x = 2; break;\n"
+ " case 5: x = 3;\n"
+ " case 9: break;\n"
+ " default: x = 4;\n"
+ "}\n"
+ "return x;";
+
+ ExpectedSnippet<1> snippets[] = {
+ {switch_code,
+ {factory->NewNumberFromInt(2), factory->NewNumberFromInt(1)}},
+ {switch_code,
+ {factory->NewNumberFromInt(2), factory->NewNumberFromInt(2)}},
+ {switch_code,
+ {factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+ {switch_code,
+ {factory->NewNumberFromInt(2), factory->NewNumberFromInt(4)}},
+ {switch_code,
+ {factory->NewNumberFromInt(3), factory->NewNumberFromInt(5)}},
+ {switch_code,
+ {factory->NewNumberFromInt(10), factory->NewNumberFromInt(9)}},
+ {switch_code,
+ {factory->NewNumberFromInt(4), factory->NewNumberFromInt(6)}},
+ };
+
+ for (size_t i = 0; i < arraysize(snippets); i++) {
+ ScopedVector<char> script(2048);
+ SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName,
+ snippets[i].code_snippet, kFunctionName);
+
+ BytecodeGraphTester tester(isolate, zone, script.start());
+ auto callable = tester.GetCallable<Handle<Object>>();
+ Handle<Object> return_value =
+ callable(snippets[i].parameter(0)).ToHandleChecked();
+ CHECK(return_value->SameValue(*snippets[i].return_value()));
+ }
+}
TEST(BytecodeGraphBuilderNestedSwitch) {
HandleAndZoneScope scope;
@@ -2294,12 +2484,102 @@
}
-TEST(JumpWithConstantsAndWideConstants) {
+TEST(BytecodeGraphBuilderForOf) {
HandleAndZoneScope scope;
- auto isolate = scope.main_isolate();
- const int kStep = 19;
- int start = 7;
- for (int constants = start; constants < 256 + 3 * kStep; constants += kStep) {
+ Isolate* isolate = scope.main_isolate();
+ Zone* zone = scope.main_zone();
+ Factory* factory = isolate->factory();
+ ExpectedSnippet<0> snippets[] = {
+ {" var r = 0;\n"
+ " for (var a of [0,6,7,9]) { r += a; }\n"
+ " return r;\n",
+ {handle(Smi::FromInt(22), isolate)}},
+ {" var r = '';\n"
+ " for (var a of 'foobar') { r = a + r; }\n"
+ " return r;\n",
+ {factory->NewStringFromStaticChars("raboof")}},
+ {" var a = [1, 2, 3];\n"
+ " a.name = 4;\n"
+ " var r = 0;\n"
+ " for (var x of a) { r += x; }\n"
+ " return r;\n",
+ {handle(Smi::FromInt(6), isolate)}},
+ {" var r = '';\n"
+ " var data = [1, 2, 3]; \n"
+ " for (a of data) { delete data[0]; r += a; } return r;",
+ {factory->NewStringFromStaticChars("123")}},
+ {" var r = '';\n"
+ " var data = [1, 2, 3]; \n"
+ " for (a of data) { delete data[2]; r += a; } return r;",
+ {factory->NewStringFromStaticChars("12undefined")}},
+ {" var r = '';\n"
+ " var data = [1, 2, 3]; \n"
+ " for (a of data) { delete data; r += a; } return r;",
+ {factory->NewStringFromStaticChars("123")}},
+ {" var r = '';\n"
+ " var input = 'foobar';\n"
+ " for (var a of input) {\n"
+ " if (a == 'b') break;\n"
+ " r += a;\n"
+ " }\n"
+ " return r;\n",
+ {factory->NewStringFromStaticChars("foo")}},
+ {" var r = '';\n"
+ " var input = 'foobar';\n"
+ " for (var a of input) {\n"
+ " if (a == 'b') continue;\n"
+ " r += a;\n"
+ " }\n"
+ " return r;\n",
+ {factory->NewStringFromStaticChars("fooar")}},
+ {" var r = '';\n"
+ " var data = [1, 2, 3, 4]; \n"
+ " for (a of data) { data[2] = 567; r += a; }\n"
+ " return r;\n",
+ {factory->NewStringFromStaticChars("125674")}},
+ {" var r = '';\n"
+ " var data = [1, 2, 3, 4]; \n"
+ " for (a of data) { data[4] = 567; r += a; }\n"
+ " return r;\n",
+ {factory->NewStringFromStaticChars("1234567")}},
+ {" var r = '';\n"
+ " var data = [1, 2, 3, 4]; \n"
+ " for (a of data) { data[5] = 567; r += a; }\n"
+ " return r;\n",
+ {factory->NewStringFromStaticChars("1234undefined567")}},
+ {" var r = '';\n"
+ " var obj = new Object();\n"
+ " obj[Symbol.iterator] = function() { return {\n"
+ " index: 3,\n"
+ " data: ['a', 'b', 'c', 'd'],"
+ " next: function() {"
+ " return {"
+ " done: this.index == -1,\n"
+ " value: this.index < 0 ? undefined : this.data[this.index--]\n"
+ " }\n"
+ " }\n"
+ " }}\n"
+ " for (a of obj) { r += a }\n"
+ " return r;\n",
+ {factory->NewStringFromStaticChars("dcba")}},
+ };
+
+ for (size_t i = 0; i < arraysize(snippets); i++) {
+ ScopedVector<char> script(1024);
+ SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+ snippets[i].code_snippet, kFunctionName);
+
+ BytecodeGraphTester tester(isolate, zone, script.start());
+ auto callable = tester.GetCallable<>();
+ Handle<Object> return_value = callable().ToHandleChecked();
+ CHECK(return_value->SameValue(*snippets[i].return_value()));
+ }
+}
+
+void TestJumpWithConstantsAndWideConstants(size_t shard) {
+ const int kStep = 46;
+ int start = static_cast<int>(7 + 17 * shard);
+ for (int constants = start; constants < 300; constants += kStep) {
std::stringstream filler_os;
// Generate a string that consumes constant pool entries and
// spread out branch distances in script below.
@@ -2321,11 +2601,14 @@
script_os << "}\n";
script_os << kFunctionName << "(0);\n";
std::string script(script_os.str());
+
+ HandleAndZoneScope scope;
+ auto isolate = scope.main_isolate();
auto factory = isolate->factory();
auto zone = scope.main_zone();
+ BytecodeGraphTester tester(isolate, zone, script.c_str());
+ auto callable = tester.GetCallable<Handle<Object>>();
for (int a = 0; a < 3; a++) {
- BytecodeGraphTester tester(isolate, zone, script.c_str());
- auto callable = tester.GetCallable<Handle<Object>>();
Handle<Object> return_val =
callable(factory->NewNumberFromInt(a)).ToHandleChecked();
static const int results[] = {11, 12, 2};
@@ -2334,6 +2617,368 @@
}
}
+SHARD_TEST_BY_4(JumpWithConstantsAndWideConstants)
+
+TEST(BytecodeGraphBuilderDoExpressions) {
+ bool old_flag = FLAG_harmony_do_expressions;
+ FLAG_harmony_do_expressions = true;
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Zone* zone = scope.main_zone();
+ Factory* factory = isolate->factory();
+ ExpectedSnippet<0> snippets[] = {
+ {"var a = do {}; return a;", {factory->undefined_value()}},
+ {"var a = do { var x = 100; }; return a;", {factory->undefined_value()}},
+ {"var a = do { var x = 100; }; return a;", {factory->undefined_value()}},
+ {"var a = do { var x = 100; x++; }; return a;",
+ {handle(Smi::FromInt(100), isolate)}},
+ {"var i = 0; for (; i < 5;) { i = do { if (i == 3) { break; }; i + 1; }};"
+ "return i;",
+ {handle(Smi::FromInt(3), isolate)}},
+ };
+
+ for (size_t i = 0; i < arraysize(snippets); i++) {
+ ScopedVector<char> script(1024);
+ SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+ snippets[i].code_snippet, kFunctionName);
+
+ BytecodeGraphTester tester(isolate, zone, script.start());
+ auto callable = tester.GetCallable<>();
+ Handle<Object> return_value = callable().ToHandleChecked();
+ CHECK(return_value->SameValue(*snippets[i].return_value()));
+ }
+
+ FLAG_harmony_do_expressions = old_flag;
+}
+
+TEST(BytecodeGraphBuilderWithStatement) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Zone* zone = scope.main_zone();
+
+ ExpectedSnippet<0> snippets[] = {
+ {"with({x:42}) return x;", {handle(Smi::FromInt(42), isolate)}},
+ {"with({}) { var y = 10; return y;}",
+ {handle(Smi::FromInt(10), isolate)}},
+ {"var y = {x:42};"
+ " function inner() {"
+ " var x = 20;"
+ " with(y) return x;"
+ "}"
+ "return inner();",
+ {handle(Smi::FromInt(42), isolate)}},
+ {"var y = {x:42};"
+ " function inner(o) {"
+ " var x = 20;"
+ " with(o) return x;"
+ "}"
+ "return inner(y);",
+ {handle(Smi::FromInt(42), isolate)}},
+ };
+
+ for (size_t i = 0; i < arraysize(snippets); i++) {
+ ScopedVector<char> script(1024);
+ SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+ snippets[i].code_snippet, kFunctionName);
+
+ BytecodeGraphTester tester(isolate, zone, script.start());
+ auto callable = tester.GetCallable<>();
+ Handle<Object> return_value = callable().ToHandleChecked();
+ CHECK(return_value->SameValue(*snippets[i].return_value()));
+ }
+}
+
+TEST(BytecodeGraphBuilderConstDeclaration) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Zone* zone = scope.main_zone();
+ Factory* factory = isolate->factory();
+
+ ExpectedSnippet<0> snippets[] = {
+ {"const x = 3; return x;", {handle(Smi::FromInt(3), isolate)}},
+ {"let x = 10; x = x + 20; return x;",
+ {handle(Smi::FromInt(30), isolate)}},
+ {"let x = 10; x = 20; return x;", {handle(Smi::FromInt(20), isolate)}},
+ {"let x; x = 20; return x;", {handle(Smi::FromInt(20), isolate)}},
+ {"let x; return x;", {factory->undefined_value()}},
+ {"var x = 10; { let x = 30; } return x;",
+ {handle(Smi::FromInt(10), isolate)}},
+ {"let x = 10; { let x = 20; } return x;",
+ {handle(Smi::FromInt(10), isolate)}},
+ {"var x = 10; eval('let x = 20;'); return x;",
+ {handle(Smi::FromInt(10), isolate)}},
+ {"var x = 10; eval('const x = 20;'); return x;",
+ {handle(Smi::FromInt(10), isolate)}},
+ {"var x = 10; { const x = 20; } return x;",
+ {handle(Smi::FromInt(10), isolate)}},
+ {"var x = 10; { const x = 20; return x;} return -1;",
+ {handle(Smi::FromInt(20), isolate)}},
+ {"var a = 10;\n"
+ "for (var i = 0; i < 10; ++i) {\n"
+ " const x = i;\n" // const declarations are block scoped.
+ " a = a + x;\n"
+ "}\n"
+ "return a;\n",
+ {handle(Smi::FromInt(55), isolate)}},
+ };
+
+ // Tests for sloppy mode.
+ for (size_t i = 0; i < arraysize(snippets); i++) {
+ ScopedVector<char> script(1024);
+ SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+ snippets[i].code_snippet, kFunctionName);
+
+ BytecodeGraphTester tester(isolate, zone, script.start());
+ auto callable = tester.GetCallable<>();
+ Handle<Object> return_value = callable().ToHandleChecked();
+ CHECK(return_value->SameValue(*snippets[i].return_value()));
+ }
+
+ // Tests for strict mode.
+ for (size_t i = 0; i < arraysize(snippets); i++) {
+ ScopedVector<char> script(1024);
+ SNPrintF(script, "function %s() {'use strict'; %s }\n%s();", kFunctionName,
+ snippets[i].code_snippet, kFunctionName);
+
+ BytecodeGraphTester tester(isolate, zone, script.start());
+ auto callable = tester.GetCallable<>();
+ Handle<Object> return_value = callable().ToHandleChecked();
+ CHECK(return_value->SameValue(*snippets[i].return_value()));
+ }
+}
+
+TEST(BytecodeGraphBuilderConstDeclarationLookupSlots) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Zone* zone = scope.main_zone();
+ Factory* factory = isolate->factory();
+
+ ExpectedSnippet<0> snippets[] = {
+ {"const x = 3; function f1() {return x;}; return x;",
+ {handle(Smi::FromInt(3), isolate)}},
+ {"let x = 10; x = x + 20; function f1() {return x;}; return x;",
+ {handle(Smi::FromInt(30), isolate)}},
+ {"let x; x = 20; function f1() {return x;}; return x;",
+ {handle(Smi::FromInt(20), isolate)}},
+ {"let x; function f1() {return x;}; return x;",
+ {factory->undefined_value()}},
+ };
+
+ // Tests for sloppy mode.
+ for (size_t i = 0; i < arraysize(snippets); i++) {
+ ScopedVector<char> script(1024);
+ SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+ snippets[i].code_snippet, kFunctionName);
+
+ BytecodeGraphTester tester(isolate, zone, script.start());
+ auto callable = tester.GetCallable<>();
+ Handle<Object> return_value = callable().ToHandleChecked();
+ CHECK(return_value->SameValue(*snippets[i].return_value()));
+ }
+
+ // Tests for strict mode.
+ for (size_t i = 0; i < arraysize(snippets); i++) {
+ ScopedVector<char> script(1024);
+ SNPrintF(script, "function %s() {'use strict'; %s }\n%s();", kFunctionName,
+ snippets[i].code_snippet, kFunctionName);
+
+ BytecodeGraphTester tester(isolate, zone, script.start());
+ auto callable = tester.GetCallable<>();
+ Handle<Object> return_value = callable().ToHandleChecked();
+ CHECK(return_value->SameValue(*snippets[i].return_value()));
+ }
+}
+
+TEST(BytecodeGraphBuilderConstInLookupContextChain) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Zone* zone = scope.main_zone();
+
+ const char* prologue =
+ "function OuterMost() {\n"
+ " const outerConst = 10;\n"
+ " let outerLet = 20;\n"
+ " function Outer() {\n"
+ " function Inner() {\n"
+ " this.innerFunc = function() { ";
+ const char* epilogue =
+ " }\n"
+ " }\n"
+ " this.getInnerFunc ="
+ " function() {return new Inner().innerFunc;}\n"
+ " }\n"
+ " this.getOuterFunc ="
+ " function() {return new Outer().getInnerFunc();}"
+ "}\n"
+ "var f = new OuterMost().getOuterFunc();\n"
+ "f();\n";
+
+ // Tests for let / constant.
+ ExpectedSnippet<0> const_decl[] = {
+ {"return outerConst;", {handle(Smi::FromInt(10), isolate)}},
+ {"return outerLet;", {handle(Smi::FromInt(20), isolate)}},
+ {"outerLet = 30; return outerLet;", {handle(Smi::FromInt(30), isolate)}},
+ {"var outerLet = 40; return outerLet;",
+ {handle(Smi::FromInt(40), isolate)}},
+ {"var outerConst = 50; return outerConst;",
+ {handle(Smi::FromInt(50), isolate)}},
+ {"try { outerConst = 30 } catch(e) { return -1; }",
+ {handle(Smi::FromInt(-1), isolate)}}};
+
+ for (size_t i = 0; i < arraysize(const_decl); i++) {
+ ScopedVector<char> script(1024);
+ SNPrintF(script, "%s %s %s", prologue, const_decl[i].code_snippet,
+ epilogue);
+
+ BytecodeGraphTester tester(isolate, zone, script.start(), "*");
+ auto callable = tester.GetCallable<>();
+ Handle<Object> return_value = callable().ToHandleChecked();
+ CHECK(return_value->SameValue(*const_decl[i].return_value()));
+ }
+
+ // Tests for Legacy constant.
+ bool old_flag_legacy_const = FLAG_legacy_const;
+ FLAG_legacy_const = true;
+
+ ExpectedSnippet<0> legacy_const_decl[] = {
+ {"return outerConst = 23;", {handle(Smi::FromInt(23), isolate)}},
+ {"outerConst = 30; return outerConst;",
+ {handle(Smi::FromInt(10), isolate)}},
+ };
+
+ for (size_t i = 0; i < arraysize(legacy_const_decl); i++) {
+ ScopedVector<char> script(1024);
+ SNPrintF(script, "%s %s %s", prologue, legacy_const_decl[i].code_snippet,
+ epilogue);
+
+ BytecodeGraphTester tester(isolate, zone, script.start(), "*");
+ auto callable = tester.GetCallable<>();
+ Handle<Object> return_value = callable().ToHandleChecked();
+ CHECK(return_value->SameValue(*legacy_const_decl[i].return_value()));
+ }
+
+ FLAG_legacy_const = old_flag_legacy_const;
+}
+
+TEST(BytecodeGraphBuilderIllegalConstDeclaration) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Zone* zone = scope.main_zone();
+
+ ExpectedSnippet<0, const char*> illegal_const_decl[] = {
+ {"const x = x = 10 + 3; return x;",
+ {"Uncaught ReferenceError: x is not defined"}},
+ {"const x = 10; x = 20; return x;",
+ {"Uncaught TypeError: Assignment to constant variable."}},
+ {"const x = 10; { x = 20; } return x;",
+ {"Uncaught TypeError: Assignment to constant variable."}},
+ {"const x = 10; eval('x = 20;'); return x;",
+ {"Uncaught TypeError: Assignment to constant variable."}},
+ {"let x = x + 10; return x;",
+ {"Uncaught ReferenceError: x is not defined"}},
+ {"'use strict'; (function f1() { f1 = 123; })() ",
+ {"Uncaught TypeError: Assignment to constant variable."}},
+ };
+
+ // Tests for sloppy mode.
+ for (size_t i = 0; i < arraysize(illegal_const_decl); i++) {
+ ScopedVector<char> script(1024);
+ SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+ illegal_const_decl[i].code_snippet, kFunctionName);
+
+ BytecodeGraphTester tester(isolate, zone, script.start());
+ v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get();
+ v8::Local<v8::String> expected_string =
+ v8_str(illegal_const_decl[i].return_value());
+ CHECK(
+ message->Equals(CcTest::isolate()->GetCurrentContext(), expected_string)
+ .FromJust());
+ }
+
+ // Tests for strict mode.
+ for (size_t i = 0; i < arraysize(illegal_const_decl); i++) {
+ ScopedVector<char> script(1024);
+ SNPrintF(script, "function %s() {'use strict'; %s }\n%s();", kFunctionName,
+ illegal_const_decl[i].code_snippet, kFunctionName);
+
+ BytecodeGraphTester tester(isolate, zone, script.start());
+ v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get();
+ v8::Local<v8::String> expected_string =
+ v8_str(illegal_const_decl[i].return_value());
+ CHECK(
+ message->Equals(CcTest::isolate()->GetCurrentContext(), expected_string)
+ .FromJust());
+ }
+}
+
+TEST(BytecodeGraphBuilderLegacyConstDeclaration) {
+ bool old_flag_legacy_const = FLAG_legacy_const;
+ FLAG_legacy_const = true;
+
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Zone* zone = scope.main_zone();
+
+ ExpectedSnippet<0> snippets[] = {
+ {"const x = (x = 10) + 3; return x;",
+ {handle(Smi::FromInt(13), isolate)}},
+ {"const x = 10; x = 20; return x;", {handle(Smi::FromInt(10), isolate)}},
+ {"var a = 10;\n"
+ "for (var i = 0; i < 10; ++i) {\n"
+ " const x = i;\n" // Legacy constants are not block scoped.
+ " a = a + x;\n"
+ "}\n"
+ "return a;\n",
+ {handle(Smi::FromInt(10), isolate)}},
+ {"const x = 20; eval('x = 10;'); return x;",
+ {handle(Smi::FromInt(20), isolate)}},
+ };
+
+ for (size_t i = 0; i < arraysize(snippets); i++) {
+ ScopedVector<char> script(1024);
+ SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+ snippets[i].code_snippet, kFunctionName);
+
+ BytecodeGraphTester tester(isolate, zone, script.start());
+ auto callable = tester.GetCallable<>();
+ Handle<Object> return_value = callable().ToHandleChecked();
+ CHECK(return_value->SameValue(*snippets[i].return_value()));
+ }
+
+ FLAG_legacy_const = old_flag_legacy_const;
+}
+
+TEST(BytecodeGraphBuilderDebuggerStatement) {
+ FLAG_expose_debug_as = "debug";
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Zone* zone = scope.main_zone();
+
+ ExpectedSnippet<0> snippet = {
+ "var Debug = debug.Debug;"
+ "var count = 0;"
+ "function f() {"
+ " debugger;"
+ "}"
+ "function listener(event) {"
+ " if (event == Debug.DebugEvent.Break) count++;"
+ "}"
+ "Debug.setListener(listener);"
+ "f();"
+ "Debug.setListener(null);"
+ "return count;",
+ {handle(Smi::FromInt(1), isolate)}};
+
+ ScopedVector<char> script(1024);
+ SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+ snippet.code_snippet, kFunctionName);
+
+ BytecodeGraphTester tester(isolate, zone, script.start());
+ auto callable = tester.GetCallable<>();
+ Handle<Object> return_value = callable().ToHandleChecked();
+ CHECK(return_value->SameValue(*snippet.return_value()));
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/test/cctest/compiler/test-run-deopt.cc b/test/cctest/compiler/test-run-deopt.cc
index 8b4c9dc..76dc9ac 100644
--- a/test/cctest/compiler/test-run-deopt.cc
+++ b/test/cctest/compiler/test-run-deopt.cc
@@ -84,7 +84,6 @@
TEST(DeoptExceptionHandlerFinally) {
FLAG_allow_natives_syntax = true;
- FLAG_turbo_try_finally = true;
FunctionTester T(
"(function f() {"
@@ -98,9 +97,7 @@
CompileRun("function DeoptAndThrow(f) { %DeoptimizeFunction(f); throw 0; }");
InstallIsOptimizedHelper(CcTest::isolate());
-#if 0 // TODO(4195,mstarzinger): Reproduces on MIPS64, re-enable once fixed.
T.CheckCall(T.false_value());
-#endif
}
diff --git a/test/cctest/compiler/test-run-intrinsics.cc b/test/cctest/compiler/test-run-intrinsics.cc
index b201711..6e9ebf2 100644
--- a/test/cctest/compiler/test-run-intrinsics.cc
+++ b/test/cctest/compiler/test-run-intrinsics.cc
@@ -104,18 +104,6 @@
}
-TEST(IsMinusZero) {
- FunctionTester T("(function(a) { return %_IsMinusZero(a); })", flags);
-
- T.CheckFalse(T.Val(1));
- T.CheckFalse(T.Val(1.1));
- T.CheckTrue(T.Val(-0.0));
- T.CheckFalse(T.Val(-2));
- T.CheckFalse(T.Val(-2.3));
- T.CheckFalse(T.undefined());
-}
-
-
TEST(IsRegExp) {
FunctionTester T("(function(a) { return %_IsRegExp(a); })", flags);
@@ -148,19 +136,6 @@
}
-TEST(ObjectEquals) {
- FunctionTester T("(function(a,b) { return %_ObjectEquals(a,b); })", flags);
- CompileRun("var o = {}");
-
- T.CheckTrue(T.NewObject("(o)"), T.NewObject("(o)"));
- T.CheckTrue(T.Val("internal"), T.Val("internal"));
- T.CheckTrue(T.true_value(), T.true_value());
- T.CheckFalse(T.true_value(), T.false_value());
- T.CheckFalse(T.NewObject("({})"), T.NewObject("({})"));
- T.CheckFalse(T.Val("a"), T.Val("b"));
-}
-
-
TEST(OneByteSeqStringGetChar) {
FunctionTester T("(function(a,b) { return %_OneByteSeqStringGetChar(a,b); })",
flags);
@@ -192,15 +167,6 @@
}
-TEST(SetValueOf) {
- FunctionTester T("(function(a,b) { return %_SetValueOf(a,b); })", flags);
-
- T.CheckCall(T.Val("a"), T.NewObject("(new String)"), T.Val("a"));
- T.CheckCall(T.Val(123), T.NewObject("(new Number)"), T.Val(123));
- T.CheckCall(T.Val("x"), T.undefined(), T.Val("x"));
-}
-
-
TEST(StringAdd) {
FunctionTester T("(function(a,b) { return %_StringAdd(a,b); })", flags);
diff --git a/test/cctest/compiler/test-run-jscalls.cc b/test/cctest/compiler/test-run-jscalls.cc
index 474453d..c282958 100644
--- a/test/cctest/compiler/test-run-jscalls.cc
+++ b/test/cctest/compiler/test-run-jscalls.cc
@@ -21,37 +21,36 @@
TEST(SimpleCall2) {
FunctionTester T("(function(foo,a) { return foo(a); })");
- Handle<JSFunction> foo = T.NewFunction("(function(a) { return a; })");
- T.Compile(foo);
+ FunctionTester U("(function(a) { return a; })");
- T.CheckCall(T.Val(3), foo, T.Val(3));
- T.CheckCall(T.Val(3.1), foo, T.Val(3.1));
- T.CheckCall(foo, foo, foo);
- T.CheckCall(T.Val("Abba"), foo, T.Val("Abba"));
+ T.CheckCall(T.Val(3), U.function, T.Val(3));
+ T.CheckCall(T.Val(3.1), U.function, T.Val(3.1));
+ T.CheckCall(U.function, U.function, U.function);
+ T.CheckCall(T.Val("Abba"), U.function, T.Val("Abba"));
}
TEST(ConstCall) {
FunctionTester T("(function(foo,a) { return foo(a,3); })");
- Handle<JSFunction> foo = T.NewFunction("(function(a,b) { return a + b; })");
- T.Compile(foo);
+ FunctionTester U("(function(a,b) { return a + b; })");
- T.CheckCall(T.Val(6), foo, T.Val(3));
- T.CheckCall(T.Val(6.1), foo, T.Val(3.1));
- T.CheckCall(T.Val("function (a,b) { return a + b; }3"), foo, foo);
- T.CheckCall(T.Val("Abba3"), foo, T.Val("Abba"));
+ T.CheckCall(T.Val(6), U.function, T.Val(3));
+ T.CheckCall(T.Val(6.1), U.function, T.Val(3.1));
+ T.CheckCall(T.Val("function (a,b) { return a + b; }3"), U.function,
+ U.function);
+ T.CheckCall(T.Val("Abba3"), U.function, T.Val("Abba"));
}
TEST(ConstCall2) {
FunctionTester T("(function(foo,a) { return foo(a,\"3\"); })");
- Handle<JSFunction> foo = T.NewFunction("(function(a,b) { return a + b; })");
- T.Compile(foo);
+ FunctionTester U("(function(a,b) { return a + b; })");
- T.CheckCall(T.Val("33"), foo, T.Val(3));
- T.CheckCall(T.Val("3.13"), foo, T.Val(3.1));
- T.CheckCall(T.Val("function (a,b) { return a + b; }3"), foo, foo);
- T.CheckCall(T.Val("Abba3"), foo, T.Val("Abba"));
+ T.CheckCall(T.Val("33"), U.function, T.Val(3));
+ T.CheckCall(T.Val("3.13"), U.function, T.Val(3.1));
+ T.CheckCall(T.Val("function (a,b) { return a + b; }3"), U.function,
+ U.function);
+ T.CheckCall(T.Val("Abba3"), U.function, T.Val("Abba"));
}
@@ -130,7 +129,6 @@
}
-// TODO(titzer): factor these out into test-runtime-calls.cc
TEST(RuntimeCallCPP2) {
FLAG_allow_natives_syntax = true;
FunctionTester T("(function(a,b) { return %NumberImul(a, b); })");
diff --git a/test/cctest/compiler/test-run-jsexceptions.cc b/test/cctest/compiler/test-run-jsexceptions.cc
index 37b2a2d..ab8c42a 100644
--- a/test/cctest/compiler/test-run-jsexceptions.cc
+++ b/test/cctest/compiler/test-run-jsexceptions.cc
@@ -61,7 +61,6 @@
TEST(ThrowMessageIndirectly) {
- i::FLAG_turbo_try_finally = true;
static const char* src =
"(function(a, b) {"
" try {"
@@ -170,7 +169,6 @@
TEST(Finally) {
- i::FLAG_turbo_try_finally = true;
const char* src =
"(function(a,b) {"
" var r = '-';"
@@ -188,7 +186,6 @@
TEST(FinallyBreak) {
- i::FLAG_turbo_try_finally = true;
const char* src =
"(function(a,b) {"
" var r = '-';"
@@ -244,7 +241,6 @@
TEST(DeoptFinallyReturn) {
- i::FLAG_turbo_try_finally = true;
const char* src =
"(function f(a) {"
" try {"
@@ -261,7 +257,6 @@
TEST(DeoptFinallyReThrow) {
- i::FLAG_turbo_try_finally = true;
const char* src =
"(function f(a) {"
" try {"
@@ -272,9 +267,7 @@
"})";
FunctionTester T(src);
-#if 0 // TODO(mstarzinger): Enable once we can.
T.CheckThrows(T.NewObject("new Error"), T.Val(1));
-#endif
}
} // namespace compiler
diff --git a/test/cctest/compiler/test-run-machops.cc b/test/cctest/compiler/test-run-machops.cc
index 11a3582..fba9e0e 100644
--- a/test/cctest/compiler/test-run-machops.cc
+++ b/test/cctest/compiler/test-run-machops.cc
@@ -29,6 +29,25 @@
}
+TEST(RunWord32ReverseBits) {
+ BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
+ if (!m.machine()->Word32ReverseBits().IsSupported()) {
+ // We can only test the operator if it exists on the testing platform.
+ return;
+ }
+ m.Return(m.AddNode(m.machine()->Word32ReverseBits().op(), m.Parameter(0)));
+
+ CHECK_EQ(uint32_t(0x00000000), m.Call(uint32_t(0x00000000)));
+ CHECK_EQ(uint32_t(0x12345678), m.Call(uint32_t(0x1e6a2c48)));
+ CHECK_EQ(uint32_t(0xfedcba09), m.Call(uint32_t(0x905d3b7f)));
+ CHECK_EQ(uint32_t(0x01010101), m.Call(uint32_t(0x80808080)));
+ CHECK_EQ(uint32_t(0x01020408), m.Call(uint32_t(0x10204080)));
+ CHECK_EQ(uint32_t(0xf0703010), m.Call(uint32_t(0x080c0e0f)));
+ CHECK_EQ(uint32_t(0x1f8d0a3a), m.Call(uint32_t(0x5c50b1f8)));
+ CHECK_EQ(uint32_t(0xffffffff), m.Call(uint32_t(0xffffffff)));
+}
+
+
TEST(RunWord32Ctz) {
BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
if (!m.machine()->Word32Ctz().IsSupported()) {
@@ -72,7 +91,6 @@
CHECK_EQ(0, m.Call(uint32_t(0x9afdbc81)));
}
-
TEST(RunWord32Clz) {
BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
m.Return(m.Word32Clz(m.Parameter(0)));
@@ -133,6 +151,25 @@
#if V8_TARGET_ARCH_64_BIT
+TEST(RunWord64ReverseBits) {
+ RawMachineAssemblerTester<uint64_t> m(MachineType::Uint64());
+ if (!m.machine()->Word64ReverseBits().IsSupported()) {
+ return;
+ }
+
+ m.Return(m.AddNode(m.machine()->Word64ReverseBits().op(), m.Parameter(0)));
+
+ CHECK_EQ(uint64_t(0x0000000000000000), m.Call(uint64_t(0x0000000000000000)));
+ CHECK_EQ(uint64_t(0x1234567890abcdef), m.Call(uint64_t(0xf7b3d5091e6a2c48)));
+ CHECK_EQ(uint64_t(0xfedcba0987654321), m.Call(uint64_t(0x84c2a6e1905d3b7f)));
+ CHECK_EQ(uint64_t(0x0101010101010101), m.Call(uint64_t(0x8080808080808080)));
+ CHECK_EQ(uint64_t(0x0102040803060c01), m.Call(uint64_t(0x803060c010204080)));
+ CHECK_EQ(uint64_t(0xf0703010e060200f), m.Call(uint64_t(0xf0040607080c0e0f)));
+ CHECK_EQ(uint64_t(0x2f8a6df01c21fa3b), m.Call(uint64_t(0xdc5f84380fb651f4)));
+ CHECK_EQ(uint64_t(0xffffffffffffffff), m.Call(uint64_t(0xffffffffffffffff)));
+}
+
+
TEST(RunWord64Clz) {
BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint64());
m.Return(m.Word64Clz(m.Parameter(0)));
@@ -3534,7 +3571,7 @@
const int kNumElems = 3;
Type buffer[kNumElems];
- // initialize the buffer with raw data.
+ // initialize the buffer with some raw data.
byte* raw = reinterpret_cast<byte*>(buffer);
for (size_t i = 0; i < sizeof(buffer); i++) {
raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA);
@@ -3543,14 +3580,14 @@
// Test with various large and small offsets.
for (int offset = -1; offset <= 200000; offset *= -5) {
for (int i = 0; i < kNumElems; i++) {
- RawMachineAssemblerTester<Type> m;
+ BufferedRawMachineAssemblerTester<Type> m;
Node* base = m.PointerConstant(buffer - offset);
Node* index = m.Int32Constant((offset + i) * sizeof(buffer[0]));
m.Return(m.Load(rep, base, index));
- Type expected = buffer[i];
- Type actual = m.Call();
- CHECK(expected == actual);
+ volatile Type expected = buffer[i];
+ volatile Type actual = m.Call();
+ CHECK_EQ(expected, actual);
}
}
}
@@ -3564,9 +3601,11 @@
RunLoadImmIndex<int32_t>(MachineType::Int32());
RunLoadImmIndex<uint32_t>(MachineType::Uint32());
RunLoadImmIndex<int32_t*>(MachineType::AnyTagged());
-
- // TODO(titzer): test kRepBit loads
- // TODO(titzer): test MachineType::Float64() loads
+ RunLoadImmIndex<float>(MachineType::Float32());
+ RunLoadImmIndex<double>(MachineType::Float64());
+ if (kPointerSize == 8) {
+ RunLoadImmIndex<int64_t>(MachineType::Int64());
+ }
// TODO(titzer): test various indexing modes.
}
@@ -4124,6 +4163,43 @@
}
+TEST(RunTruncateFloat32ToInt32) {
+ BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Float32());
+ m.Return(m.TruncateFloat32ToInt32(m.Parameter(0)));
+ FOR_FLOAT32_INPUTS(i) {
+ if (*i <= static_cast<float>(std::numeric_limits<int32_t>::max()) &&
+ *i >= static_cast<float>(std::numeric_limits<int32_t>::min())) {
+ CheckFloatEq(static_cast<int32_t>(*i), m.Call(*i));
+ }
+ }
+}
+
+
+TEST(RunTruncateFloat32ToUint32) {
+ BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float32());
+ m.Return(m.TruncateFloat32ToUint32(m.Parameter(0)));
+ {
+ FOR_UINT32_INPUTS(i) {
+ float input = static_cast<float>(*i);
+ // This condition on 'input' is required because
+ // static_cast<float>(std::numeric_limits<uint32_t>::max()) results in a
+ // value outside uint32 range.
+ if (input < static_cast<float>(std::numeric_limits<uint32_t>::max())) {
+ CHECK_EQ(static_cast<uint32_t>(input), m.Call(input));
+ }
+ }
+ }
+ {
+ FOR_FLOAT32_INPUTS(i) {
+ if (*i <= static_cast<float>(std::numeric_limits<uint32_t>::max()) &&
+ *i >= static_cast<float>(std::numeric_limits<uint32_t>::min())) {
+ CheckFloatEq(static_cast<uint32_t>(*i), m.Call(*i));
+ }
+ }
+ }
+}
+
+
TEST(RunChangeFloat64ToInt32_A) {
BufferedRawMachineAssemblerTester<int32_t> m;
double magic = 11.1;
@@ -5577,6 +5653,79 @@
}
#endif // USE_SIMULATOR
+template <typename T>
+void TestExternalReferenceFunction(
+ BufferedRawMachineAssemblerTester<int32_t>* m, ExternalReference ref,
+ T (*comparison)(T)) {
+ T parameter;
+
+ Node* function = m->ExternalConstant(ref);
+ m->CallCFunction1(MachineType::Pointer(), MachineType::Pointer(), function,
+ m->PointerConstant(¶meter));
+ m->Return(m->Int32Constant(4356));
+ FOR_FLOAT64_INPUTS(i) {
+ parameter = *i;
+ m->Call();
+ CheckDoubleEq(comparison(*i), parameter);
+ }
+}
+
+TEST(RunCallExternalReferenceF32Trunc) {
+ BufferedRawMachineAssemblerTester<int32_t> m;
+ ExternalReference ref =
+ ExternalReference::f32_trunc_wrapper_function(m.isolate());
+ TestExternalReferenceFunction<float>(&m, ref, truncf);
+}
+
+TEST(RunCallExternalReferenceF32Floor) {
+ BufferedRawMachineAssemblerTester<int32_t> m;
+ ExternalReference ref =
+ ExternalReference::f32_floor_wrapper_function(m.isolate());
+ TestExternalReferenceFunction<float>(&m, ref, floorf);
+}
+
+TEST(RunCallExternalReferenceF32Ceil) {
+ BufferedRawMachineAssemblerTester<int32_t> m;
+ ExternalReference ref =
+ ExternalReference::f32_ceil_wrapper_function(m.isolate());
+ TestExternalReferenceFunction<float>(&m, ref, ceilf);
+}
+
+TEST(RunCallExternalReferenceF32RoundTiesEven) {
+ BufferedRawMachineAssemblerTester<int32_t> m;
+ ExternalReference ref =
+ ExternalReference::f32_nearest_int_wrapper_function(m.isolate());
+ TestExternalReferenceFunction<float>(&m, ref, nearbyintf);
+}
+
+TEST(RunCallExternalReferenceF64Trunc) {
+ BufferedRawMachineAssemblerTester<int32_t> m;
+ ExternalReference ref =
+ ExternalReference::f64_trunc_wrapper_function(m.isolate());
+ TestExternalReferenceFunction<double>(&m, ref, trunc);
+}
+
+TEST(RunCallExternalReferenceF64Floor) {
+ BufferedRawMachineAssemblerTester<int32_t> m;
+ ExternalReference ref =
+ ExternalReference::f64_floor_wrapper_function(m.isolate());
+ TestExternalReferenceFunction<double>(&m, ref, floor);
+}
+
+TEST(RunCallExternalReferenceF64Ceil) {
+ BufferedRawMachineAssemblerTester<int32_t> m;
+ ExternalReference ref =
+ ExternalReference::f64_ceil_wrapper_function(m.isolate());
+ TestExternalReferenceFunction<double>(&m, ref, ceil);
+}
+
+TEST(RunCallExternalReferenceF64RoundTiesEven) {
+ BufferedRawMachineAssemblerTester<int32_t> m;
+ ExternalReference ref =
+ ExternalReference::f64_nearest_int_wrapper_function(m.isolate());
+ TestExternalReferenceFunction<double>(&m, ref, nearbyint);
+}
+
#if V8_TARGET_ARCH_64_BIT
// TODO(titzer): run int64 tests on all platforms when supported.
TEST(RunCheckedLoadInt64) {
@@ -6001,6 +6150,26 @@
}
+TEST(RunRoundInt32ToFloat32) {
+ BufferedRawMachineAssemblerTester<float> m(MachineType::Int32());
+ m.Return(m.RoundInt32ToFloat32(m.Parameter(0)));
+ FOR_INT32_INPUTS(i) {
+ volatile float expected = static_cast<float>(*i);
+ CHECK_EQ(expected, m.Call(*i));
+ }
+}
+
+
+TEST(RunRoundUint32ToFloat32) {
+ BufferedRawMachineAssemblerTester<float> m(MachineType::Uint32());
+ m.Return(m.RoundUint32ToFloat32(m.Parameter(0)));
+ FOR_UINT32_INPUTS(i) {
+ volatile float expected = static_cast<float>(*i);
+ CHECK_EQ(expected, m.Call(*i));
+ }
+}
+
+
TEST(RunBitcastInt32ToFloat32) {
int32_t input = 1;
float output = 0.0;
@@ -6068,6 +6237,27 @@
CHECK_EQ(44, r.Call(0));
}
+TEST(ParentFramePointer) {
+ RawMachineAssemblerTester<int32_t> r(MachineType::Int32());
+ RawMachineLabel tlabel;
+ RawMachineLabel flabel;
+ RawMachineLabel merge;
+ Node* frame = r.LoadFramePointer();
+ Node* parent_frame = r.LoadParentFramePointer();
+ frame = r.Load(MachineType::IntPtr(), frame);
+ r.Branch(r.WordEqual(frame, parent_frame), &tlabel, &flabel);
+ r.Bind(&tlabel);
+ Node* fa = r.Int32Constant(1);
+ r.Goto(&merge);
+ r.Bind(&flabel);
+ Node* fb = r.Int32Constant(0);
+ r.Goto(&merge);
+ r.Bind(&merge);
+ Node* phi = r.Phi(MachineRepresentation::kWord32, fa, fb);
+ r.Return(phi);
+ CHECK_EQ(1, r.Call(1));
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/test/cctest/compiler/test-run-native-calls.cc b/test/cctest/compiler/test-run-native-calls.cc
index 791b0d7..8911409 100644
--- a/test/cctest/compiler/test-run-native-calls.cc
+++ b/test/cctest/compiler/test-run-native-calls.cc
@@ -1157,6 +1157,99 @@
TEST(MixedParams_2) { MixedParamTest(2); }
TEST(MixedParams_3) { MixedParamTest(3); }
+template <typename T>
+void TestStackSlot(MachineType slot_type, T expected) {
+ // Test: Generate with a function f which reserves a stack slot, call an inner
+ // function g from f which writes into the stack slot of f.
+
+ if (RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+ ->num_allocatable_double_registers() < 2)
+ return;
+
+ Isolate* isolate = CcTest::InitIsolateOnce();
+
+ // Lots of code to generate the build descriptor for the inner function.
+ int parray_gp[] = {
+ RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+ ->GetAllocatableGeneralCode(0),
+ RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+ ->GetAllocatableGeneralCode(1)};
+ int rarray_gp[] = {
+ RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+ ->GetAllocatableGeneralCode(0)};
+ int parray_fp[] = {
+ RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+ ->GetAllocatableDoubleCode(0),
+ RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+ ->GetAllocatableDoubleCode(1)};
+ int rarray_fp[] = {
+ RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+ ->GetAllocatableDoubleCode(0)};
+ Allocator palloc(parray_gp, 2, parray_fp, 2);
+ Allocator ralloc(rarray_gp, 1, rarray_fp, 1);
+ RegisterConfig config(palloc, ralloc);
+
+ Zone zone;
+ HandleScope scope(isolate);
+ MachineSignature::Builder builder(&zone, 1, 12);
+ builder.AddReturn(MachineType::Int32());
+ for (int i = 0; i < 10; i++) {
+ builder.AddParam(MachineType::Int32());
+ }
+ builder.AddParam(slot_type);
+ builder.AddParam(MachineType::Pointer());
+ MachineSignature* sig = builder.Build();
+ CallDescriptor* desc = config.Create(&zone, sig);
+
+ // Create inner function g. g has lots of parameters so that they are passed
+ // over the stack.
+ Handle<Code> inner;
+ Graph graph(&zone);
+ RawMachineAssembler g(isolate, &graph, desc);
+
+ g.Store(slot_type.representation(), g.Parameter(11), g.Parameter(10),
+ WriteBarrierKind::kNoWriteBarrier);
+ g.Return(g.Parameter(9));
+ inner = CompileGraph("Compute", desc, &graph, g.Export());
+
+ // Create function f with a stack slot which calls the inner function g.
+ BufferedRawMachineAssemblerTester<T> f(slot_type);
+ Node* target = f.HeapConstant(inner);
+ Node* stack_slot = f.StackSlot(slot_type.representation());
+ Node* args[12];
+ for (int i = 0; i < 10; i++) {
+ args[i] = f.Int32Constant(i);
+ }
+ args[10] = f.Parameter(0);
+ args[11] = stack_slot;
+
+ f.CallN(desc, target, args);
+ f.Return(f.Load(slot_type, stack_slot, f.IntPtrConstant(0)));
+
+ CHECK_EQ(expected, f.Call(expected));
+}
+
+TEST(RunStackSlotInt32) {
+ int32_t magic = 0x12345678;
+ TestStackSlot(MachineType::Int32(), magic);
+}
+
+#if !V8_TARGET_ARCH_32_BIT
+TEST(RunStackSlotInt64) {
+ int64_t magic = 0x123456789abcdef0;
+ TestStackSlot(MachineType::Int64(), magic);
+}
+#endif
+
+TEST(RunStackSlotFloat32) {
+ float magic = 1234.125f;
+ TestStackSlot(MachineType::Float32(), magic);
+}
+
+TEST(RunStackSlotFloat64) {
+ double magic = 3456.375;
+ TestStackSlot(MachineType::Float64(), magic);
+}
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/test/cctest/compiler/test-run-properties.cc b/test/cctest/compiler/test-run-properties.cc
deleted file mode 100644
index 3c42102..0000000
--- a/test/cctest/compiler/test-run-properties.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-// 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.
-
-#include "test/cctest/compiler/function-tester.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-template <typename U>
-static void TypedArrayLoadHelper(const char* array_type) {
- static const uint32_t kValues[] = {
- 0x00000000, 0x00000001, 0x00000023, 0x00000042, 0x12345678, 0x87654321,
- 0x0000003f, 0x0000007f, 0x00003fff, 0x00007fff, 0x3fffffff, 0x7fffffff,
- 0x000000ff, 0x00000080, 0x0000ffff, 0x00008000, 0xffffffff, 0x80000000};
- EmbeddedVector<char, 1024> values_buffer;
- StringBuilder values_builder(values_buffer.start(), values_buffer.length());
- for (size_t i = 0; i < arraysize(kValues); ++i) {
- values_builder.AddFormatted("a[%d] = 0x%08x;", i, kValues[i]);
- }
-
- // Note that below source creates two different typed arrays with the same
- // elements kind to get coverage for both (on heap / with external backing
- // store) access patterns.
- const char* source =
- "(function(a) {"
- " var x = (a = new %sArray(%d)); %s;"
- " var y = (a = new %sArray(%d)); %s; %%TypedArrayGetBuffer(y);"
- " if (!%%HasFixed%sElements(x)) %%AbortJS('x');"
- " if (!%%HasFixed%sElements(y)) %%AbortJS('y');"
- " function f(a,b) {"
- " a = a | 0; b = b | 0;"
- " return x[a] + y[b];"
- " }"
- " return f;"
- "})()";
- EmbeddedVector<char, 1024> source_buffer;
- SNPrintF(source_buffer, source, array_type, arraysize(kValues),
- values_buffer.start(), array_type, arraysize(kValues),
- values_buffer.start(), array_type, array_type);
-
- FunctionTester T(source_buffer.start(),
- CompilationInfo::kFunctionContextSpecializing |
- CompilationInfo::kTypingEnabled);
- for (size_t i = 0; i < arraysize(kValues); ++i) {
- for (size_t j = 0; j < arraysize(kValues); ++j) {
- volatile U value_a = static_cast<U>(kValues[i]);
- volatile U value_b = static_cast<U>(kValues[j]);
- double expected =
- static_cast<double>(value_a) + static_cast<double>(value_b);
- T.CheckCall(T.Val(expected), T.Val(static_cast<double>(i)),
- T.Val(static_cast<double>(j)));
- }
- }
-}
-
-
-TEST(TypedArrayLoad) {
- FLAG_typed_array_max_size_in_heap = 256;
- TypedArrayLoadHelper<int8_t>("Int8");
- TypedArrayLoadHelper<uint8_t>("Uint8");
- TypedArrayLoadHelper<int16_t>("Int16");
- TypedArrayLoadHelper<uint16_t>("Uint16");
- TypedArrayLoadHelper<int32_t>("Int32");
- TypedArrayLoadHelper<uint32_t>("Uint32");
- TypedArrayLoadHelper<float>("Float32");
- TypedArrayLoadHelper<double>("Float64");
- // TODO(mstarzinger): Add tests for ClampedUint8.
-}
-
-
-template <typename U>
-static void TypedArrayStoreHelper(const char* array_type) {
- static const uint32_t kValues[] = {
- 0x00000000, 0x00000001, 0x00000023, 0x00000042, 0x12345678, 0x87654321,
- 0x0000003f, 0x0000007f, 0x00003fff, 0x00007fff, 0x3fffffff, 0x7fffffff,
- 0x000000ff, 0x00000080, 0x0000ffff, 0x00008000, 0xffffffff, 0x80000000};
- EmbeddedVector<char, 1024> values_buffer;
- StringBuilder values_builder(values_buffer.start(), values_buffer.length());
- for (size_t i = 0; i < arraysize(kValues); ++i) {
- values_builder.AddFormatted("a[%d] = 0x%08x;", i, kValues[i]);
- }
-
- // Note that below source creates two different typed arrays with the same
- // elements kind to get coverage for both (on heap/with external backing
- // store) access patterns.
- const char* source =
- "(function(a) {"
- " var x = (a = new %sArray(%d)); %s;"
- " var y = (a = new %sArray(%d)); %s; %%TypedArrayGetBuffer(y);"
- " if (!%%HasFixed%sElements(x)) %%AbortJS('x');"
- " if (!%%HasFixed%sElements(y)) %%AbortJS('y');"
- " function f(a,b) {"
- " a = a | 0; b = b | 0;"
- " var t = x[a];"
- " x[a] = y[b];"
- " y[b] = t;"
- " t = y[b];"
- " y[b] = x[a];"
- " x[a] = t;"
- " return x[a] + y[b];"
- " }"
- " return f;"
- "})()";
- EmbeddedVector<char, 2048> source_buffer;
- SNPrintF(source_buffer, source, array_type, arraysize(kValues),
- values_buffer.start(), array_type, arraysize(kValues),
- values_buffer.start(), array_type, array_type);
-
- FunctionTester T(source_buffer.start(),
- CompilationInfo::kFunctionContextSpecializing |
- CompilationInfo::kTypingEnabled);
- for (size_t i = 0; i < arraysize(kValues); ++i) {
- for (size_t j = 0; j < arraysize(kValues); ++j) {
- volatile U value_a = static_cast<U>(kValues[i]);
- volatile U value_b = static_cast<U>(kValues[j]);
- double expected =
- static_cast<double>(value_a) + static_cast<double>(value_b);
- T.CheckCall(T.Val(expected), T.Val(static_cast<double>(i)),
- T.Val(static_cast<double>(j)));
- }
- }
-}
-
-
-TEST(TypedArrayStore) {
- FLAG_typed_array_max_size_in_heap = 256;
- TypedArrayStoreHelper<int8_t>("Int8");
- TypedArrayStoreHelper<uint8_t>("Uint8");
- TypedArrayStoreHelper<int16_t>("Int16");
- TypedArrayStoreHelper<uint16_t>("Uint16");
- TypedArrayStoreHelper<int32_t>("Int32");
- TypedArrayStoreHelper<uint32_t>("Uint32");
- TypedArrayStoreHelper<float>("Float32");
- TypedArrayStoreHelper<double>("Float64");
- // TODO(mstarzinger): Add tests for ClampedUint8.
-}
-
-} // namespace compiler
-} // namespace internal
-} // namespace v8
diff --git a/test/cctest/compiler/test-run-stubs.cc b/test/cctest/compiler/test-run-stubs.cc
index 7a2a094..c745219 100644
--- a/test/cctest/compiler/test-run-stubs.cc
+++ b/test/cctest/compiler/test-run-stubs.cc
@@ -27,8 +27,13 @@
// Create code and an accompanying descriptor.
StringLengthStub stub(isolate);
Handle<Code> code = stub.GenerateCode();
- CompilationInfo info(&stub, isolate, zone);
- CallDescriptor* descriptor = Linkage::ComputeIncoming(zone, &info);
+ CompilationInfo info("test", isolate, zone,
+ Code::ComputeFlags(Code::HANDLER));
+ CallInterfaceDescriptor interface_descriptor =
+ stub.GetCallInterfaceDescriptor();
+ CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
+ isolate, zone, interface_descriptor, stub.GetStackParameterCount(),
+ CallDescriptor::kNoFlags, Operator::kNoProperties);
// Create a function to call the code using the descriptor.
Graph graph(zone);
diff --git a/test/cctest/compiler/value-helper.h b/test/cctest/compiler/value-helper.h
index cbde9a7..83cd33c 100644
--- a/test/cctest/compiler/value-helper.h
+++ b/test/cctest/compiler/value-helper.h
@@ -312,6 +312,23 @@
#define FOR_UINT32_SHIFTS(var) for (uint32_t var = 0; var < 32; var++)
+// TODO(bmeurer): Drop this crap once we switch to GTest/Gmock.
+static inline void CheckFloatEq(volatile float x, volatile float y) {
+ if (std::isnan(x)) {
+ CHECK(std::isnan(y));
+ } else {
+ CHECK_EQ(x, y);
+ }
+}
+
+static inline void CheckDoubleEq(volatile double x, volatile double y) {
+ if (std::isnan(x)) {
+ CHECK(std::isnan(y));
+ } else {
+ CHECK_EQ(x, y);
+ }
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8