blob: 75bf631d300a9349e7369806592914800ebc3101 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2015 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/interpreter/bytecode-array-builder.h"
Ben Murdochc5610432016-08-08 18:44:38 +01006
Ben Murdoch097c5b22016-05-18 11:27:45 +01007#include "src/compiler.h"
Ben Murdochc5610432016-08-08 18:44:38 +01008#include "src/interpreter/bytecode-array-writer.h"
9#include "src/interpreter/bytecode-peephole-optimizer.h"
Ben Murdochda12d292016-06-02 14:46:10 +010010#include "src/interpreter/interpreter-intrinsics.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000011
12namespace v8 {
13namespace internal {
14namespace interpreter {
15
Ben Murdoch097c5b22016-05-18 11:27:45 +010016BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone,
17 int parameter_count,
Ben Murdochda12d292016-06-02 14:46:10 +010018 int context_count, int locals_count,
19 FunctionLiteral* literal)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000020 : isolate_(isolate),
21 zone_(zone),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000022 bytecode_generated_(false),
23 constant_array_builder_(isolate, zone),
Ben Murdoch097c5b22016-05-18 11:27:45 +010024 handler_table_builder_(isolate, zone),
25 source_position_table_builder_(isolate, zone),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000026 exit_seen_in_block_(false),
27 unbound_jumps_(0),
Ben Murdoch097c5b22016-05-18 11:27:45 +010028 parameter_count_(parameter_count),
29 local_register_count_(locals_count),
30 context_register_count_(context_count),
Ben Murdochc5610432016-08-08 18:44:38 +010031 temporary_allocator_(zone, fixed_register_count()),
32 bytecode_array_writer_(zone, &source_position_table_builder_),
33 pipeline_(&bytecode_array_writer_) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010034 DCHECK_GE(parameter_count_, 0);
35 DCHECK_GE(context_register_count_, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000036 DCHECK_GE(local_register_count_, 0);
Ben Murdochc5610432016-08-08 18:44:38 +010037
38 if (FLAG_ignition_peephole) {
39 pipeline_ = new (zone)
40 BytecodePeepholeOptimizer(&constant_array_builder_, pipeline_);
41 }
42
Ben Murdochda12d292016-06-02 14:46:10 +010043 return_position_ =
44 literal ? std::max(literal->start_position(), literal->end_position() - 1)
45 : RelocInfo::kNoPosition;
46 LOG_CODE_EVENT(isolate_, CodeStartLinePosInfoRecordEvent(
47 source_position_table_builder()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000048}
49
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000050Register BytecodeArrayBuilder::first_context_register() const {
51 DCHECK_GT(context_register_count_, 0);
52 return Register(local_register_count_);
53}
54
55
56Register BytecodeArrayBuilder::last_context_register() const {
57 DCHECK_GT(context_register_count_, 0);
58 return Register(local_register_count_ + context_register_count_ - 1);
59}
60
61
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000062Register BytecodeArrayBuilder::Parameter(int parameter_index) const {
63 DCHECK_GE(parameter_index, 0);
64 return Register::FromParameterIndex(parameter_index, parameter_count());
65}
66
67
68bool BytecodeArrayBuilder::RegisterIsParameterOrLocal(Register reg) const {
69 return reg.is_parameter() || reg.index() < locals_count();
70}
71
72
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000073Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() {
Ben Murdochc5610432016-08-08 18:44:38 +010074 DCHECK_EQ(0, unbound_jumps_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000075 DCHECK_EQ(bytecode_generated_, false);
Ben Murdoch097c5b22016-05-18 11:27:45 +010076 DCHECK(exit_seen_in_block_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000077
Ben Murdochc5610432016-08-08 18:44:38 +010078 pipeline()->FlushBasicBlock();
79 const ZoneVector<uint8_t>* bytecodes = bytecode_array_writer()->bytecodes();
80
81 int bytecode_size = static_cast<int>(bytecodes->size());
82
83 // All locals need a frame slot for the debugger, but may not be
84 // present in generated code.
85 int frame_size_for_locals = fixed_register_count() * kPointerSize;
86 int frame_size_used = bytecode_array_writer()->GetMaximumFrameSizeUsed();
87 int frame_size = std::max(frame_size_for_locals, frame_size_used);
Ben Murdoch097c5b22016-05-18 11:27:45 +010088 Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray();
89 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable();
Ben Murdochda12d292016-06-02 14:46:10 +010090 Handle<ByteArray> source_position_table =
91 source_position_table_builder()->ToSourcePositionTable();
92 Handle<BytecodeArray> bytecode_array = isolate_->factory()->NewBytecodeArray(
Ben Murdochc5610432016-08-08 18:44:38 +010093 bytecode_size, &bytecodes->front(), frame_size, parameter_count(),
Ben Murdoch097c5b22016-05-18 11:27:45 +010094 constant_pool);
Ben Murdochda12d292016-06-02 14:46:10 +010095 bytecode_array->set_handler_table(*handler_table);
96 bytecode_array->set_source_position_table(*source_position_table);
97
98 void* line_info = source_position_table_builder()->DetachJITHandlerData();
99 LOG_CODE_EVENT(isolate_, CodeEndLinePosInfoRecordEvent(
100 AbstractCode::cast(*bytecode_array), line_info));
101
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000102 bytecode_generated_ = true;
Ben Murdochda12d292016-06-02 14:46:10 +0100103 return bytecode_array;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000104}
105
Ben Murdochc5610432016-08-08 18:44:38 +0100106void BytecodeArrayBuilder::AttachSourceInfo(BytecodeNode* node) {
107 if (latest_source_info_.is_valid()) {
108 node->source_info().Update(latest_source_info_);
109 latest_source_info_.set_invalid();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000110 }
111}
112
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000113void BytecodeArrayBuilder::Output(Bytecode bytecode) {
114 // Don't output dead code.
Ben Murdochda12d292016-06-02 14:46:10 +0100115 if (exit_seen_in_block_) return;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000116
Ben Murdochc5610432016-08-08 18:44:38 +0100117 BytecodeNode node(bytecode);
118 AttachSourceInfo(&node);
119 pipeline()->Write(&node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000120}
121
Ben Murdochda12d292016-06-02 14:46:10 +0100122void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode,
123 OperandScale operand_scale,
124 uint32_t operand0, uint32_t operand1,
125 uint32_t operand2, uint32_t operand3) {
Ben Murdochc5610432016-08-08 18:44:38 +0100126 // Don't output dead code.
127 if (exit_seen_in_block_) return;
128 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0));
129 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1));
130 DCHECK(OperandIsValid(bytecode, operand_scale, 2, operand2));
131 DCHECK(OperandIsValid(bytecode, operand_scale, 3, operand3));
132 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3,
133 operand_scale);
134 AttachSourceInfo(&node);
135 pipeline()->Write(&node);
Ben Murdochda12d292016-06-02 14:46:10 +0100136}
137
138void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode,
139 OperandScale operand_scale,
140 uint32_t operand0, uint32_t operand1,
141 uint32_t operand2) {
Ben Murdochc5610432016-08-08 18:44:38 +0100142 // Don't output dead code.
143 if (exit_seen_in_block_) return;
144 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0));
145 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1));
146 DCHECK(OperandIsValid(bytecode, operand_scale, 2, operand2));
147 BytecodeNode node(bytecode, operand0, operand1, operand2, operand_scale);
148 AttachSourceInfo(&node);
149 pipeline()->Write(&node);
Ben Murdochda12d292016-06-02 14:46:10 +0100150}
151
152void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode,
153 OperandScale operand_scale,
154 uint32_t operand0, uint32_t operand1) {
Ben Murdochc5610432016-08-08 18:44:38 +0100155 // Don't output dead code.
156 if (exit_seen_in_block_) return;
157 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0));
158 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1));
159 BytecodeNode node(bytecode, operand0, operand1, operand_scale);
160 AttachSourceInfo(&node);
161 pipeline()->Write(&node);
Ben Murdochda12d292016-06-02 14:46:10 +0100162}
163
164void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode,
165 OperandScale operand_scale,
166 uint32_t operand0) {
Ben Murdochc5610432016-08-08 18:44:38 +0100167 // Don't output dead code.
168 if (exit_seen_in_block_) return;
169 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0));
170 BytecodeNode node(bytecode, operand0, operand_scale);
171 AttachSourceInfo(&node);
172 pipeline()->Write(&node);
Ben Murdochda12d292016-06-02 14:46:10 +0100173}
174
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000175BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100176 Register reg) {
Ben Murdochc5610432016-08-08 18:44:38 +0100177 OperandScale operand_scale =
178 Bytecodes::OperandSizesToScale(reg.SizeOfOperand());
Ben Murdochda12d292016-06-02 14:46:10 +0100179 OutputScaled(BytecodeForBinaryOperation(op), operand_scale,
180 RegisterOperand(reg));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000181 return *this;
182}
183
Ben Murdoch097c5b22016-05-18 11:27:45 +0100184BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000185 Output(BytecodeForCountOperation(op));
186 return *this;
187}
188
189
190BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() {
Ben Murdochc5610432016-08-08 18:44:38 +0100191 Output(Bytecode::kToBooleanLogicalNot);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000192 return *this;
193}
194
195
196BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() {
197 Output(Bytecode::kTypeOf);
198 return *this;
199}
200
Ben Murdoch097c5b22016-05-18 11:27:45 +0100201BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(Token::Value op,
202 Register reg) {
Ben Murdochc5610432016-08-08 18:44:38 +0100203 OperandScale operand_scale =
204 Bytecodes::OperandSizesToScale(reg.SizeOfOperand());
Ben Murdochda12d292016-06-02 14:46:10 +0100205 OutputScaled(BytecodeForCompareOperation(op), operand_scale,
206 RegisterOperand(reg));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000207 return *this;
208}
209
210
211BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(
212 v8::internal::Smi* smi) {
213 int32_t raw_smi = smi->value();
214 if (raw_smi == 0) {
215 Output(Bytecode::kLdaZero);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000216 } else {
Ben Murdochc5610432016-08-08 18:44:38 +0100217 OperandSize operand_size = Bytecodes::SizeForSignedOperand(raw_smi);
218 OperandScale operand_scale = Bytecodes::OperandSizesToScale(operand_size);
Ben Murdochda12d292016-06-02 14:46:10 +0100219 OutputScaled(Bytecode::kLdaSmi, operand_scale,
220 SignedOperand(raw_smi, operand_size));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000221 }
222 return *this;
223}
224
225
226BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) {
227 size_t entry = GetConstantPoolEntry(object);
Ben Murdochda12d292016-06-02 14:46:10 +0100228 OperandScale operand_scale =
Ben Murdochc5610432016-08-08 18:44:38 +0100229 Bytecodes::OperandSizesToScale(Bytecodes::SizeForUnsignedOperand(entry));
Ben Murdochda12d292016-06-02 14:46:10 +0100230 OutputScaled(Bytecode::kLdaConstant, operand_scale, UnsignedOperand(entry));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000231 return *this;
232}
233
234
235BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() {
236 Output(Bytecode::kLdaUndefined);
237 return *this;
238}
239
240
241BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNull() {
242 Output(Bytecode::kLdaNull);
243 return *this;
244}
245
246
247BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTheHole() {
248 Output(Bytecode::kLdaTheHole);
249 return *this;
250}
251
252
253BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTrue() {
254 Output(Bytecode::kLdaTrue);
255 return *this;
256}
257
258
259BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() {
260 Output(Bytecode::kLdaFalse);
261 return *this;
262}
263
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000264BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
265 Register reg) {
Ben Murdochc5610432016-08-08 18:44:38 +0100266 OperandScale operand_scale =
267 Bytecodes::OperandSizesToScale(reg.SizeOfOperand());
268 OutputScaled(Bytecode::kLdar, operand_scale, RegisterOperand(reg));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000269 return *this;
270}
271
272
273BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
274 Register reg) {
Ben Murdochc5610432016-08-08 18:44:38 +0100275 OperandScale operand_scale =
276 Bytecodes::OperandSizesToScale(reg.SizeOfOperand());
277 OutputScaled(Bytecode::kStar, operand_scale, RegisterOperand(reg));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000278 return *this;
279}
280
281
282BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from,
283 Register to) {
284 DCHECK(from != to);
Ben Murdochc5610432016-08-08 18:44:38 +0100285 OperandScale operand_scale =
286 Bytecodes::OperandSizesToScale(from.SizeOfOperand(), to.SizeOfOperand());
Ben Murdochda12d292016-06-02 14:46:10 +0100287 OutputScaled(Bytecode::kMov, operand_scale, RegisterOperand(from),
288 RegisterOperand(to));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000289 return *this;
290}
291
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000292BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100293 const Handle<String> name, int feedback_slot, TypeofMode typeof_mode) {
294 // TODO(rmcilroy): Potentially store typeof information in an
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000295 // operand rather than having extra bytecodes.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100296 Bytecode bytecode = BytecodeForLoadGlobal(typeof_mode);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000297 size_t name_index = GetConstantPoolEntry(name);
Ben Murdochc5610432016-08-08 18:44:38 +0100298 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
299 Bytecodes::SizeForUnsignedOperand(name_index),
300 Bytecodes::SizeForUnsignedOperand(feedback_slot));
Ben Murdochda12d292016-06-02 14:46:10 +0100301 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index),
302 UnsignedOperand(feedback_slot));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000303 return *this;
304}
305
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000306BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal(
307 const Handle<String> name, int feedback_slot, LanguageMode language_mode) {
308 Bytecode bytecode = BytecodeForStoreGlobal(language_mode);
309 size_t name_index = GetConstantPoolEntry(name);
Ben Murdochc5610432016-08-08 18:44:38 +0100310 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
311 Bytecodes::SizeForUnsignedOperand(name_index),
312 Bytecodes::SizeForUnsignedOperand(feedback_slot));
Ben Murdochda12d292016-06-02 14:46:10 +0100313 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index),
314 UnsignedOperand(feedback_slot));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000315 return *this;
316}
317
318
319BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context,
320 int slot_index) {
Ben Murdochc5610432016-08-08 18:44:38 +0100321 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
322 context.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(slot_index));
Ben Murdochda12d292016-06-02 14:46:10 +0100323 OutputScaled(Bytecode::kLdaContextSlot, operand_scale,
324 RegisterOperand(context), UnsignedOperand(slot_index));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000325 return *this;
326}
327
328
329BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context,
330 int slot_index) {
Ben Murdochc5610432016-08-08 18:44:38 +0100331 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
332 context.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(slot_index));
Ben Murdochda12d292016-06-02 14:46:10 +0100333 OutputScaled(Bytecode::kStaContextSlot, operand_scale,
334 RegisterOperand(context), UnsignedOperand(slot_index));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000335 return *this;
336}
337
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000338BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot(
339 const Handle<String> name, TypeofMode typeof_mode) {
340 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF)
341 ? Bytecode::kLdaLookupSlotInsideTypeof
342 : Bytecode::kLdaLookupSlot;
343 size_t name_index = GetConstantPoolEntry(name);
Ben Murdochc5610432016-08-08 18:44:38 +0100344 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
345 Bytecodes::SizeForUnsignedOperand(name_index));
Ben Murdochda12d292016-06-02 14:46:10 +0100346 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000347 return *this;
348}
349
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000350BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot(
351 const Handle<String> name, LanguageMode language_mode) {
352 Bytecode bytecode = BytecodeForStoreLookupSlot(language_mode);
353 size_t name_index = GetConstantPoolEntry(name);
Ben Murdochc5610432016-08-08 18:44:38 +0100354 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
355 Bytecodes::SizeForUnsignedOperand(name_index));
Ben Murdochda12d292016-06-02 14:46:10 +0100356 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000357 return *this;
358}
359
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000360BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100361 Register object, const Handle<Name> name, int feedback_slot) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000362 size_t name_index = GetConstantPoolEntry(name);
Ben Murdochc5610432016-08-08 18:44:38 +0100363 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
364 object.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(name_index),
365 Bytecodes::SizeForUnsignedOperand(feedback_slot));
Ben Murdochda12d292016-06-02 14:46:10 +0100366 OutputScaled(Bytecode::kLoadIC, operand_scale, RegisterOperand(object),
367 UnsignedOperand(name_index), UnsignedOperand(feedback_slot));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000368 return *this;
369}
370
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000371BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100372 Register object, int feedback_slot) {
Ben Murdochc5610432016-08-08 18:44:38 +0100373 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
374 object.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(feedback_slot));
Ben Murdochda12d292016-06-02 14:46:10 +0100375 OutputScaled(Bytecode::kKeyedLoadIC, operand_scale, RegisterOperand(object),
376 UnsignedOperand(feedback_slot));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000377 return *this;
378}
379
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000380BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100381 Register object, const Handle<Name> name, int feedback_slot,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000382 LanguageMode language_mode) {
383 Bytecode bytecode = BytecodeForStoreIC(language_mode);
384 size_t name_index = GetConstantPoolEntry(name);
Ben Murdochc5610432016-08-08 18:44:38 +0100385 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
386 object.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(name_index),
387 Bytecodes::SizeForUnsignedOperand(feedback_slot));
Ben Murdochda12d292016-06-02 14:46:10 +0100388 OutputScaled(bytecode, operand_scale, RegisterOperand(object),
389 UnsignedOperand(name_index), UnsignedOperand(feedback_slot));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000390 return *this;
391}
392
393
394BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
395 Register object, Register key, int feedback_slot,
396 LanguageMode language_mode) {
397 Bytecode bytecode = BytecodeForKeyedStoreIC(language_mode);
Ben Murdochc5610432016-08-08 18:44:38 +0100398 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
399 object.SizeOfOperand(), key.SizeOfOperand(),
400 Bytecodes::SizeForUnsignedOperand(feedback_slot));
Ben Murdochda12d292016-06-02 14:46:10 +0100401 OutputScaled(bytecode, operand_scale, RegisterOperand(object),
402 RegisterOperand(key), UnsignedOperand(feedback_slot));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000403 return *this;
404}
405
406
407BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(
408 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) {
409 size_t entry = GetConstantPoolEntry(shared_info);
Ben Murdochda12d292016-06-02 14:46:10 +0100410 OperandScale operand_scale =
Ben Murdochc5610432016-08-08 18:44:38 +0100411 Bytecodes::OperandSizesToScale(Bytecodes::SizeForUnsignedOperand(entry));
Ben Murdochda12d292016-06-02 14:46:10 +0100412 OutputScaled(Bytecode::kCreateClosure, operand_scale, UnsignedOperand(entry),
413 UnsignedOperand(static_cast<size_t>(tenured)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000414 return *this;
415}
416
417
418BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments(
419 CreateArgumentsType type) {
420 // TODO(rmcilroy): Consider passing the type as a bytecode operand rather
421 // than having two different bytecodes once we have better support for
422 // branches in the InterpreterAssembler.
423 Bytecode bytecode = BytecodeForCreateArguments(type);
424 Output(bytecode);
425 return *this;
426}
427
428
429BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral(
430 Handle<String> pattern, int literal_index, int flags) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000431 size_t pattern_entry = GetConstantPoolEntry(pattern);
Ben Murdochc5610432016-08-08 18:44:38 +0100432 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
433 Bytecodes::SizeForUnsignedOperand(pattern_entry),
434 Bytecodes::SizeForUnsignedOperand(literal_index),
435 Bytecodes::SizeForUnsignedOperand(flags));
Ben Murdochda12d292016-06-02 14:46:10 +0100436 OutputScaled(Bytecode::kCreateRegExpLiteral, operand_scale,
437 UnsignedOperand(pattern_entry), UnsignedOperand(literal_index),
438 UnsignedOperand(flags));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000439 return *this;
440}
441
442
443BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral(
444 Handle<FixedArray> constant_elements, int literal_index, int flags) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000445 size_t constant_elements_entry = GetConstantPoolEntry(constant_elements);
Ben Murdochc5610432016-08-08 18:44:38 +0100446 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
447 Bytecodes::SizeForUnsignedOperand(constant_elements_entry),
448 Bytecodes::SizeForUnsignedOperand(literal_index),
449 Bytecodes::SizeForUnsignedOperand(flags));
Ben Murdochda12d292016-06-02 14:46:10 +0100450 OutputScaled(Bytecode::kCreateArrayLiteral, operand_scale,
451 UnsignedOperand(constant_elements_entry),
452 UnsignedOperand(literal_index), UnsignedOperand(flags));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000453 return *this;
454}
455
456
457BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral(
458 Handle<FixedArray> constant_properties, int literal_index, int flags) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000459 size_t constant_properties_entry = GetConstantPoolEntry(constant_properties);
Ben Murdochc5610432016-08-08 18:44:38 +0100460 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
461 Bytecodes::SizeForUnsignedOperand(constant_properties_entry),
462 Bytecodes::SizeForUnsignedOperand(literal_index),
463 Bytecodes::SizeForUnsignedOperand(flags));
Ben Murdochda12d292016-06-02 14:46:10 +0100464 OutputScaled(Bytecode::kCreateObjectLiteral, operand_scale,
465 UnsignedOperand(constant_properties_entry),
466 UnsignedOperand(literal_index), UnsignedOperand(flags));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000467 return *this;
468}
469
470
471BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) {
Ben Murdochda12d292016-06-02 14:46:10 +0100472 OperandScale operand_scale =
Ben Murdochc5610432016-08-08 18:44:38 +0100473 Bytecodes::OperandSizesToScale(context.SizeOfOperand());
Ben Murdochda12d292016-06-02 14:46:10 +0100474 OutputScaled(Bytecode::kPushContext, operand_scale, RegisterOperand(context));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000475 return *this;
476}
477
478
479BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
Ben Murdochda12d292016-06-02 14:46:10 +0100480 OperandScale operand_scale =
Ben Murdochc5610432016-08-08 18:44:38 +0100481 Bytecodes::OperandSizesToScale(context.SizeOfOperand());
Ben Murdochda12d292016-06-02 14:46:10 +0100482 OutputScaled(Bytecode::kPopContext, operand_scale, RegisterOperand(context));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000483 return *this;
484}
485
486
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000487BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() {
488 Output(Bytecode::kToObject);
489 return *this;
490}
491
492
493BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000494 Output(Bytecode::kToName);
495 return *this;
496}
497
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000498BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000499 Output(Bytecode::kToNumber);
500 return *this;
501}
502
503
504BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) {
Ben Murdochc5610432016-08-08 18:44:38 +0100505 size_t current_offset = pipeline()->FlushForOffset();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000506 if (label->is_forward_target()) {
507 // An earlier jump instruction refers to this label. Update it's location.
Ben Murdochc5610432016-08-08 18:44:38 +0100508 PatchJump(current_offset, label->offset());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000509 // Now treat as if the label will only be back referred to.
510 }
Ben Murdochc5610432016-08-08 18:44:38 +0100511 label->bind_to(current_offset);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000512 LeaveBasicBlock();
513 return *this;
514}
515
516
517BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target,
518 BytecodeLabel* label) {
519 DCHECK(!label->is_bound());
520 DCHECK(target.is_bound());
Ben Murdochc5610432016-08-08 18:44:38 +0100521 // There is no need to flush the pipeline here, it will have been
522 // flushed when |target| was bound.
Ben Murdochda12d292016-06-02 14:46:10 +0100523 if (label->is_forward_target()) {
524 // An earlier jump instruction refers to this label. Update it's location.
Ben Murdochc5610432016-08-08 18:44:38 +0100525 PatchJump(target.offset(), label->offset());
Ben Murdochda12d292016-06-02 14:46:10 +0100526 // Now treat as if the label will only be back referred to.
527 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000528 label->bind_to(target.offset());
529 LeaveBasicBlock();
530 return *this;
531}
532
533
534// static
535Bytecode BytecodeArrayBuilder::GetJumpWithConstantOperand(
536 Bytecode jump_bytecode) {
537 switch (jump_bytecode) {
538 case Bytecode::kJump:
539 return Bytecode::kJumpConstant;
540 case Bytecode::kJumpIfTrue:
541 return Bytecode::kJumpIfTrueConstant;
542 case Bytecode::kJumpIfFalse:
543 return Bytecode::kJumpIfFalseConstant;
544 case Bytecode::kJumpIfToBooleanTrue:
545 return Bytecode::kJumpIfToBooleanTrueConstant;
546 case Bytecode::kJumpIfToBooleanFalse:
547 return Bytecode::kJumpIfToBooleanFalseConstant;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100548 case Bytecode::kJumpIfNotHole:
549 return Bytecode::kJumpIfNotHoleConstant;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000550 case Bytecode::kJumpIfNull:
551 return Bytecode::kJumpIfNullConstant;
552 case Bytecode::kJumpIfUndefined:
553 return Bytecode::kJumpIfUndefinedConstant;
554 default:
555 UNREACHABLE();
Ben Murdochda12d292016-06-02 14:46:10 +0100556 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000557 }
558}
559
Ben Murdochc5610432016-08-08 18:44:38 +0100560void BytecodeArrayBuilder::PatchJumpWith8BitOperand(
561 ZoneVector<uint8_t>* bytecodes, size_t jump_location, int delta) {
562 Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes->at(jump_location));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000563 DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode));
Ben Murdochc5610432016-08-08 18:44:38 +0100564 size_t operand_location = jump_location + 1;
565 DCHECK_EQ(bytecodes->at(operand_location), 0);
566 if (Bytecodes::SizeForSignedOperand(delta) == OperandSize::kByte) {
Ben Murdochda12d292016-06-02 14:46:10 +0100567 // The jump fits within the range of an Imm operand, so cancel
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000568 // the reservation and jump directly.
569 constant_array_builder()->DiscardReservedEntry(OperandSize::kByte);
Ben Murdochc5610432016-08-08 18:44:38 +0100570 bytecodes->at(operand_location) = static_cast<uint8_t>(delta);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000571 } else {
Ben Murdochda12d292016-06-02 14:46:10 +0100572 // The jump does not fit within the range of an Imm operand, so
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000573 // commit reservation putting the offset into the constant pool,
574 // and update the jump instruction and operand.
575 size_t entry = constant_array_builder()->CommitReservedEntry(
576 OperandSize::kByte, handle(Smi::FromInt(delta), isolate()));
Ben Murdochc5610432016-08-08 18:44:38 +0100577 DCHECK(Bytecodes::SizeForUnsignedOperand(entry) == OperandSize::kByte);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000578 jump_bytecode = GetJumpWithConstantOperand(jump_bytecode);
Ben Murdochc5610432016-08-08 18:44:38 +0100579 bytecodes->at(jump_location) = Bytecodes::ToByte(jump_bytecode);
580 bytecodes->at(operand_location) = static_cast<uint8_t>(entry);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000581 }
582}
583
Ben Murdochc5610432016-08-08 18:44:38 +0100584void BytecodeArrayBuilder::PatchJumpWith16BitOperand(
585 ZoneVector<uint8_t>* bytecodes, size_t jump_location, int delta) {
586 Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes->at(jump_location));
Ben Murdochda12d292016-06-02 14:46:10 +0100587 DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode));
Ben Murdochc5610432016-08-08 18:44:38 +0100588 size_t operand_location = jump_location + 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000589 uint8_t operand_bytes[2];
Ben Murdochc5610432016-08-08 18:44:38 +0100590 if (Bytecodes::SizeForSignedOperand(delta) <= OperandSize::kShort) {
Ben Murdochda12d292016-06-02 14:46:10 +0100591 constant_array_builder()->DiscardReservedEntry(OperandSize::kShort);
592 WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(delta));
593 } else {
594 jump_bytecode = GetJumpWithConstantOperand(jump_bytecode);
Ben Murdochc5610432016-08-08 18:44:38 +0100595 bytecodes->at(jump_location) = Bytecodes::ToByte(jump_bytecode);
Ben Murdochda12d292016-06-02 14:46:10 +0100596 size_t entry = constant_array_builder()->CommitReservedEntry(
597 OperandSize::kShort, handle(Smi::FromInt(delta), isolate()));
598 WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(entry));
599 }
Ben Murdochc5610432016-08-08 18:44:38 +0100600 DCHECK(bytecodes->at(operand_location) == 0 &&
601 bytecodes->at(operand_location + 1) == 0);
602 bytecodes->at(operand_location++) = operand_bytes[0];
603 bytecodes->at(operand_location) = operand_bytes[1];
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000604}
605
Ben Murdochc5610432016-08-08 18:44:38 +0100606void BytecodeArrayBuilder::PatchJumpWith32BitOperand(
607 ZoneVector<uint8_t>* bytecodes, size_t jump_location, int delta) {
608 DCHECK(Bytecodes::IsJumpImmediate(
609 Bytecodes::FromByte(bytecodes->at(jump_location))));
Ben Murdochda12d292016-06-02 14:46:10 +0100610 constant_array_builder()->DiscardReservedEntry(OperandSize::kQuad);
Ben Murdochda12d292016-06-02 14:46:10 +0100611 uint8_t operand_bytes[4];
612 WriteUnalignedUInt32(operand_bytes, static_cast<uint32_t>(delta));
Ben Murdochc5610432016-08-08 18:44:38 +0100613 size_t operand_location = jump_location + 1;
614 DCHECK(bytecodes->at(operand_location) == 0 &&
615 bytecodes->at(operand_location + 1) == 0 &&
616 bytecodes->at(operand_location + 2) == 0 &&
617 bytecodes->at(operand_location + 3) == 0);
618 bytecodes->at(operand_location++) = operand_bytes[0];
619 bytecodes->at(operand_location++) = operand_bytes[1];
620 bytecodes->at(operand_location++) = operand_bytes[2];
621 bytecodes->at(operand_location) = operand_bytes[3];
Ben Murdochda12d292016-06-02 14:46:10 +0100622}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000623
Ben Murdochc5610432016-08-08 18:44:38 +0100624void BytecodeArrayBuilder::PatchJump(size_t jump_target, size_t jump_location) {
625 ZoneVector<uint8_t>* bytecodes = bytecode_array_writer()->bytecodes();
626 Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes->at(jump_location));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000627 int delta = static_cast<int>(jump_target - jump_location);
Ben Murdochda12d292016-06-02 14:46:10 +0100628 int prefix_offset = 0;
629 OperandScale operand_scale = OperandScale::kSingle;
630 if (Bytecodes::IsPrefixScalingBytecode(jump_bytecode)) {
631 // If a prefix scaling bytecode is emitted the target offset is one
632 // less than the case of no prefix scaling bytecode.
633 delta -= 1;
634 prefix_offset = 1;
635 operand_scale = Bytecodes::PrefixBytecodeToOperandScale(jump_bytecode);
Ben Murdochc5610432016-08-08 18:44:38 +0100636 jump_bytecode =
637 Bytecodes::FromByte(bytecodes->at(jump_location + prefix_offset));
Ben Murdochda12d292016-06-02 14:46:10 +0100638 }
639
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000640 DCHECK(Bytecodes::IsJump(jump_bytecode));
Ben Murdochda12d292016-06-02 14:46:10 +0100641 switch (operand_scale) {
642 case OperandScale::kSingle:
Ben Murdochc5610432016-08-08 18:44:38 +0100643 PatchJumpWith8BitOperand(bytecodes, jump_location, delta);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000644 break;
Ben Murdochda12d292016-06-02 14:46:10 +0100645 case OperandScale::kDouble:
Ben Murdochc5610432016-08-08 18:44:38 +0100646 PatchJumpWith16BitOperand(bytecodes, jump_location + prefix_offset,
647 delta);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000648 break;
Ben Murdochda12d292016-06-02 14:46:10 +0100649 case OperandScale::kQuadruple:
Ben Murdochc5610432016-08-08 18:44:38 +0100650 PatchJumpWith32BitOperand(bytecodes, jump_location + prefix_offset,
651 delta);
Ben Murdochda12d292016-06-02 14:46:10 +0100652 break;
653 default:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000654 UNREACHABLE();
655 }
656 unbound_jumps_--;
657}
658
659
660BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode,
661 BytecodeLabel* label) {
662 // Don't emit dead code.
Ben Murdochda12d292016-06-02 14:46:10 +0100663 if (exit_seen_in_block_) return *this;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000664
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000665 if (label->is_bound()) {
666 // Label has been bound already so this is a backwards jump.
Ben Murdochc5610432016-08-08 18:44:38 +0100667 size_t current_offset = pipeline()->FlushForOffset();
668 CHECK_GE(current_offset, label->offset());
669 CHECK_LE(current_offset, static_cast<size_t>(kMaxInt));
670 size_t abs_delta = current_offset - label->offset();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000671 int delta = -static_cast<int>(abs_delta);
Ben Murdochc5610432016-08-08 18:44:38 +0100672 OperandSize operand_size = Bytecodes::SizeForSignedOperand(delta);
Ben Murdochda12d292016-06-02 14:46:10 +0100673 if (operand_size > OperandSize::kByte) {
674 // Adjust for scaling byte prefix for wide jump offset.
675 DCHECK_LE(delta, 0);
676 delta -= 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000677 }
Ben Murdochc5610432016-08-08 18:44:38 +0100678 OutputScaled(jump_bytecode, Bytecodes::OperandSizesToScale(operand_size),
Ben Murdochda12d292016-06-02 14:46:10 +0100679 SignedOperand(delta, operand_size));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000680 } else {
681 // The label has not yet been bound so this is a forward reference
682 // that will be patched when the label is bound. We create a
683 // reservation in the constant pool so the jump can be patched
684 // when the label is bound. The reservation means the maximum size
685 // of the operand for the constant is known and the jump can
686 // be emitted into the bytecode stream with space for the operand.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000687 unbound_jumps_++;
688 OperandSize reserved_operand_size =
689 constant_array_builder()->CreateReservedEntry();
Ben Murdochc5610432016-08-08 18:44:38 +0100690 OutputScaled(jump_bytecode,
691 Bytecodes::OperandSizesToScale(reserved_operand_size), 0);
692
693 // Calculate the label position by flushing for offset after emitting the
694 // jump bytecode.
695 size_t offset = pipeline()->FlushForOffset();
696 OperandScale operand_scale =
697 Bytecodes::OperandSizesToScale(reserved_operand_size);
698 offset -= Bytecodes::Size(jump_bytecode, operand_scale);
699 if (Bytecodes::OperandScaleRequiresPrefixBytecode(operand_scale)) {
700 offset -= 1;
701 }
702 label->set_referrer(offset);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000703 }
704 LeaveBasicBlock();
705 return *this;
706}
707
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000708BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) {
709 return OutputJump(Bytecode::kJump, label);
710}
711
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000712BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) {
Ben Murdochc5610432016-08-08 18:44:38 +0100713 // The peephole optimizer attempts to simplify JumpIfToBooleanTrue
714 // to JumpIfTrue.
715 return OutputJump(Bytecode::kJumpIfToBooleanTrue, label);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000716}
717
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000718BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) {
Ben Murdochc5610432016-08-08 18:44:38 +0100719 // The peephole optimizer attempts to simplify JumpIfToBooleanFalse
720 // to JumpIfFalse.
721 return OutputJump(Bytecode::kJumpIfToBooleanFalse, label);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000722}
723
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000724BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) {
725 return OutputJump(Bytecode::kJumpIfNull, label);
726}
727
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000728BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined(
729 BytecodeLabel* label) {
730 return OutputJump(Bytecode::kJumpIfUndefined, label);
731}
732
Ben Murdochc5610432016-08-08 18:44:38 +0100733BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) {
734 if (position != RelocInfo::kNoPosition) {
735 // We need to attach a non-breakable source position to a stack check,
736 // so we simply add it as expression position.
737 latest_source_info_.Update({position, false});
738 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100739 Output(Bytecode::kStackCheck);
740 return *this;
741}
742
743BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole(
744 BytecodeLabel* label) {
745 return OutputJump(Bytecode::kJumpIfNotHole, label);
746}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000747
748BytecodeArrayBuilder& BytecodeArrayBuilder::Throw() {
749 Output(Bytecode::kThrow);
750 exit_seen_in_block_ = true;
751 return *this;
752}
753
754
Ben Murdoch097c5b22016-05-18 11:27:45 +0100755BytecodeArrayBuilder& BytecodeArrayBuilder::ReThrow() {
756 Output(Bytecode::kReThrow);
757 exit_seen_in_block_ = true;
758 return *this;
759}
760
761
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000762BytecodeArrayBuilder& BytecodeArrayBuilder::Return() {
Ben Murdochda12d292016-06-02 14:46:10 +0100763 SetReturnPosition();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000764 Output(Bytecode::kReturn);
765 exit_seen_in_block_ = true;
766 return *this;
767}
768
Ben Murdoch097c5b22016-05-18 11:27:45 +0100769BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() {
770 Output(Bytecode::kDebugger);
771 return *this;
772}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000773
774BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100775 Register cache_info_triple) {
Ben Murdochda12d292016-06-02 14:46:10 +0100776 OperandScale operand_scale =
Ben Murdochc5610432016-08-08 18:44:38 +0100777 Bytecodes::OperandSizesToScale(cache_info_triple.SizeOfOperand());
Ben Murdochda12d292016-06-02 14:46:10 +0100778 OutputScaled(Bytecode::kForInPrepare, operand_scale,
779 RegisterOperand(cache_info_triple));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000780 return *this;
781}
782
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000783BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index,
784 Register cache_length) {
Ben Murdochc5610432016-08-08 18:44:38 +0100785 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
786 index.SizeOfOperand(), cache_length.SizeOfOperand());
Ben Murdochda12d292016-06-02 14:46:10 +0100787 OutputScaled(Bytecode::kForInDone, operand_scale, RegisterOperand(index),
788 RegisterOperand(cache_length));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000789 return *this;
790}
791
Ben Murdoch097c5b22016-05-18 11:27:45 +0100792BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext(
Ben Murdochda12d292016-06-02 14:46:10 +0100793 Register receiver, Register index, Register cache_type_array_pair,
794 int feedback_slot) {
Ben Murdochc5610432016-08-08 18:44:38 +0100795 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
796 receiver.SizeOfOperand(), index.SizeOfOperand(),
797 cache_type_array_pair.SizeOfOperand(),
798 Bytecodes::SizeForUnsignedOperand(feedback_slot));
Ben Murdochda12d292016-06-02 14:46:10 +0100799 OutputScaled(Bytecode::kForInNext, operand_scale, RegisterOperand(receiver),
800 RegisterOperand(index), RegisterOperand(cache_type_array_pair),
801 UnsignedOperand(feedback_slot));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000802 return *this;
803}
804
805
806BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) {
Ben Murdochda12d292016-06-02 14:46:10 +0100807 OperandScale operand_scale =
Ben Murdochc5610432016-08-08 18:44:38 +0100808 Bytecodes::OperandSizesToScale(index.SizeOfOperand());
Ben Murdochda12d292016-06-02 14:46:10 +0100809 OutputScaled(Bytecode::kForInStep, operand_scale, RegisterOperand(index));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100810 return *this;
811}
812
813
Ben Murdochc5610432016-08-08 18:44:38 +0100814BytecodeArrayBuilder& BytecodeArrayBuilder::SuspendGenerator(
815 Register generator) {
816 OperandScale operand_scale =
817 Bytecodes::OperandSizesToScale(generator.SizeOfOperand());
818 OutputScaled(Bytecode::kSuspendGenerator, operand_scale,
819 RegisterOperand(generator));
820 return *this;
821}
822
823
824BytecodeArrayBuilder& BytecodeArrayBuilder::ResumeGenerator(
825 Register generator) {
826 OperandScale operand_scale =
827 Bytecodes::OperandSizesToScale(generator.SizeOfOperand());
828 OutputScaled(Bytecode::kResumeGenerator, operand_scale,
829 RegisterOperand(generator));
830 return *this;
831}
832
833
Ben Murdoch097c5b22016-05-18 11:27:45 +0100834BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id,
835 bool will_catch) {
Ben Murdochc5610432016-08-08 18:44:38 +0100836 size_t offset = pipeline()->FlushForOffset();
837 handler_table_builder()->SetHandlerTarget(handler_id, offset);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100838 handler_table_builder()->SetPrediction(handler_id, will_catch);
839 return *this;
840}
841
842
843BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryBegin(int handler_id,
844 Register context) {
Ben Murdochc5610432016-08-08 18:44:38 +0100845 size_t offset = pipeline()->FlushForOffset();
846 handler_table_builder()->SetTryRegionStart(handler_id, offset);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100847 handler_table_builder()->SetContextRegister(handler_id, context);
848 return *this;
849}
850
851
852BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryEnd(int handler_id) {
Ben Murdochc5610432016-08-08 18:44:38 +0100853 size_t offset = pipeline()->FlushForOffset();
854 handler_table_builder()->SetTryRegionEnd(handler_id, offset);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000855 return *this;
856}
857
858
859void BytecodeArrayBuilder::LeaveBasicBlock() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000860 exit_seen_in_block_ = false;
Ben Murdochc5610432016-08-08 18:44:38 +0100861 pipeline()->FlushBasicBlock();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000862}
863
Ben Murdochda12d292016-06-02 14:46:10 +0100864void BytecodeArrayBuilder::EnsureReturn() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000865 if (!exit_seen_in_block_) {
866 LoadUndefined();
867 Return();
868 }
Ben Murdochda12d292016-06-02 14:46:10 +0100869 DCHECK(exit_seen_in_block_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000870}
871
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000872BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100873 Register receiver_args,
874 size_t receiver_args_count,
875 int feedback_slot,
876 TailCallMode tail_call_mode) {
877 Bytecode bytecode = BytecodeForCall(tail_call_mode);
Ben Murdochc5610432016-08-08 18:44:38 +0100878 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
879 callable.SizeOfOperand(), receiver_args.SizeOfOperand(),
880 Bytecodes::SizeForUnsignedOperand(receiver_args_count),
881 Bytecodes::SizeForUnsignedOperand(feedback_slot));
Ben Murdochda12d292016-06-02 14:46:10 +0100882 OutputScaled(bytecode, operand_scale, RegisterOperand(callable),
883 RegisterOperand(receiver_args),
884 UnsignedOperand(receiver_args_count),
885 UnsignedOperand(feedback_slot));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000886 return *this;
887}
888
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000889BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor,
890 Register first_arg,
891 size_t arg_count) {
892 if (!first_arg.is_valid()) {
893 DCHECK_EQ(0u, arg_count);
894 first_arg = Register(0);
895 }
Ben Murdochc5610432016-08-08 18:44:38 +0100896 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
897 constructor.SizeOfOperand(), first_arg.SizeOfOperand(),
898 Bytecodes::SizeForUnsignedOperand(arg_count));
Ben Murdochda12d292016-06-02 14:46:10 +0100899 OutputScaled(Bytecode::kNew, operand_scale, RegisterOperand(constructor),
900 RegisterOperand(first_arg), UnsignedOperand(arg_count));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000901 return *this;
902}
903
904
905BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
906 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) {
907 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size);
Ben Murdochc5610432016-08-08 18:44:38 +0100908 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000909 if (!first_arg.is_valid()) {
910 DCHECK_EQ(0u, arg_count);
911 first_arg = Register(0);
912 }
Ben Murdochda12d292016-06-02 14:46:10 +0100913 Bytecode bytecode = IntrinsicsHelper::IsSupported(function_id)
914 ? Bytecode::kInvokeIntrinsic
915 : Bytecode::kCallRuntime;
Ben Murdochc5610432016-08-08 18:44:38 +0100916 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
917 first_arg.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(arg_count));
Ben Murdochda12d292016-06-02 14:46:10 +0100918 OutputScaled(bytecode, operand_scale, static_cast<uint16_t>(function_id),
919 RegisterOperand(first_arg), UnsignedOperand(arg_count));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000920 return *this;
921}
922
923
924BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair(
925 Runtime::FunctionId function_id, Register first_arg, size_t arg_count,
926 Register first_return) {
927 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size);
Ben Murdochc5610432016-08-08 18:44:38 +0100928 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000929 if (!first_arg.is_valid()) {
930 DCHECK_EQ(0u, arg_count);
931 first_arg = Register(0);
932 }
Ben Murdochc5610432016-08-08 18:44:38 +0100933 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
934 first_arg.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(arg_count),
935 first_return.SizeOfOperand());
Ben Murdochda12d292016-06-02 14:46:10 +0100936 OutputScaled(Bytecode::kCallRuntimeForPair, operand_scale,
937 static_cast<uint16_t>(function_id), RegisterOperand(first_arg),
938 UnsignedOperand(arg_count), RegisterOperand(first_return));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000939 return *this;
940}
941
Ben Murdoch097c5b22016-05-18 11:27:45 +0100942BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(
943 int context_index, Register receiver_args, size_t receiver_args_count) {
Ben Murdochc5610432016-08-08 18:44:38 +0100944 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
945 Bytecodes::SizeForUnsignedOperand(context_index),
946 receiver_args.SizeOfOperand(),
947 Bytecodes::SizeForUnsignedOperand(receiver_args_count));
Ben Murdochda12d292016-06-02 14:46:10 +0100948 OutputScaled(Bytecode::kCallJSRuntime, operand_scale,
949 UnsignedOperand(context_index), RegisterOperand(receiver_args),
950 UnsignedOperand(receiver_args_count));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000951 return *this;
952}
953
954
955BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object,
956 LanguageMode language_mode) {
Ben Murdochda12d292016-06-02 14:46:10 +0100957 OperandScale operand_scale =
Ben Murdochc5610432016-08-08 18:44:38 +0100958 Bytecodes::OperandSizesToScale(object.SizeOfOperand());
Ben Murdochda12d292016-06-02 14:46:10 +0100959 OutputScaled(BytecodeForDelete(language_mode), operand_scale,
960 RegisterOperand(object));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000961 return *this;
962}
963
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000964size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) {
965 return constant_array_builder()->Insert(object);
966}
967
Ben Murdochda12d292016-06-02 14:46:10 +0100968void BytecodeArrayBuilder::SetReturnPosition() {
969 if (return_position_ == RelocInfo::kNoPosition) return;
970 if (exit_seen_in_block_) return;
Ben Murdochc5610432016-08-08 18:44:38 +0100971 latest_source_info_.Update({return_position_, true});
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000972}
973
Ben Murdoch097c5b22016-05-18 11:27:45 +0100974void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) {
975 if (stmt->position() == RelocInfo::kNoPosition) return;
Ben Murdochda12d292016-06-02 14:46:10 +0100976 if (exit_seen_in_block_) return;
Ben Murdochc5610432016-08-08 18:44:38 +0100977 latest_source_info_.Update({stmt->position(), true});
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000978}
979
Ben Murdoch097c5b22016-05-18 11:27:45 +0100980void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) {
981 if (expr->position() == RelocInfo::kNoPosition) return;
Ben Murdochda12d292016-06-02 14:46:10 +0100982 if (exit_seen_in_block_) return;
Ben Murdochc5610432016-08-08 18:44:38 +0100983 latest_source_info_.Update({expr->position(), false});
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000984}
985
Ben Murdochda12d292016-06-02 14:46:10 +0100986void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) {
987 if (expr->position() == RelocInfo::kNoPosition) return;
988 if (exit_seen_in_block_) return;
Ben Murdochc5610432016-08-08 18:44:38 +0100989 latest_source_info_.Update({expr->position(), true});
Ben Murdochda12d292016-06-02 14:46:10 +0100990}
991
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000992bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100993 return temporary_register_allocator()->RegisterIsLive(reg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000994}
995
Ben Murdochda12d292016-06-02 14:46:10 +0100996bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode,
997 OperandScale operand_scale,
998 int operand_index,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000999 uint32_t operand_value) const {
Ben Murdochda12d292016-06-02 14:46:10 +01001000 OperandSize operand_size =
1001 Bytecodes::GetOperandSize(bytecode, operand_index, operand_scale);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001002 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index);
1003 switch (operand_type) {
1004 case OperandType::kNone:
1005 return false;
Ben Murdochda12d292016-06-02 14:46:10 +01001006 case OperandType::kRegCount: {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001007 if (operand_index > 0) {
1008 OperandType previous_operand_type =
1009 Bytecodes::GetOperandType(bytecode, operand_index - 1);
Ben Murdochda12d292016-06-02 14:46:10 +01001010 if (previous_operand_type != OperandType::kMaybeReg &&
1011 previous_operand_type != OperandType::kReg) {
1012 return false;
1013 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001014 }
Ben Murdochda12d292016-06-02 14:46:10 +01001015 } // Fall-through
1016 case OperandType::kFlag8:
1017 case OperandType::kIdx:
1018 case OperandType::kRuntimeId:
1019 case OperandType::kImm: {
1020 size_t unsigned_value = static_cast<size_t>(operand_value);
Ben Murdochc5610432016-08-08 18:44:38 +01001021 return Bytecodes::SizeForUnsignedOperand(unsigned_value) <= operand_size;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001022 }
Ben Murdochda12d292016-06-02 14:46:10 +01001023 case OperandType::kMaybeReg:
Ben Murdochc5610432016-08-08 18:44:38 +01001024 if (RegisterFromOperand(operand_value) == Register(0)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001025 return true;
1026 }
Ben Murdochda12d292016-06-02 14:46:10 +01001027 // Fall-through to kReg case.
1028 case OperandType::kReg:
1029 case OperandType::kRegOut: {
1030 Register reg = RegisterFromOperand(operand_value);
1031 return RegisterIsValid(reg, operand_size);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001032 }
Ben Murdochda12d292016-06-02 14:46:10 +01001033 case OperandType::kRegOutPair:
1034 case OperandType::kRegPair: {
1035 Register reg0 = RegisterFromOperand(operand_value);
1036 Register reg1 = Register(reg0.index() + 1);
1037 // The size of reg1 is immaterial.
1038 return RegisterIsValid(reg0, operand_size) &&
1039 RegisterIsValid(reg1, OperandSize::kQuad);
1040 }
1041 case OperandType::kRegOutTriple: {
1042 Register reg0 = RegisterFromOperand(operand_value);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001043 Register reg1 = Register(reg0.index() + 1);
1044 Register reg2 = Register(reg0.index() + 2);
Ben Murdochda12d292016-06-02 14:46:10 +01001045 // The size of reg1 and reg2 is immaterial.
1046 return RegisterIsValid(reg0, operand_size) &&
1047 RegisterIsValid(reg1, OperandSize::kQuad) &&
1048 RegisterIsValid(reg2, OperandSize::kQuad);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001049 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001050 }
1051 UNREACHABLE();
1052 return false;
1053}
1054
Ben Murdoch097c5b22016-05-18 11:27:45 +01001055bool BytecodeArrayBuilder::RegisterIsValid(Register reg,
Ben Murdochda12d292016-06-02 14:46:10 +01001056 OperandSize reg_size) const {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001057 if (!reg.is_valid()) {
1058 return false;
1059 }
1060
Ben Murdochc5610432016-08-08 18:44:38 +01001061 if (reg.SizeOfOperand() > reg_size) {
Ben Murdochda12d292016-06-02 14:46:10 +01001062 return false;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001063 }
1064
1065 if (reg.is_current_context() || reg.is_function_closure() ||
1066 reg.is_new_target()) {
1067 return true;
1068 } else if (reg.is_parameter()) {
1069 int parameter_index = reg.ToParameterIndex(parameter_count());
1070 return parameter_index >= 0 && parameter_index < parameter_count();
Ben Murdochda12d292016-06-02 14:46:10 +01001071 } else if (reg.index() < fixed_register_count()) {
1072 return true;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001073 } else {
Ben Murdochda12d292016-06-02 14:46:10 +01001074 return TemporaryRegisterIsLive(reg);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001075 }
1076}
1077
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001078// static
1079Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) {
1080 switch (op) {
1081 case Token::Value::ADD:
1082 return Bytecode::kAdd;
1083 case Token::Value::SUB:
1084 return Bytecode::kSub;
1085 case Token::Value::MUL:
1086 return Bytecode::kMul;
1087 case Token::Value::DIV:
1088 return Bytecode::kDiv;
1089 case Token::Value::MOD:
1090 return Bytecode::kMod;
1091 case Token::Value::BIT_OR:
1092 return Bytecode::kBitwiseOr;
1093 case Token::Value::BIT_XOR:
1094 return Bytecode::kBitwiseXor;
1095 case Token::Value::BIT_AND:
1096 return Bytecode::kBitwiseAnd;
1097 case Token::Value::SHL:
1098 return Bytecode::kShiftLeft;
1099 case Token::Value::SAR:
1100 return Bytecode::kShiftRight;
1101 case Token::Value::SHR:
1102 return Bytecode::kShiftRightLogical;
1103 default:
1104 UNREACHABLE();
Ben Murdochda12d292016-06-02 14:46:10 +01001105 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001106 }
1107}
1108
1109
1110// static
1111Bytecode BytecodeArrayBuilder::BytecodeForCountOperation(Token::Value op) {
1112 switch (op) {
1113 case Token::Value::ADD:
1114 return Bytecode::kInc;
1115 case Token::Value::SUB:
1116 return Bytecode::kDec;
1117 default:
1118 UNREACHABLE();
Ben Murdochda12d292016-06-02 14:46:10 +01001119 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001120 }
1121}
1122
1123
1124// static
1125Bytecode BytecodeArrayBuilder::BytecodeForCompareOperation(Token::Value op) {
1126 switch (op) {
1127 case Token::Value::EQ:
1128 return Bytecode::kTestEqual;
1129 case Token::Value::NE:
1130 return Bytecode::kTestNotEqual;
1131 case Token::Value::EQ_STRICT:
1132 return Bytecode::kTestEqualStrict;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001133 case Token::Value::LT:
1134 return Bytecode::kTestLessThan;
1135 case Token::Value::GT:
1136 return Bytecode::kTestGreaterThan;
1137 case Token::Value::LTE:
1138 return Bytecode::kTestLessThanOrEqual;
1139 case Token::Value::GTE:
1140 return Bytecode::kTestGreaterThanOrEqual;
1141 case Token::Value::INSTANCEOF:
1142 return Bytecode::kTestInstanceOf;
1143 case Token::Value::IN:
1144 return Bytecode::kTestIn;
1145 default:
1146 UNREACHABLE();
Ben Murdochda12d292016-06-02 14:46:10 +01001147 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001148 }
1149}
1150
1151
1152// static
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001153Bytecode BytecodeArrayBuilder::BytecodeForStoreIC(LanguageMode language_mode) {
1154 switch (language_mode) {
1155 case SLOPPY:
1156 return Bytecode::kStoreICSloppy;
1157 case STRICT:
1158 return Bytecode::kStoreICStrict;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001159 default:
1160 UNREACHABLE();
1161 }
Ben Murdochda12d292016-06-02 14:46:10 +01001162 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001163}
1164
1165
1166// static
1167Bytecode BytecodeArrayBuilder::BytecodeForKeyedStoreIC(
1168 LanguageMode language_mode) {
1169 switch (language_mode) {
1170 case SLOPPY:
1171 return Bytecode::kKeyedStoreICSloppy;
1172 case STRICT:
1173 return Bytecode::kKeyedStoreICStrict;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001174 default:
1175 UNREACHABLE();
1176 }
Ben Murdochda12d292016-06-02 14:46:10 +01001177 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001178}
1179
1180
1181// static
Ben Murdoch097c5b22016-05-18 11:27:45 +01001182Bytecode BytecodeArrayBuilder::BytecodeForLoadGlobal(TypeofMode typeof_mode) {
1183 return typeof_mode == INSIDE_TYPEOF ? Bytecode::kLdaGlobalInsideTypeof
1184 : Bytecode::kLdaGlobal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001185}
1186
1187
1188// static
1189Bytecode BytecodeArrayBuilder::BytecodeForStoreGlobal(
1190 LanguageMode language_mode) {
1191 switch (language_mode) {
1192 case SLOPPY:
1193 return Bytecode::kStaGlobalSloppy;
1194 case STRICT:
1195 return Bytecode::kStaGlobalStrict;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001196 default:
1197 UNREACHABLE();
1198 }
Ben Murdochda12d292016-06-02 14:46:10 +01001199 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001200}
1201
1202
1203// static
1204Bytecode BytecodeArrayBuilder::BytecodeForStoreLookupSlot(
1205 LanguageMode language_mode) {
1206 switch (language_mode) {
1207 case SLOPPY:
1208 return Bytecode::kStaLookupSlotSloppy;
1209 case STRICT:
1210 return Bytecode::kStaLookupSlotStrict;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001211 default:
1212 UNREACHABLE();
1213 }
Ben Murdochda12d292016-06-02 14:46:10 +01001214 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001215}
1216
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001217// static
1218Bytecode BytecodeArrayBuilder::BytecodeForCreateArguments(
1219 CreateArgumentsType type) {
1220 switch (type) {
1221 case CreateArgumentsType::kMappedArguments:
1222 return Bytecode::kCreateMappedArguments;
1223 case CreateArgumentsType::kUnmappedArguments:
1224 return Bytecode::kCreateUnmappedArguments;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001225 case CreateArgumentsType::kRestParameter:
1226 return Bytecode::kCreateRestParameter;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001227 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001228 UNREACHABLE();
Ben Murdochda12d292016-06-02 14:46:10 +01001229 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001230}
1231
1232
1233// static
1234Bytecode BytecodeArrayBuilder::BytecodeForDelete(LanguageMode language_mode) {
1235 switch (language_mode) {
1236 case SLOPPY:
1237 return Bytecode::kDeletePropertySloppy;
1238 case STRICT:
1239 return Bytecode::kDeletePropertyStrict;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001240 default:
1241 UNREACHABLE();
1242 }
Ben Murdochda12d292016-06-02 14:46:10 +01001243 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001244}
1245
Ben Murdoch097c5b22016-05-18 11:27:45 +01001246// static
1247Bytecode BytecodeArrayBuilder::BytecodeForCall(TailCallMode tail_call_mode) {
1248 switch (tail_call_mode) {
1249 case TailCallMode::kDisallow:
1250 return Bytecode::kCall;
1251 case TailCallMode::kAllow:
1252 return Bytecode::kTailCall;
1253 default:
1254 UNREACHABLE();
1255 }
Ben Murdochda12d292016-06-02 14:46:10 +01001256 return Bytecode::kIllegal;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001257}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001258
Ben Murdochda12d292016-06-02 14:46:10 +01001259uint32_t BytecodeArrayBuilder::RegisterOperand(Register reg) {
1260 return static_cast<uint32_t>(reg.ToOperand());
1261}
1262
1263Register BytecodeArrayBuilder::RegisterFromOperand(uint32_t operand) {
1264 return Register::FromOperand(static_cast<int32_t>(operand));
1265}
1266
1267uint32_t BytecodeArrayBuilder::SignedOperand(int value, OperandSize size) {
1268 switch (size) {
1269 case OperandSize::kByte:
1270 return static_cast<uint8_t>(value & 0xff);
1271 case OperandSize::kShort:
1272 return static_cast<uint16_t>(value & 0xffff);
1273 case OperandSize::kQuad:
1274 return static_cast<uint32_t>(value);
1275 case OperandSize::kNone:
1276 UNREACHABLE();
1277 }
1278 return 0;
1279}
1280
1281uint32_t BytecodeArrayBuilder::UnsignedOperand(int value) {
1282 DCHECK_GE(value, 0);
1283 return static_cast<uint32_t>(value);
1284}
1285
1286uint32_t BytecodeArrayBuilder::UnsignedOperand(size_t value) {
1287 DCHECK_LE(value, kMaxUInt32);
1288 return static_cast<uint32_t>(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001289}
1290
1291} // namespace interpreter
1292} // namespace internal
1293} // namespace v8