blob: 255d836af535844fd1794505582fffd3d22cf0e8 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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/v8.h"
6
7#include "src/interpreter/bytecode-array-builder.h"
8#include "src/interpreter/bytecode-array-iterator.h"
9#include "src/interpreter/bytecode-register-allocator.h"
10#include "test/unittests/test-utils.h"
11
12namespace v8 {
13namespace internal {
14namespace interpreter {
15
16class BytecodeArrayBuilderTest : public TestWithIsolateAndZone {
17 public:
18 BytecodeArrayBuilderTest() {}
19 ~BytecodeArrayBuilderTest() override {}
20};
21
22
23TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010024 BytecodeArrayBuilder builder(isolate(), zone(), 0, 1, 131);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000025
Ben Murdoch097c5b22016-05-18 11:27:45 +010026 CHECK_EQ(builder.locals_count(), 131);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000027 CHECK_EQ(builder.context_count(), 1);
Ben Murdoch097c5b22016-05-18 11:27:45 +010028 CHECK_EQ(builder.fixed_register_count(), 132);
29
30 // Emit argument creation operations.
31 builder.CreateArguments(CreateArgumentsType::kMappedArguments)
32 .CreateArguments(CreateArgumentsType::kUnmappedArguments)
33 .CreateArguments(CreateArgumentsType::kRestParameter);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000034
35 // Emit constant loads.
36 builder.LoadLiteral(Smi::FromInt(0))
37 .LoadLiteral(Smi::FromInt(8))
38 .LoadLiteral(Smi::FromInt(10000000))
39 .LoadUndefined()
40 .LoadNull()
41 .LoadTheHole()
42 .LoadTrue()
43 .LoadFalse();
44
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000045 Register reg(0);
Ben Murdoch097c5b22016-05-18 11:27:45 +010046 Register other(reg.index() + 1);
47 Register wide(128);
48
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000049 builder.LoadAccumulatorWithRegister(reg)
50 .LoadNull()
51 .StoreAccumulatorInRegister(reg);
52
53 // Emit register-register transfer.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000054 builder.MoveRegister(reg, other);
Ben Murdoch097c5b22016-05-18 11:27:45 +010055 builder.MoveRegister(reg, wide);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000056
57 // Emit global load / store operations.
58 Factory* factory = isolate()->factory();
59 Handle<String> name = factory->NewStringFromStaticChars("var_name");
Ben Murdoch097c5b22016-05-18 11:27:45 +010060 builder.LoadGlobal(name, 1, TypeofMode::NOT_INSIDE_TYPEOF)
61 .LoadGlobal(name, 1, TypeofMode::INSIDE_TYPEOF)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000062 .StoreGlobal(name, 1, LanguageMode::SLOPPY)
63 .StoreGlobal(name, 1, LanguageMode::STRICT);
64
65 // Emit context operations.
66 builder.PushContext(reg)
67 .PopContext(reg)
68 .LoadContextSlot(reg, 1)
69 .StoreContextSlot(reg, 1);
70
71 // Emit load / store property operations.
Ben Murdoch097c5b22016-05-18 11:27:45 +010072 builder.LoadNamedProperty(reg, name, 0)
73 .LoadKeyedProperty(reg, 0)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000074 .StoreNamedProperty(reg, name, 0, LanguageMode::SLOPPY)
75 .StoreKeyedProperty(reg, reg, 0, LanguageMode::SLOPPY)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000076 .StoreNamedProperty(reg, name, 0, LanguageMode::STRICT)
77 .StoreKeyedProperty(reg, reg, 0, LanguageMode::STRICT);
78
79 // Emit load / store lookup slots.
80 builder.LoadLookupSlot(name, TypeofMode::NOT_INSIDE_TYPEOF)
81 .LoadLookupSlot(name, TypeofMode::INSIDE_TYPEOF)
82 .StoreLookupSlot(name, LanguageMode::SLOPPY)
83 .StoreLookupSlot(name, LanguageMode::STRICT);
84
85 // Emit closure operations.
86 Handle<SharedFunctionInfo> shared_info = factory->NewSharedFunctionInfo(
87 factory->NewStringFromStaticChars("function_a"), MaybeHandle<Code>(),
88 false);
89 builder.CreateClosure(shared_info, NOT_TENURED);
90
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000091 // Emit literal creation operations.
92 builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("a"), 0, 0)
93 .CreateArrayLiteral(factory->NewFixedArray(1), 0, 0)
94 .CreateObjectLiteral(factory->NewFixedArray(1), 0, 0);
95
96 // Call operations.
Ben Murdoch097c5b22016-05-18 11:27:45 +010097 builder.Call(reg, other, 1, 0)
98 .Call(reg, wide, 1, 0)
99 .TailCall(reg, other, 1, 0)
100 .TailCall(reg, wide, 1, 0)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000101 .CallRuntime(Runtime::kIsArray, reg, 1)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100102 .CallRuntime(Runtime::kIsArray, wide, 1)
103 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, reg, 1, other)
104 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, wide, 1, other)
105 .CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, reg, 1)
106 .CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, wide, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000107
108 // Emit binary operator invocations.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100109 builder.BinaryOperation(Token::Value::ADD, reg)
110 .BinaryOperation(Token::Value::SUB, reg)
111 .BinaryOperation(Token::Value::MUL, reg)
112 .BinaryOperation(Token::Value::DIV, reg)
113 .BinaryOperation(Token::Value::MOD, reg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000114
115 // Emit bitwise operator invocations
Ben Murdoch097c5b22016-05-18 11:27:45 +0100116 builder.BinaryOperation(Token::Value::BIT_OR, reg)
117 .BinaryOperation(Token::Value::BIT_XOR, reg)
118 .BinaryOperation(Token::Value::BIT_AND, reg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000119
120 // Emit shift operator invocations
Ben Murdoch097c5b22016-05-18 11:27:45 +0100121 builder.BinaryOperation(Token::Value::SHL, reg)
122 .BinaryOperation(Token::Value::SAR, reg)
123 .BinaryOperation(Token::Value::SHR, reg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000124
125 // Emit count operatior invocations
Ben Murdoch097c5b22016-05-18 11:27:45 +0100126 builder.CountOperation(Token::Value::ADD).CountOperation(Token::Value::SUB);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000127
128 // Emit unary operator invocations.
129 builder.LogicalNot().TypeOf();
130
131 // Emit delete
Ben Murdoch097c5b22016-05-18 11:27:45 +0100132 builder.Delete(reg, LanguageMode::SLOPPY).Delete(reg, LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000133
134 // Emit new.
135 builder.New(reg, reg, 0);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100136 builder.New(wide, wide, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000137
138 // Emit test operator invocations.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100139 builder.CompareOperation(Token::Value::EQ, reg)
140 .CompareOperation(Token::Value::NE, reg)
141 .CompareOperation(Token::Value::EQ_STRICT, reg)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100142 .CompareOperation(Token::Value::LT, reg)
143 .CompareOperation(Token::Value::GT, reg)
144 .CompareOperation(Token::Value::LTE, reg)
145 .CompareOperation(Token::Value::GTE, reg)
146 .CompareOperation(Token::Value::INSTANCEOF, reg)
147 .CompareOperation(Token::Value::IN, reg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000148
149 // Emit cast operator invocations.
150 builder.CastAccumulatorToNumber()
151 .CastAccumulatorToJSObject()
152 .CastAccumulatorToName();
153
154 // Emit control flow. Return must be the last instruction.
155 BytecodeLabel start;
156 builder.Bind(&start);
157 // Short jumps with Imm8 operands
158 builder.Jump(&start)
159 .JumpIfNull(&start)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100160 .JumpIfUndefined(&start)
161 .JumpIfNotHole(&start);
162
Ben Murdochda12d292016-06-02 14:46:10 +0100163 // Longer jumps with constant operands
164 BytecodeLabel end[8];
165 builder.Jump(&end[0])
166 .LoadTrue()
167 .JumpIfTrue(&end[1])
168 .LoadTrue()
169 .JumpIfFalse(&end[2])
170 .LoadLiteral(Smi::FromInt(0))
171 .JumpIfTrue(&end[3])
172 .LoadLiteral(Smi::FromInt(0))
173 .JumpIfFalse(&end[4])
174 .JumpIfNull(&end[5])
175 .JumpIfUndefined(&end[6])
176 .JumpIfNotHole(&end[7]);
177
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000178 // Perform an operation that returns boolean value to
179 // generate JumpIfTrue/False
Ben Murdoch097c5b22016-05-18 11:27:45 +0100180 builder.CompareOperation(Token::Value::EQ, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000181 .JumpIfTrue(&start)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100182 .CompareOperation(Token::Value::EQ, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000183 .JumpIfFalse(&start);
184 // Perform an operation that returns a non-boolean operation to
185 // generate JumpIfToBooleanTrue/False.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100186 builder.BinaryOperation(Token::Value::ADD, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000187 .JumpIfTrue(&start)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100188 .BinaryOperation(Token::Value::ADD, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000189 .JumpIfFalse(&start);
190 // Insert dummy ops to force longer jumps
191 for (int i = 0; i < 128; i++) {
192 builder.LoadTrue();
193 }
194 // Longer jumps requiring Constant operand
Ben Murdoch097c5b22016-05-18 11:27:45 +0100195 builder.Jump(&start).JumpIfNull(&start).JumpIfUndefined(&start).JumpIfNotHole(
196 &start);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000197 // Perform an operation that returns boolean value to
198 // generate JumpIfTrue/False
Ben Murdoch097c5b22016-05-18 11:27:45 +0100199 builder.CompareOperation(Token::Value::EQ, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000200 .JumpIfTrue(&start)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100201 .CompareOperation(Token::Value::EQ, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000202 .JumpIfFalse(&start);
203 // Perform an operation that returns a non-boolean operation to
204 // generate JumpIfToBooleanTrue/False.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100205 builder.BinaryOperation(Token::Value::ADD, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000206 .JumpIfTrue(&start)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100207 .BinaryOperation(Token::Value::ADD, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000208 .JumpIfFalse(&start);
209
Ben Murdoch097c5b22016-05-18 11:27:45 +0100210 // Emit stack check bytecode.
211 builder.StackCheck();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000212
Ben Murdoch097c5b22016-05-18 11:27:45 +0100213 // Emit throw and re-throw in it's own basic block so that the rest of the
214 // code isn't omitted due to being dead.
215 BytecodeLabel after_throw;
216 builder.Jump(&after_throw).Throw().Bind(&after_throw);
217 BytecodeLabel after_rethrow;
218 builder.Jump(&after_rethrow).ReThrow().Bind(&after_rethrow);
219
220 builder.ForInPrepare(reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000221 .ForInDone(reg, reg)
Ben Murdochda12d292016-06-02 14:46:10 +0100222 .ForInNext(reg, reg, reg, 1)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100223 .ForInStep(reg);
224 builder.ForInPrepare(wide)
225 .ForInDone(reg, other)
Ben Murdochda12d292016-06-02 14:46:10 +0100226 .ForInNext(wide, wide, wide, 1024)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000227 .ForInStep(reg);
228
229 // Wide constant pool loads
230 for (int i = 0; i < 256; i++) {
231 // Emit junk in constant pool to force wide constant pool index.
232 builder.LoadLiteral(factory->NewNumber(2.5321 + i));
233 }
234 builder.LoadLiteral(Smi::FromInt(20000000));
235 Handle<String> wide_name = factory->NewStringFromStaticChars("var_wide_name");
236
237 // Emit wide global load / store operations.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100238 builder.LoadGlobal(name, 1024, TypeofMode::NOT_INSIDE_TYPEOF)
239 .LoadGlobal(name, 1024, TypeofMode::INSIDE_TYPEOF)
Ben Murdochda12d292016-06-02 14:46:10 +0100240 .LoadGlobal(name, 1024, TypeofMode::INSIDE_TYPEOF)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000241 .StoreGlobal(name, 1024, LanguageMode::SLOPPY)
242 .StoreGlobal(wide_name, 1, LanguageMode::STRICT);
243
Ben Murdochda12d292016-06-02 14:46:10 +0100244 // Emit extra wide global load.
245 builder.LoadGlobal(name, 1024 * 1024, TypeofMode::NOT_INSIDE_TYPEOF);
246
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000247 // Emit wide load / store property operations.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100248 builder.LoadNamedProperty(reg, wide_name, 0)
249 .LoadKeyedProperty(reg, 2056)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000250 .StoreNamedProperty(reg, wide_name, 0, LanguageMode::SLOPPY)
251 .StoreKeyedProperty(reg, reg, 2056, LanguageMode::SLOPPY)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000252 .StoreNamedProperty(reg, wide_name, 0, LanguageMode::STRICT)
253 .StoreKeyedProperty(reg, reg, 2056, LanguageMode::STRICT);
254
255 // Emit wide context operations.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100256 builder.LoadContextSlot(reg, 1024).StoreContextSlot(reg, 1024);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000257
258 // Emit wide load / store lookup slots.
259 builder.LoadLookupSlot(wide_name, TypeofMode::NOT_INSIDE_TYPEOF)
260 .LoadLookupSlot(wide_name, TypeofMode::INSIDE_TYPEOF)
261 .StoreLookupSlot(wide_name, LanguageMode::SLOPPY)
262 .StoreLookupSlot(wide_name, LanguageMode::STRICT);
263
264 // CreateClosureWide
265 Handle<SharedFunctionInfo> shared_info2 = factory->NewSharedFunctionInfo(
266 factory->NewStringFromStaticChars("function_b"), MaybeHandle<Code>(),
267 false);
268 builder.CreateClosure(shared_info2, NOT_TENURED);
269
270 // Emit wide variant of literal creation operations.
271 builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("wide_literal"),
272 0, 0)
273 .CreateArrayLiteral(factory->NewFixedArray(2), 0, 0)
274 .CreateObjectLiteral(factory->NewFixedArray(2), 0, 0);
275
276 // Longer jumps requiring ConstantWide operand
Ben Murdoch097c5b22016-05-18 11:27:45 +0100277 builder.Jump(&start).JumpIfNull(&start).JumpIfUndefined(&start).JumpIfNotHole(
278 &start);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000279 // Perform an operation that returns boolean value to
280 // generate JumpIfTrue/False
Ben Murdoch097c5b22016-05-18 11:27:45 +0100281 builder.CompareOperation(Token::Value::EQ, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000282 .JumpIfTrue(&start)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100283 .CompareOperation(Token::Value::EQ, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000284 .JumpIfFalse(&start);
285 // Perform an operation that returns a non-boolean operation to
286 // generate JumpIfToBooleanTrue/False.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100287 builder.BinaryOperation(Token::Value::ADD, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000288 .JumpIfTrue(&start)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100289 .BinaryOperation(Token::Value::ADD, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000290 .JumpIfFalse(&start);
291
Ben Murdochda12d292016-06-02 14:46:10 +0100292 // Intrinsics handled by the interpreter.
293 builder.CallRuntime(Runtime::kInlineIsArray, reg, 1)
294 .CallRuntime(Runtime::kInlineIsArray, wide, 1);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100295
Ben Murdochda12d292016-06-02 14:46:10 +0100296 builder.Debugger();
297 for (size_t i = 0; i < arraysize(end); i++) {
298 builder.Bind(&end[i]);
299 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000300 builder.Return();
301
302 // Generate BytecodeArray.
303 Handle<BytecodeArray> the_array = builder.ToBytecodeArray();
304 CHECK_EQ(the_array->frame_size(),
Ben Murdochda12d292016-06-02 14:46:10 +0100305 builder.fixed_and_temporary_register_count() * kPointerSize);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000306
307 // Build scorecard of bytecodes encountered in the BytecodeArray.
308 std::vector<int> scorecard(Bytecodes::ToByte(Bytecode::kLast) + 1);
Ben Murdochda12d292016-06-02 14:46:10 +0100309
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000310 Bytecode final_bytecode = Bytecode::kLdaZero;
311 int i = 0;
312 while (i < the_array->length()) {
313 uint8_t code = the_array->get(i);
314 scorecard[code] += 1;
315 final_bytecode = Bytecodes::FromByte(code);
Ben Murdochda12d292016-06-02 14:46:10 +0100316 OperandScale operand_scale = OperandScale::kSingle;
317 int prefix_offset = 0;
318 if (Bytecodes::IsPrefixScalingBytecode(final_bytecode)) {
319 operand_scale = Bytecodes::PrefixBytecodeToOperandScale(final_bytecode);
320 prefix_offset = 1;
321 code = the_array->get(i + 1);
322 final_bytecode = Bytecodes::FromByte(code);
323 }
324 i += prefix_offset + Bytecodes::Size(final_bytecode, operand_scale);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000325 }
326
Ben Murdochda12d292016-06-02 14:46:10 +0100327 // Insert entry for illegal bytecode as this is never willingly emitted.
328 scorecard[Bytecodes::ToByte(Bytecode::kIllegal)] = 1;
329
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000330 // Check return occurs at the end and only once in the BytecodeArray.
331 CHECK_EQ(final_bytecode, Bytecode::kReturn);
332 CHECK_EQ(scorecard[Bytecodes::ToByte(final_bytecode)], 1);
333
Ben Murdoch097c5b22016-05-18 11:27:45 +0100334#define CHECK_BYTECODE_PRESENT(Name, ...) \
335 /* Check Bytecode is marked in scorecard, unless it's a debug break */ \
336 if (!Bytecodes::IsDebugBreak(Bytecode::k##Name)) { \
337 CHECK_GE(scorecard[Bytecodes::ToByte(Bytecode::k##Name)], 1); \
338 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000339 BYTECODE_LIST(CHECK_BYTECODE_PRESENT)
340#undef CHECK_BYTECODE_PRESENT
341}
342
343
344TEST_F(BytecodeArrayBuilderTest, FrameSizesLookGood) {
345 for (int locals = 0; locals < 5; locals++) {
346 for (int contexts = 0; contexts < 4; contexts++) {
347 for (int temps = 0; temps < 3; temps++) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100348 BytecodeArrayBuilder builder(isolate(), zone(), 0, contexts, locals);
349 BytecodeRegisterAllocator temporaries(
350 zone(), builder.temporary_register_allocator());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000351 for (int i = 0; i < temps; i++) {
352 builder.StoreAccumulatorInRegister(temporaries.NewRegister());
353 }
354 builder.Return();
355
356 Handle<BytecodeArray> the_array = builder.ToBytecodeArray();
357 int total_registers = locals + contexts + temps;
358 CHECK_EQ(the_array->frame_size(), total_registers * kPointerSize);
359 }
360 }
361 }
362}
363
364
365TEST_F(BytecodeArrayBuilderTest, RegisterValues) {
366 int index = 1;
Ben Murdochda12d292016-06-02 14:46:10 +0100367 int32_t operand = -index;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000368
369 Register the_register(index);
370 CHECK_EQ(the_register.index(), index);
371
372 int actual_operand = the_register.ToOperand();
373 CHECK_EQ(actual_operand, operand);
374
375 int actual_index = Register::FromOperand(actual_operand).index();
376 CHECK_EQ(actual_index, index);
377}
378
379
380TEST_F(BytecodeArrayBuilderTest, Parameters) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100381 BytecodeArrayBuilder builder(isolate(), zone(), 10, 0, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000382 Register param0(builder.Parameter(0));
383 Register param9(builder.Parameter(9));
384 CHECK_EQ(param9.index() - param0.index(), 9);
385}
386
387
388TEST_F(BytecodeArrayBuilderTest, RegisterType) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100389 BytecodeArrayBuilder builder(isolate(), zone(), 10, 0, 3);
390 BytecodeRegisterAllocator register_allocator(
391 zone(), builder.temporary_register_allocator());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000392 Register temp0 = register_allocator.NewRegister();
393 Register param0(builder.Parameter(0));
394 Register param9(builder.Parameter(9));
395 Register temp1 = register_allocator.NewRegister();
396 Register reg0(0);
397 Register reg1(1);
398 Register reg2(2);
399 Register temp2 = register_allocator.NewRegister();
400 CHECK_EQ(builder.RegisterIsParameterOrLocal(temp0), false);
401 CHECK_EQ(builder.RegisterIsParameterOrLocal(temp1), false);
402 CHECK_EQ(builder.RegisterIsParameterOrLocal(temp2), false);
403 CHECK_EQ(builder.RegisterIsParameterOrLocal(param0), true);
404 CHECK_EQ(builder.RegisterIsParameterOrLocal(param9), true);
405 CHECK_EQ(builder.RegisterIsParameterOrLocal(reg0), true);
406 CHECK_EQ(builder.RegisterIsParameterOrLocal(reg1), true);
407 CHECK_EQ(builder.RegisterIsParameterOrLocal(reg2), true);
408}
409
410
411TEST_F(BytecodeArrayBuilderTest, Constants) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100412 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000413 Factory* factory = isolate()->factory();
414 Handle<HeapObject> heap_num_1 = factory->NewHeapNumber(3.14);
415 Handle<HeapObject> heap_num_2 = factory->NewHeapNumber(5.2);
416 Handle<Object> large_smi(Smi::FromInt(0x12345678), isolate());
417 Handle<HeapObject> heap_num_2_copy(*heap_num_2);
418 builder.LoadLiteral(heap_num_1)
419 .LoadLiteral(heap_num_2)
420 .LoadLiteral(large_smi)
421 .LoadLiteral(heap_num_1)
422 .LoadLiteral(heap_num_1)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100423 .LoadLiteral(heap_num_2_copy)
424 .Return();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000425
426 Handle<BytecodeArray> array = builder.ToBytecodeArray();
427 // Should only have one entry for each identical constant.
428 CHECK_EQ(array->constant_pool()->length(), 3);
429}
430
431
432TEST_F(BytecodeArrayBuilderTest, ForwardJumps) {
433 static const int kFarJumpDistance = 256;
434
Ben Murdoch097c5b22016-05-18 11:27:45 +0100435 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000436 Register reg(0);
437 BytecodeLabel far0, far1, far2, far3, far4;
438 BytecodeLabel near0, near1, near2, near3, near4;
439
440 builder.Jump(&near0)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100441 .CompareOperation(Token::Value::EQ, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000442 .JumpIfTrue(&near1)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100443 .CompareOperation(Token::Value::EQ, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000444 .JumpIfFalse(&near2)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100445 .BinaryOperation(Token::Value::ADD, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000446 .JumpIfTrue(&near3)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100447 .BinaryOperation(Token::Value::ADD, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000448 .JumpIfFalse(&near4)
449 .Bind(&near0)
450 .Bind(&near1)
451 .Bind(&near2)
452 .Bind(&near3)
453 .Bind(&near4)
454 .Jump(&far0)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100455 .CompareOperation(Token::Value::EQ, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000456 .JumpIfTrue(&far1)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100457 .CompareOperation(Token::Value::EQ, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000458 .JumpIfFalse(&far2)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100459 .BinaryOperation(Token::Value::ADD, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000460 .JumpIfTrue(&far3)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100461 .BinaryOperation(Token::Value::ADD, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000462 .JumpIfFalse(&far4);
463 for (int i = 0; i < kFarJumpDistance - 18; i++) {
464 builder.LoadUndefined();
465 }
466 builder.Bind(&far0).Bind(&far1).Bind(&far2).Bind(&far3).Bind(&far4);
467 builder.Return();
468
469 Handle<BytecodeArray> array = builder.ToBytecodeArray();
470 DCHECK_EQ(array->length(), 36 + kFarJumpDistance - 18 + 1);
471
472 BytecodeArrayIterator iterator(array);
473 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
474 CHECK_EQ(iterator.GetImmediateOperand(0), 18);
475 iterator.Advance();
476
477 // Ignore compare operation.
478 iterator.Advance();
479
480 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue);
481 CHECK_EQ(iterator.GetImmediateOperand(0), 14);
482 iterator.Advance();
483
484 // Ignore compare operation.
485 iterator.Advance();
486
487 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse);
488 CHECK_EQ(iterator.GetImmediateOperand(0), 10);
489 iterator.Advance();
490
491 // Ignore add operation.
492 iterator.Advance();
493
494 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue);
495 CHECK_EQ(iterator.GetImmediateOperand(0), 6);
496 iterator.Advance();
497
498 // Ignore add operation.
499 iterator.Advance();
500
501 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse);
502 CHECK_EQ(iterator.GetImmediateOperand(0), 2);
503 iterator.Advance();
504
505
506 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant);
507 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
508 Smi::FromInt(kFarJumpDistance));
509 iterator.Advance();
510
511 // Ignore compare operation.
512 iterator.Advance();
513
514 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant);
515 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
516 Smi::FromInt(kFarJumpDistance - 4));
517 iterator.Advance();
518
519 // Ignore compare operation.
520 iterator.Advance();
521
522 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant);
523 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
524 Smi::FromInt(kFarJumpDistance - 8));
525 iterator.Advance();
526
527 // Ignore add operation.
528 iterator.Advance();
529
530 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant);
531 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
532 Smi::FromInt(kFarJumpDistance - 12));
533 iterator.Advance();
534
535 // Ignore add operation.
536 iterator.Advance();
537
538 CHECK_EQ(iterator.current_bytecode(),
539 Bytecode::kJumpIfToBooleanFalseConstant);
540 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
541 Smi::FromInt(kFarJumpDistance - 16));
542 iterator.Advance();
543}
544
545
546TEST_F(BytecodeArrayBuilderTest, BackwardJumps) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100547 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000548 Register reg(0);
549
550 BytecodeLabel label0, label1, label2, label3, label4;
551 builder.Bind(&label0)
552 .Jump(&label0)
553 .Bind(&label1)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100554 .CompareOperation(Token::Value::EQ, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000555 .JumpIfTrue(&label1)
556 .Bind(&label2)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100557 .CompareOperation(Token::Value::EQ, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000558 .JumpIfFalse(&label2)
559 .Bind(&label3)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100560 .BinaryOperation(Token::Value::ADD, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000561 .JumpIfTrue(&label3)
562 .Bind(&label4)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100563 .BinaryOperation(Token::Value::ADD, reg)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000564 .JumpIfFalse(&label4);
565 for (int i = 0; i < 63; i++) {
566 builder.Jump(&label4);
567 }
Ben Murdochda12d292016-06-02 14:46:10 +0100568
569 // Add padding to force wide backwards jumps.
570 for (int i = 0; i < 256; i++) {
571 builder.LoadTrue();
572 }
573
Ben Murdoch097c5b22016-05-18 11:27:45 +0100574 builder.BinaryOperation(Token::Value::ADD, reg).JumpIfFalse(&label4);
575 builder.BinaryOperation(Token::Value::ADD, reg).JumpIfTrue(&label3);
576 builder.CompareOperation(Token::Value::EQ, reg).JumpIfFalse(&label2);
577 builder.CompareOperation(Token::Value::EQ, reg).JumpIfTrue(&label1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000578 builder.Jump(&label0);
579 builder.Return();
580
581 Handle<BytecodeArray> array = builder.ToBytecodeArray();
582 BytecodeArrayIterator iterator(array);
583 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
584 CHECK_EQ(iterator.GetImmediateOperand(0), 0);
585 iterator.Advance();
586 // Ignore compare operation.
587 iterator.Advance();
588 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue);
Ben Murdochda12d292016-06-02 14:46:10 +0100589 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000590 CHECK_EQ(iterator.GetImmediateOperand(0), -2);
591 iterator.Advance();
592 // Ignore compare operation.
593 iterator.Advance();
594 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse);
Ben Murdochda12d292016-06-02 14:46:10 +0100595 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000596 CHECK_EQ(iterator.GetImmediateOperand(0), -2);
597 iterator.Advance();
598 // Ignore binary operation.
599 iterator.Advance();
600 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue);
Ben Murdochda12d292016-06-02 14:46:10 +0100601 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000602 CHECK_EQ(iterator.GetImmediateOperand(0), -2);
603 iterator.Advance();
604 // Ignore binary operation.
605 iterator.Advance();
606 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse);
Ben Murdochda12d292016-06-02 14:46:10 +0100607 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000608 CHECK_EQ(iterator.GetImmediateOperand(0), -2);
609 iterator.Advance();
610 for (int i = 0; i < 63; i++) {
611 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
Ben Murdochda12d292016-06-02 14:46:10 +0100612 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000613 CHECK_EQ(iterator.GetImmediateOperand(0), -i * 2 - 4);
614 iterator.Advance();
615 }
Ben Murdochda12d292016-06-02 14:46:10 +0100616 // Check padding to force wide backwards jumps.
617 for (int i = 0; i < 256; i++) {
618 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaTrue);
619 iterator.Advance();
620 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000621 // Ignore binary operation.
622 iterator.Advance();
Ben Murdochda12d292016-06-02 14:46:10 +0100623 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse);
624 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble);
625 CHECK_EQ(iterator.GetImmediateOperand(0), -389);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000626 iterator.Advance();
627 // Ignore binary operation.
628 iterator.Advance();
Ben Murdochda12d292016-06-02 14:46:10 +0100629 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue);
630 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble);
631 CHECK_EQ(iterator.GetImmediateOperand(0), -399);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000632 iterator.Advance();
633 // Ignore compare operation.
634 iterator.Advance();
Ben Murdochda12d292016-06-02 14:46:10 +0100635 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse);
636 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble);
637 CHECK_EQ(iterator.GetImmediateOperand(0), -409);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000638 iterator.Advance();
639 // Ignore compare operation.
640 iterator.Advance();
Ben Murdochda12d292016-06-02 14:46:10 +0100641 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue);
642 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble);
643 CHECK_EQ(iterator.GetImmediateOperand(0), -419);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000644 iterator.Advance();
Ben Murdochda12d292016-06-02 14:46:10 +0100645 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
646 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble);
647 CHECK_EQ(iterator.GetImmediateOperand(0), -425);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000648 iterator.Advance();
649 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
650 iterator.Advance();
651 CHECK(iterator.done());
652}
653
654
655TEST_F(BytecodeArrayBuilderTest, LabelReuse) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100656 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000657
658 // Labels can only have 1 forward reference, but
659 // can be referred to mulitple times once bound.
660 BytecodeLabel label;
661
662 builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label).Return();
663
664 Handle<BytecodeArray> array = builder.ToBytecodeArray();
665 BytecodeArrayIterator iterator(array);
666 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
667 CHECK_EQ(iterator.GetImmediateOperand(0), 2);
668 iterator.Advance();
669 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
670 CHECK_EQ(iterator.GetImmediateOperand(0), 0);
671 iterator.Advance();
672 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
673 CHECK_EQ(iterator.GetImmediateOperand(0), -2);
674 iterator.Advance();
675 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
676 iterator.Advance();
677 CHECK(iterator.done());
678}
679
680
681TEST_F(BytecodeArrayBuilderTest, LabelAddressReuse) {
682 static const int kRepeats = 3;
683
Ben Murdoch097c5b22016-05-18 11:27:45 +0100684 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000685 for (int i = 0; i < kRepeats; i++) {
686 BytecodeLabel label;
687 builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label);
688 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000689 builder.Return();
690
691 Handle<BytecodeArray> array = builder.ToBytecodeArray();
692 BytecodeArrayIterator iterator(array);
693 for (int i = 0; i < kRepeats; i++) {
694 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
695 CHECK_EQ(iterator.GetImmediateOperand(0), 2);
696 iterator.Advance();
697 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
698 CHECK_EQ(iterator.GetImmediateOperand(0), 0);
699 iterator.Advance();
700 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
701 CHECK_EQ(iterator.GetImmediateOperand(0), -2);
702 iterator.Advance();
703 }
704 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
705 iterator.Advance();
706 CHECK(iterator.done());
707}
708
Ben Murdochda12d292016-06-02 14:46:10 +0100709TEST_F(BytecodeArrayBuilderTest, OperandScales) {
710 CHECK_EQ(BytecodeArrayBuilder::OperandSizesToScale(OperandSize::kByte),
711 OperandScale::kSingle);
712 CHECK_EQ(BytecodeArrayBuilder::OperandSizesToScale(OperandSize::kShort),
713 OperandScale::kDouble);
714 CHECK_EQ(BytecodeArrayBuilder::OperandSizesToScale(OperandSize::kQuad),
715 OperandScale::kQuadruple);
716 CHECK_EQ(BytecodeArrayBuilder::OperandSizesToScale(
717 OperandSize::kShort, OperandSize::kShort, OperandSize::kShort,
718 OperandSize::kShort),
719 OperandScale::kDouble);
720 CHECK_EQ(BytecodeArrayBuilder::OperandSizesToScale(
721 OperandSize::kQuad, OperandSize::kShort, OperandSize::kShort,
722 OperandSize::kShort),
723 OperandScale::kQuadruple);
724 CHECK_EQ(BytecodeArrayBuilder::OperandSizesToScale(
725 OperandSize::kShort, OperandSize::kQuad, OperandSize::kShort,
726 OperandSize::kShort),
727 OperandScale::kQuadruple);
728 CHECK_EQ(BytecodeArrayBuilder::OperandSizesToScale(
729 OperandSize::kShort, OperandSize::kShort, OperandSize::kQuad,
730 OperandSize::kShort),
731 OperandScale::kQuadruple);
732 CHECK_EQ(BytecodeArrayBuilder::OperandSizesToScale(
733 OperandSize::kShort, OperandSize::kShort, OperandSize::kShort,
734 OperandSize::kQuad),
735 OperandScale::kQuadruple);
736}
737
738TEST_F(BytecodeArrayBuilderTest, SizesForSignOperands) {
739 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(0) == OperandSize::kByte);
740 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMaxInt8) ==
741 OperandSize::kByte);
742 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMinInt8) ==
743 OperandSize::kByte);
744 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMaxInt8 + 1) ==
745 OperandSize::kShort);
746 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMinInt8 - 1) ==
747 OperandSize::kShort);
748 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMaxInt16) ==
749 OperandSize::kShort);
750 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMinInt16) ==
751 OperandSize::kShort);
752 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMaxInt16 + 1) ==
753 OperandSize::kQuad);
754 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMinInt16 - 1) ==
755 OperandSize::kQuad);
756 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMaxInt) ==
757 OperandSize::kQuad);
758 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMinInt) ==
759 OperandSize::kQuad);
760}
761
762TEST_F(BytecodeArrayBuilderTest, SizesForUnsignOperands) {
763 // int overloads
764 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(0) == OperandSize::kByte);
765 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(kMaxUInt8) ==
766 OperandSize::kByte);
767 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(kMaxUInt8 + 1) ==
768 OperandSize::kShort);
769 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(kMaxUInt16) ==
770 OperandSize::kShort);
771 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(kMaxUInt16 + 1) ==
772 OperandSize::kQuad);
773 // size_t overloads
774 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(static_cast<size_t>(0)) ==
775 OperandSize::kByte);
776 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(
777 static_cast<size_t>(kMaxUInt8)) == OperandSize::kByte);
778 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(
779 static_cast<size_t>(kMaxUInt8 + 1)) == OperandSize::kShort);
780 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(
781 static_cast<size_t>(kMaxUInt16)) == OperandSize::kShort);
782 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(
783 static_cast<size_t>(kMaxUInt16 + 1)) == OperandSize::kQuad);
784 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(
785 static_cast<size_t>(kMaxUInt32)) == OperandSize::kQuad);
786}
787
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000788} // namespace interpreter
789} // namespace internal
790} // namespace v8