blob: e0db7714581e22b05ec466dbabd1a3c382a24e8b [file] [log] [blame]
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/compiler/js-operator.h"
6#include "src/compiler/opcodes.h"
7#include "src/compiler/operator.h"
8#include "src/compiler/operator-properties.h"
9#include "test/unittests/test-utils.h"
10
11namespace v8 {
12namespace internal {
13namespace compiler {
14
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000015namespace {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040016
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000017const LanguageMode kLanguageModes[] = {SLOPPY, STRICT, STRONG};
18
19
20#if GTEST_HAS_COMBINE
21
22template <typename T>
23class JSOperatorTestWithLanguageModeAndParam
24 : public TestWithZone,
25 public ::testing::WithParamInterface<::testing::tuple<LanguageMode, T>> {
26 protected:
27 LanguageMode language_mode() const {
28 return ::testing::get<0>(B::GetParam());
29 }
30 const T& GetParam() const { return ::testing::get<1>(B::GetParam()); }
31
32 private:
33 typedef ::testing::WithParamInterface<::testing::tuple<LanguageMode, T>> B;
34};
35
36#endif // GTEST_HAS_COMBINE
37
38} // namespace
39
40
41// -----------------------------------------------------------------------------
42// Shared operators without language mode.
Emily Bernierd0a1eb72015-03-24 16:35:39 -040043
44namespace {
45
46struct SharedOperator {
47 const Operator* (JSOperatorBuilder::*constructor)();
48 IrOpcode::Value opcode;
49 Operator::Properties properties;
50 int value_input_count;
51 int frame_state_input_count;
52 int effect_input_count;
53 int control_input_count;
54 int value_output_count;
55 int effect_output_count;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000056 int control_output_count;
57};
58
59
60const SharedOperator kSharedOperators[] = {
61#define SHARED(Name, properties, value_input_count, frame_state_input_count, \
62 effect_input_count, control_input_count, value_output_count, \
63 effect_output_count, control_output_count) \
64 { \
65 &JSOperatorBuilder::Name, IrOpcode::kJS##Name, properties, \
66 value_input_count, frame_state_input_count, effect_input_count, \
67 control_input_count, value_output_count, effect_output_count, \
68 control_output_count \
69 }
70 SHARED(Equal, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
71 SHARED(NotEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
72 SHARED(StrictEqual, Operator::kNoThrow, 2, 0, 1, 1, 1, 1, 0),
73 SHARED(StrictNotEqual, Operator::kNoThrow, 2, 0, 1, 1, 1, 1, 0),
74 SHARED(ToNumber, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2),
75 SHARED(ToString, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2),
76 SHARED(ToName, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2),
77 SHARED(ToObject, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2),
78 SHARED(Yield, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2),
79 SHARED(Create, Operator::kEliminatable, 2, 1, 1, 0, 1, 1, 0),
80 SHARED(HasProperty, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
81 SHARED(TypeOf, Operator::kEliminatable, 1, 0, 1, 0, 1, 1, 0),
82 SHARED(InstanceOf, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
83 SHARED(CreateWithContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1, 2),
84 SHARED(CreateModuleContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1, 2),
85#undef SHARED
Emily Bernierd0a1eb72015-03-24 16:35:39 -040086};
87
88
89std::ostream& operator<<(std::ostream& os, const SharedOperator& sop) {
90 return os << IrOpcode::Mnemonic(sop.opcode);
91}
92
Emily Bernierd0a1eb72015-03-24 16:35:39 -040093} // namespace
94
95
96class JSSharedOperatorTest
97 : public TestWithZone,
98 public ::testing::WithParamInterface<SharedOperator> {};
99
100
101TEST_P(JSSharedOperatorTest, InstancesAreGloballyShared) {
102 const SharedOperator& sop = GetParam();
103 JSOperatorBuilder javascript1(zone());
104 JSOperatorBuilder javascript2(zone());
105 EXPECT_EQ((javascript1.*sop.constructor)(), (javascript2.*sop.constructor)());
106}
107
108
109TEST_P(JSSharedOperatorTest, NumberOfInputsAndOutputs) {
110 JSOperatorBuilder javascript(zone());
111 const SharedOperator& sop = GetParam();
112 const Operator* op = (javascript.*sop.constructor)();
113
114 const int context_input_count = 1;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400115 EXPECT_EQ(sop.value_input_count, op->ValueInputCount());
116 EXPECT_EQ(context_input_count, OperatorProperties::GetContextInputCount(op));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000117 EXPECT_EQ(sop.frame_state_input_count,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400118 OperatorProperties::GetFrameStateInputCount(op));
119 EXPECT_EQ(sop.effect_input_count, op->EffectInputCount());
120 EXPECT_EQ(sop.control_input_count, op->ControlInputCount());
121 EXPECT_EQ(sop.value_input_count + context_input_count +
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000122 sop.frame_state_input_count + sop.effect_input_count +
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400123 sop.control_input_count,
124 OperatorProperties::GetTotalInputCount(op));
125
126 EXPECT_EQ(sop.value_output_count, op->ValueOutputCount());
127 EXPECT_EQ(sop.effect_output_count, op->EffectOutputCount());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000128 EXPECT_EQ(sop.control_output_count, op->ControlOutputCount());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400129}
130
131
132TEST_P(JSSharedOperatorTest, OpcodeIsCorrect) {
133 JSOperatorBuilder javascript(zone());
134 const SharedOperator& sop = GetParam();
135 const Operator* op = (javascript.*sop.constructor)();
136 EXPECT_EQ(sop.opcode, op->opcode());
137}
138
139
140TEST_P(JSSharedOperatorTest, Properties) {
141 JSOperatorBuilder javascript(zone());
142 const SharedOperator& sop = GetParam();
143 const Operator* op = (javascript.*sop.constructor)();
144 EXPECT_EQ(sop.properties, op->properties());
145}
146
147
148INSTANTIATE_TEST_CASE_P(JSOperatorTest, JSSharedOperatorTest,
149 ::testing::ValuesIn(kSharedOperators));
150
151
152// -----------------------------------------------------------------------------
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000153// Shared operators with language mode.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400154
155
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000156#if GTEST_HAS_COMBINE
157
158namespace {
159
160struct SharedOperatorWithLanguageMode {
161 const Operator* (JSOperatorBuilder::*constructor)(LanguageMode);
162 IrOpcode::Value opcode;
163 Operator::Properties properties;
164 int value_input_count;
165 int frame_state_input_count;
166 int effect_input_count;
167 int control_input_count;
168 int value_output_count;
169 int effect_output_count;
170 int control_output_count;
171};
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400172
173
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000174const SharedOperatorWithLanguageMode kSharedOperatorsWithLanguageMode[] = {
175#define SHARED(Name, properties, value_input_count, frame_state_input_count, \
176 effect_input_count, control_input_count, value_output_count, \
177 effect_output_count, control_output_count) \
178 { \
179 &JSOperatorBuilder::Name, IrOpcode::kJS##Name, properties, \
180 value_input_count, frame_state_input_count, effect_input_count, \
181 control_input_count, value_output_count, effect_output_count, \
182 control_output_count \
183 }
184 SHARED(LessThan, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
185 SHARED(GreaterThan, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
186 SHARED(LessThanOrEqual, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
187 SHARED(GreaterThanOrEqual, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
188#undef SHARED
189};
190
191
192std::ostream& operator<<(std::ostream& os,
193 const SharedOperatorWithLanguageMode& sop) {
194 return os << IrOpcode::Mnemonic(sop.opcode);
195}
196
197} // namespace
198
199
200class JSSharedOperatorWithLanguageModeTest
201 : public JSOperatorTestWithLanguageModeAndParam<
202 SharedOperatorWithLanguageMode> {};
203
204
205TEST_P(JSSharedOperatorWithLanguageModeTest, InstancesAreGloballyShared) {
206 const SharedOperatorWithLanguageMode& sop = GetParam();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400207 JSOperatorBuilder javascript1(zone());
208 JSOperatorBuilder javascript2(zone());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000209 EXPECT_EQ((javascript1.*sop.constructor)(language_mode()),
210 (javascript2.*sop.constructor)(language_mode()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400211}
212
213
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000214TEST_P(JSSharedOperatorWithLanguageModeTest, NumberOfInputsAndOutputs) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400215 JSOperatorBuilder javascript(zone());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000216 const SharedOperatorWithLanguageMode& sop = GetParam();
217 const Operator* op = (javascript.*sop.constructor)(language_mode());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400218
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000219 const int context_input_count = 1;
220 EXPECT_EQ(sop.value_input_count, op->ValueInputCount());
221 EXPECT_EQ(context_input_count, OperatorProperties::GetContextInputCount(op));
222 EXPECT_EQ(sop.frame_state_input_count,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400223 OperatorProperties::GetFrameStateInputCount(op));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000224 EXPECT_EQ(sop.effect_input_count, op->EffectInputCount());
225 EXPECT_EQ(sop.control_input_count, op->ControlInputCount());
226 EXPECT_EQ(sop.value_input_count + context_input_count +
227 sop.frame_state_input_count + sop.effect_input_count +
228 sop.control_input_count,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400229 OperatorProperties::GetTotalInputCount(op));
230
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000231 EXPECT_EQ(sop.value_output_count, op->ValueOutputCount());
232 EXPECT_EQ(sop.effect_output_count, op->EffectOutputCount());
233 EXPECT_EQ(sop.control_output_count, op->ControlOutputCount());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400234}
235
236
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000237TEST_P(JSSharedOperatorWithLanguageModeTest, OpcodeIsCorrect) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400238 JSOperatorBuilder javascript(zone());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000239 const SharedOperatorWithLanguageMode& sop = GetParam();
240 const Operator* op = (javascript.*sop.constructor)(language_mode());
241 EXPECT_EQ(sop.opcode, op->opcode());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400242}
243
244
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000245TEST_P(JSSharedOperatorWithLanguageModeTest, Parameter) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400246 JSOperatorBuilder javascript(zone());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000247 const SharedOperatorWithLanguageMode& sop = GetParam();
248 const Operator* op = (javascript.*sop.constructor)(language_mode());
249 EXPECT_EQ(language_mode(), OpParameter<LanguageMode>(op));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400250}
251
252
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000253TEST_P(JSSharedOperatorWithLanguageModeTest, Properties) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400254 JSOperatorBuilder javascript(zone());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000255 const SharedOperatorWithLanguageMode& sop = GetParam();
256 const Operator* op = (javascript.*sop.constructor)(language_mode());
257 EXPECT_EQ(sop.properties, op->properties());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400258}
259
260
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000261INSTANTIATE_TEST_CASE_P(
262 JSOperatorTest, JSSharedOperatorWithLanguageModeTest,
263 ::testing::Combine(::testing::ValuesIn(kLanguageModes),
264 ::testing::ValuesIn(kSharedOperatorsWithLanguageMode)));
265
266#endif // GTEST_HAS_COMBINE
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400267
268} // namespace compiler
269} // namespace internal
270} // namespace v8