blob: c74fe7ef9d721a405eeec337f1f8f132e7901eb5 [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"
Ben Murdoch61f157c2016-09-16 13:49:30 +01009#include "src/interpreter/bytecode-dead-code-optimizer.h"
10#include "src/interpreter/bytecode-label.h"
Ben Murdochc5610432016-08-08 18:44:38 +010011#include "src/interpreter/bytecode-peephole-optimizer.h"
Ben Murdoch61f157c2016-09-16 13:49:30 +010012#include "src/interpreter/bytecode-register-optimizer.h"
Ben Murdochda12d292016-06-02 14:46:10 +010013#include "src/interpreter/interpreter-intrinsics.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000014
15namespace v8 {
16namespace internal {
17namespace interpreter {
18
Ben Murdoch097c5b22016-05-18 11:27:45 +010019BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone,
20 int parameter_count,
Ben Murdochda12d292016-06-02 14:46:10 +010021 int context_count, int locals_count,
22 FunctionLiteral* literal)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000023 : isolate_(isolate),
24 zone_(zone),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000025 bytecode_generated_(false),
26 constant_array_builder_(isolate, zone),
Ben Murdoch097c5b22016-05-18 11:27:45 +010027 handler_table_builder_(isolate, zone),
Ben Murdoch61f157c2016-09-16 13:49:30 +010028 return_seen_in_block_(false),
Ben Murdoch097c5b22016-05-18 11:27:45 +010029 parameter_count_(parameter_count),
30 local_register_count_(locals_count),
31 context_register_count_(context_count),
Ben Murdochc5610432016-08-08 18:44:38 +010032 temporary_allocator_(zone, fixed_register_count()),
Ben Murdoch61f157c2016-09-16 13:49:30 +010033 bytecode_array_writer_(isolate, zone, &constant_array_builder_),
Ben Murdochc5610432016-08-08 18:44:38 +010034 pipeline_(&bytecode_array_writer_) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010035 DCHECK_GE(parameter_count_, 0);
36 DCHECK_GE(context_register_count_, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000037 DCHECK_GE(local_register_count_, 0);
Ben Murdochc5610432016-08-08 18:44:38 +010038
Ben Murdoch61f157c2016-09-16 13:49:30 +010039 if (FLAG_ignition_deadcode) {
40 pipeline_ = new (zone) BytecodeDeadCodeOptimizer(pipeline_);
41 }
42
Ben Murdochc5610432016-08-08 18:44:38 +010043 if (FLAG_ignition_peephole) {
44 pipeline_ = new (zone)
45 BytecodePeepholeOptimizer(&constant_array_builder_, pipeline_);
46 }
47
Ben Murdoch61f157c2016-09-16 13:49:30 +010048 if (FLAG_ignition_reo) {
49 pipeline_ = new (zone) BytecodeRegisterOptimizer(
50 zone, &temporary_allocator_, parameter_count, pipeline_);
51 }
52
Ben Murdochda12d292016-06-02 14:46:10 +010053 return_position_ =
54 literal ? std::max(literal->start_position(), literal->end_position() - 1)
55 : RelocInfo::kNoPosition;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000056}
57
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000058Register BytecodeArrayBuilder::first_context_register() const {
59 DCHECK_GT(context_register_count_, 0);
60 return Register(local_register_count_);
61}
62
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000063Register BytecodeArrayBuilder::last_context_register() const {
64 DCHECK_GT(context_register_count_, 0);
65 return Register(local_register_count_ + context_register_count_ - 1);
66}
67
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000068Register BytecodeArrayBuilder::Parameter(int parameter_index) const {
69 DCHECK_GE(parameter_index, 0);
70 return Register::FromParameterIndex(parameter_index, parameter_count());
71}
72
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000073bool BytecodeArrayBuilder::RegisterIsParameterOrLocal(Register reg) const {
74 return reg.is_parameter() || reg.index() < locals_count();
75}
76
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000077Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() {
Ben Murdoch61f157c2016-09-16 13:49:30 +010078 DCHECK(return_seen_in_block_);
79 DCHECK(!bytecode_generated_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000080 bytecode_generated_ = true;
Ben Murdoch61f157c2016-09-16 13:49:30 +010081
82 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable();
83 return pipeline_->ToBytecodeArray(fixed_register_count(), parameter_count(),
84 handler_table);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000085}
86
Ben Murdoch61f157c2016-09-16 13:49:30 +010087namespace {
88
89static bool ExpressionPositionIsNeeded(Bytecode bytecode) {
90 // An expression position is always needed if filtering is turned
91 // off. Otherwise an expression is only needed if the bytecode has
92 // external side effects.
93 return !FLAG_ignition_filter_expression_positions ||
94 !Bytecodes::IsWithoutExternalSideEffects(bytecode);
95}
96
97} // namespace
98
Ben Murdochc5610432016-08-08 18:44:38 +010099void BytecodeArrayBuilder::AttachSourceInfo(BytecodeNode* node) {
100 if (latest_source_info_.is_valid()) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100101 // Statement positions need to be emitted immediately. Expression
102 // positions can be pushed back until a bytecode is found that can
103 // throw. Hence we only invalidate the existing source position
104 // information if it is used.
105 if (latest_source_info_.is_statement() ||
106 ExpressionPositionIsNeeded(node->bytecode())) {
107 node->source_info().Clone(latest_source_info_);
108 latest_source_info_.set_invalid();
109 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000110 }
111}
112
Ben Murdoch61f157c2016-09-16 13:49:30 +0100113void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0,
114 uint32_t operand1, uint32_t operand2,
115 uint32_t operand3) {
116 DCHECK(OperandsAreValid(bytecode, 4, operand0, operand1, operand2, operand3));
117 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3);
118 AttachSourceInfo(&node);
119 pipeline()->Write(&node);
120}
121
122void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0,
123 uint32_t operand1, uint32_t operand2) {
124 DCHECK(OperandsAreValid(bytecode, 3, operand0, operand1, operand2));
125 BytecodeNode node(bytecode, operand0, operand1, operand2);
126 AttachSourceInfo(&node);
127 pipeline()->Write(&node);
128}
129
130void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0,
131 uint32_t operand1) {
132 DCHECK(OperandsAreValid(bytecode, 2, operand0, operand1));
133 BytecodeNode node(bytecode, operand0, operand1);
134 AttachSourceInfo(&node);
135 pipeline()->Write(&node);
136}
137
138void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) {
139 DCHECK(OperandsAreValid(bytecode, 1, operand0));
140 BytecodeNode node(bytecode, operand0);
141 AttachSourceInfo(&node);
142 pipeline()->Write(&node);
143}
144
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000145void BytecodeArrayBuilder::Output(Bytecode bytecode) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100146 DCHECK(OperandsAreValid(bytecode, 0));
Ben Murdochc5610432016-08-08 18:44:38 +0100147 BytecodeNode node(bytecode);
148 AttachSourceInfo(&node);
149 pipeline()->Write(&node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000150}
151
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000152BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100153 Register reg) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100154 Output(BytecodeForBinaryOperation(op), RegisterOperand(reg));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000155 return *this;
156}
157
Ben Murdoch097c5b22016-05-18 11:27:45 +0100158BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000159 Output(BytecodeForCountOperation(op));
160 return *this;
161}
162
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000163BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() {
Ben Murdochc5610432016-08-08 18:44:38 +0100164 Output(Bytecode::kToBooleanLogicalNot);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000165 return *this;
166}
167
168
169BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() {
170 Output(Bytecode::kTypeOf);
171 return *this;
172}
173
Ben Murdoch097c5b22016-05-18 11:27:45 +0100174BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(Token::Value op,
175 Register reg) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100176 Output(BytecodeForCompareOperation(op), RegisterOperand(reg));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000177 return *this;
178}
179
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000180BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(
181 v8::internal::Smi* smi) {
182 int32_t raw_smi = smi->value();
183 if (raw_smi == 0) {
184 Output(Bytecode::kLdaZero);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000185 } else {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100186 Output(Bytecode::kLdaSmi, SignedOperand(raw_smi));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000187 }
188 return *this;
189}
190
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000191BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) {
192 size_t entry = GetConstantPoolEntry(object);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100193 Output(Bytecode::kLdaConstant, UnsignedOperand(entry));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000194 return *this;
195}
196
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000197BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() {
198 Output(Bytecode::kLdaUndefined);
199 return *this;
200}
201
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000202BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNull() {
203 Output(Bytecode::kLdaNull);
204 return *this;
205}
206
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000207BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTheHole() {
208 Output(Bytecode::kLdaTheHole);
209 return *this;
210}
211
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000212BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTrue() {
213 Output(Bytecode::kLdaTrue);
214 return *this;
215}
216
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000217BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() {
218 Output(Bytecode::kLdaFalse);
219 return *this;
220}
221
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000222BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
223 Register reg) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100224 Output(Bytecode::kLdar, RegisterOperand(reg));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000225 return *this;
226}
227
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000228BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
229 Register reg) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100230 Output(Bytecode::kStar, RegisterOperand(reg));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000231 return *this;
232}
233
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000234BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from,
235 Register to) {
236 DCHECK(from != to);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100237 Output(Bytecode::kMov, RegisterOperand(from), RegisterOperand(to));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000238 return *this;
239}
240
Ben Murdoch61f157c2016-09-16 13:49:30 +0100241BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(int feedback_slot,
242 TypeofMode typeof_mode) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100243 // TODO(rmcilroy): Potentially store typeof information in an
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000244 // operand rather than having extra bytecodes.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100245 Bytecode bytecode = BytecodeForLoadGlobal(typeof_mode);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100246 Output(bytecode, UnsignedOperand(feedback_slot));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000247 return *this;
248}
249
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000250BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal(
251 const Handle<String> name, int feedback_slot, LanguageMode language_mode) {
252 Bytecode bytecode = BytecodeForStoreGlobal(language_mode);
253 size_t name_index = GetConstantPoolEntry(name);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100254 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(feedback_slot));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000255 return *this;
256}
257
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000258BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context,
259 int slot_index) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100260 Output(Bytecode::kLdaContextSlot, RegisterOperand(context),
261 UnsignedOperand(slot_index));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000262 return *this;
263}
264
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000265BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context,
266 int slot_index) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100267 Output(Bytecode::kStaContextSlot, RegisterOperand(context),
268 UnsignedOperand(slot_index));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000269 return *this;
270}
271
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000272BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot(
273 const Handle<String> name, TypeofMode typeof_mode) {
274 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF)
275 ? Bytecode::kLdaLookupSlotInsideTypeof
276 : Bytecode::kLdaLookupSlot;
277 size_t name_index = GetConstantPoolEntry(name);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100278 Output(bytecode, UnsignedOperand(name_index));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000279 return *this;
280}
281
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000282BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot(
283 const Handle<String> name, LanguageMode language_mode) {
284 Bytecode bytecode = BytecodeForStoreLookupSlot(language_mode);
285 size_t name_index = GetConstantPoolEntry(name);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100286 Output(bytecode, UnsignedOperand(name_index));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000287 return *this;
288}
289
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000290BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100291 Register object, const Handle<Name> name, int feedback_slot) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000292 size_t name_index = GetConstantPoolEntry(name);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100293 Output(Bytecode::kLdaNamedProperty, RegisterOperand(object),
294 UnsignedOperand(name_index), UnsignedOperand(feedback_slot));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000295 return *this;
296}
297
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000298BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100299 Register object, int feedback_slot) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100300 Output(Bytecode::kLdaKeyedProperty, RegisterOperand(object),
301 UnsignedOperand(feedback_slot));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000302 return *this;
303}
304
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000305BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100306 Register object, const Handle<Name> name, int feedback_slot,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000307 LanguageMode language_mode) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100308 Bytecode bytecode = BytecodeForStoreNamedProperty(language_mode);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000309 size_t name_index = GetConstantPoolEntry(name);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100310 Output(bytecode, RegisterOperand(object), UnsignedOperand(name_index),
311 UnsignedOperand(feedback_slot));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000312 return *this;
313}
314
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000315BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
316 Register object, Register key, int feedback_slot,
317 LanguageMode language_mode) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100318 Bytecode bytecode = BytecodeForStoreKeyedProperty(language_mode);
319 Output(bytecode, RegisterOperand(object), RegisterOperand(key),
320 UnsignedOperand(feedback_slot));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000321 return *this;
322}
323
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000324BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(
325 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) {
326 size_t entry = GetConstantPoolEntry(shared_info);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100327 Output(Bytecode::kCreateClosure, UnsignedOperand(entry),
328 UnsignedOperand(static_cast<size_t>(tenured)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000329 return *this;
330}
331
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000332BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments(
333 CreateArgumentsType type) {
334 // TODO(rmcilroy): Consider passing the type as a bytecode operand rather
335 // than having two different bytecodes once we have better support for
336 // branches in the InterpreterAssembler.
337 Bytecode bytecode = BytecodeForCreateArguments(type);
338 Output(bytecode);
339 return *this;
340}
341
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000342BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral(
343 Handle<String> pattern, int literal_index, int flags) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000344 size_t pattern_entry = GetConstantPoolEntry(pattern);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100345 Output(Bytecode::kCreateRegExpLiteral, UnsignedOperand(pattern_entry),
346 UnsignedOperand(literal_index), UnsignedOperand(flags));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000347 return *this;
348}
349
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000350BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral(
351 Handle<FixedArray> constant_elements, int literal_index, int flags) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000352 size_t constant_elements_entry = GetConstantPoolEntry(constant_elements);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100353 Output(Bytecode::kCreateArrayLiteral,
354 UnsignedOperand(constant_elements_entry),
355 UnsignedOperand(literal_index), UnsignedOperand(flags));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000356 return *this;
357}
358
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000359BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral(
360 Handle<FixedArray> constant_properties, int literal_index, int flags) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000361 size_t constant_properties_entry = GetConstantPoolEntry(constant_properties);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100362 Output(Bytecode::kCreateObjectLiteral,
363 UnsignedOperand(constant_properties_entry),
364 UnsignedOperand(literal_index), UnsignedOperand(flags));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000365 return *this;
366}
367
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000368BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100369 Output(Bytecode::kPushContext, RegisterOperand(context));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000370 return *this;
371}
372
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000373BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100374 Output(Bytecode::kPopContext, RegisterOperand(context));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000375 return *this;
376}
377
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000378BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() {
379 Output(Bytecode::kToObject);
380 return *this;
381}
382
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000383BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000384 Output(Bytecode::kToName);
385 return *this;
386}
387
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000388BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000389 Output(Bytecode::kToNumber);
390 return *this;
391}
392
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000393BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100394 pipeline_->BindLabel(label);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000395 LeaveBasicBlock();
396 return *this;
397}
398
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000399BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target,
400 BytecodeLabel* label) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100401 pipeline_->BindLabel(target, label);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000402 LeaveBasicBlock();
403 return *this;
404}
405
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000406BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode,
407 BytecodeLabel* label) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100408 BytecodeNode node(jump_bytecode, 0);
409 AttachSourceInfo(&node);
410 pipeline_->WriteJump(&node, label);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000411 LeaveBasicBlock();
412 return *this;
413}
414
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000415BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) {
416 return OutputJump(Bytecode::kJump, label);
417}
418
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000419BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) {
Ben Murdochc5610432016-08-08 18:44:38 +0100420 // The peephole optimizer attempts to simplify JumpIfToBooleanTrue
421 // to JumpIfTrue.
422 return OutputJump(Bytecode::kJumpIfToBooleanTrue, label);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000423}
424
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000425BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) {
Ben Murdochc5610432016-08-08 18:44:38 +0100426 // The peephole optimizer attempts to simplify JumpIfToBooleanFalse
427 // to JumpIfFalse.
428 return OutputJump(Bytecode::kJumpIfToBooleanFalse, label);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000429}
430
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000431BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) {
432 return OutputJump(Bytecode::kJumpIfNull, label);
433}
434
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000435BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined(
436 BytecodeLabel* label) {
437 return OutputJump(Bytecode::kJumpIfUndefined, label);
438}
439
Ben Murdoch097c5b22016-05-18 11:27:45 +0100440BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole(
441 BytecodeLabel* label) {
442 return OutputJump(Bytecode::kJumpIfNotHole, label);
443}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000444
Ben Murdoch61f157c2016-09-16 13:49:30 +0100445BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) {
446 if (position != RelocInfo::kNoPosition) {
447 // We need to attach a non-breakable source position to a stack
448 // check, so we simply add it as expression position. There can be
449 // a prior statement position from constructs like:
450 //
451 // do var x; while (false);
452 //
453 // A Nop could be inserted for empty statements, but since no code
454 // is associated with these positions, instead we force the stack
455 // check's expression position which eliminates the empty
456 // statement's position.
457 latest_source_info_.ForceExpressionPosition(position);
458 }
459 Output(Bytecode::kStackCheck);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000460 return *this;
461}
462
Ben Murdoch61f157c2016-09-16 13:49:30 +0100463BytecodeArrayBuilder& BytecodeArrayBuilder::Throw() {
464 Output(Bytecode::kThrow);
465 return *this;
466}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000467
Ben Murdoch097c5b22016-05-18 11:27:45 +0100468BytecodeArrayBuilder& BytecodeArrayBuilder::ReThrow() {
469 Output(Bytecode::kReThrow);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100470 return *this;
471}
472
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000473BytecodeArrayBuilder& BytecodeArrayBuilder::Return() {
Ben Murdochda12d292016-06-02 14:46:10 +0100474 SetReturnPosition();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000475 Output(Bytecode::kReturn);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100476 return_seen_in_block_ = true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000477 return *this;
478}
479
Ben Murdoch097c5b22016-05-18 11:27:45 +0100480BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() {
481 Output(Bytecode::kDebugger);
482 return *this;
483}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000484
485BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100486 Register cache_info_triple) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100487 Output(Bytecode::kForInPrepare, RegisterOperand(cache_info_triple));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000488 return *this;
489}
490
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000491BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index,
492 Register cache_length) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100493 Output(Bytecode::kForInDone, RegisterOperand(index),
494 RegisterOperand(cache_length));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000495 return *this;
496}
497
Ben Murdoch097c5b22016-05-18 11:27:45 +0100498BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext(
Ben Murdochda12d292016-06-02 14:46:10 +0100499 Register receiver, Register index, Register cache_type_array_pair,
500 int feedback_slot) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100501 Output(Bytecode::kForInNext, RegisterOperand(receiver),
502 RegisterOperand(index), RegisterOperand(cache_type_array_pair),
503 UnsignedOperand(feedback_slot));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000504 return *this;
505}
506
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000507BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100508 Output(Bytecode::kForInStep, RegisterOperand(index));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100509 return *this;
510}
511
Ben Murdochc5610432016-08-08 18:44:38 +0100512BytecodeArrayBuilder& BytecodeArrayBuilder::SuspendGenerator(
513 Register generator) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100514 Output(Bytecode::kSuspendGenerator, RegisterOperand(generator));
Ben Murdochc5610432016-08-08 18:44:38 +0100515 return *this;
516}
517
Ben Murdochc5610432016-08-08 18:44:38 +0100518BytecodeArrayBuilder& BytecodeArrayBuilder::ResumeGenerator(
519 Register generator) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100520 Output(Bytecode::kResumeGenerator, RegisterOperand(generator));
Ben Murdochc5610432016-08-08 18:44:38 +0100521 return *this;
522}
523
Ben Murdoch097c5b22016-05-18 11:27:45 +0100524BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id,
525 bool will_catch) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100526 BytecodeLabel handler;
527 Bind(&handler);
528 handler_table_builder()->SetHandlerTarget(handler_id, handler.offset());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100529 handler_table_builder()->SetPrediction(handler_id, will_catch);
530 return *this;
531}
532
Ben Murdoch097c5b22016-05-18 11:27:45 +0100533BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryBegin(int handler_id,
534 Register context) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100535 BytecodeLabel try_begin;
536 Bind(&try_begin);
537 handler_table_builder()->SetTryRegionStart(handler_id, try_begin.offset());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100538 handler_table_builder()->SetContextRegister(handler_id, context);
539 return *this;
540}
541
Ben Murdoch097c5b22016-05-18 11:27:45 +0100542BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryEnd(int handler_id) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100543 BytecodeLabel try_end;
544 Bind(&try_end);
545 handler_table_builder()->SetTryRegionEnd(handler_id, try_end.offset());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000546 return *this;
547}
548
Ben Murdochda12d292016-06-02 14:46:10 +0100549void BytecodeArrayBuilder::EnsureReturn() {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100550 if (!return_seen_in_block_) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000551 LoadUndefined();
552 Return();
553 }
Ben Murdoch61f157c2016-09-16 13:49:30 +0100554 DCHECK(return_seen_in_block_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000555}
556
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000557BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100558 Register receiver_args,
559 size_t receiver_args_count,
560 int feedback_slot,
561 TailCallMode tail_call_mode) {
562 Bytecode bytecode = BytecodeForCall(tail_call_mode);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100563 Output(bytecode, RegisterOperand(callable), RegisterOperand(receiver_args),
564 UnsignedOperand(receiver_args_count), UnsignedOperand(feedback_slot));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000565 return *this;
566}
567
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000568BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor,
569 Register first_arg,
570 size_t arg_count) {
571 if (!first_arg.is_valid()) {
572 DCHECK_EQ(0u, arg_count);
573 first_arg = Register(0);
574 }
Ben Murdoch61f157c2016-09-16 13:49:30 +0100575 Output(Bytecode::kNew, RegisterOperand(constructor),
576 RegisterOperand(first_arg), UnsignedOperand(arg_count));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000577 return *this;
578}
579
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000580BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
581 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) {
582 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size);
Ben Murdochc5610432016-08-08 18:44:38 +0100583 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000584 if (!first_arg.is_valid()) {
585 DCHECK_EQ(0u, arg_count);
586 first_arg = Register(0);
587 }
Ben Murdoch61f157c2016-09-16 13:49:30 +0100588 Bytecode bytecode;
589 uint32_t id;
590 if (IntrinsicsHelper::IsSupported(function_id)) {
591 bytecode = Bytecode::kInvokeIntrinsic;
592 id = static_cast<uint32_t>(IntrinsicsHelper::FromRuntimeId(function_id));
593 } else {
594 bytecode = Bytecode::kCallRuntime;
595 id = static_cast<uint32_t>(function_id);
596 }
597 Output(bytecode, id, RegisterOperand(first_arg), UnsignedOperand(arg_count));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000598 return *this;
599}
600
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000601BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair(
602 Runtime::FunctionId function_id, Register first_arg, size_t arg_count,
603 Register first_return) {
604 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size);
Ben Murdochc5610432016-08-08 18:44:38 +0100605 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000606 if (!first_arg.is_valid()) {
607 DCHECK_EQ(0u, arg_count);
608 first_arg = Register(0);
609 }
Ben Murdoch61f157c2016-09-16 13:49:30 +0100610 Output(Bytecode::kCallRuntimeForPair, static_cast<uint16_t>(function_id),
611 RegisterOperand(first_arg), UnsignedOperand(arg_count),
612 RegisterOperand(first_return));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000613 return *this;
614}
615
Ben Murdoch097c5b22016-05-18 11:27:45 +0100616BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(
617 int context_index, Register receiver_args, size_t receiver_args_count) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100618 Output(Bytecode::kCallJSRuntime, UnsignedOperand(context_index),
619 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000620 return *this;
621}
622
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000623BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object,
624 LanguageMode language_mode) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100625 Output(BytecodeForDelete(language_mode), RegisterOperand(object));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000626 return *this;
627}
628
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000629size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) {
630 return constant_array_builder()->Insert(object);
631}
632
Ben Murdochda12d292016-06-02 14:46:10 +0100633void BytecodeArrayBuilder::SetReturnPosition() {
634 if (return_position_ == RelocInfo::kNoPosition) return;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100635 latest_source_info_.MakeStatementPosition(return_position_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000636}
637
Ben Murdoch097c5b22016-05-18 11:27:45 +0100638void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) {
639 if (stmt->position() == RelocInfo::kNoPosition) return;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100640 latest_source_info_.MakeStatementPosition(stmt->position());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000641}
642
Ben Murdoch097c5b22016-05-18 11:27:45 +0100643void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) {
644 if (expr->position() == RelocInfo::kNoPosition) return;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100645 if (!latest_source_info_.is_statement()) {
646 // Ensure the current expression position is overwritten with the
647 // latest value.
648 latest_source_info_.MakeExpressionPosition(expr->position());
649 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000650}
651
Ben Murdochda12d292016-06-02 14:46:10 +0100652void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) {
653 if (expr->position() == RelocInfo::kNoPosition) return;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100654 latest_source_info_.MakeStatementPosition(expr->position());
Ben Murdochda12d292016-06-02 14:46:10 +0100655}
656
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000657bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100658 return temporary_register_allocator()->RegisterIsLive(reg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000659}
660
Ben Murdoch61f157c2016-09-16 13:49:30 +0100661bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100662 if (!reg.is_valid()) {
663 return false;
664 }
665
Ben Murdoch097c5b22016-05-18 11:27:45 +0100666 if (reg.is_current_context() || reg.is_function_closure() ||
667 reg.is_new_target()) {
668 return true;
669 } else if (reg.is_parameter()) {
670 int parameter_index = reg.ToParameterIndex(parameter_count());
671 return parameter_index >= 0 && parameter_index < parameter_count();
Ben Murdochda12d292016-06-02 14:46:10 +0100672 } else if (reg.index() < fixed_register_count()) {
673 return true;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100674 } else {
Ben Murdochda12d292016-06-02 14:46:10 +0100675 return TemporaryRegisterIsLive(reg);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100676 }
677}
678
Ben Murdoch61f157c2016-09-16 13:49:30 +0100679bool BytecodeArrayBuilder::OperandsAreValid(
680 Bytecode bytecode, int operand_count, uint32_t operand0, uint32_t operand1,
681 uint32_t operand2, uint32_t operand3) const {
682 if (Bytecodes::NumberOfOperands(bytecode) != operand_count) {
683 return false;
684 }
685
686 uint32_t operands[] = {operand0, operand1, operand2, operand3};
687 const OperandType* operand_types = Bytecodes::GetOperandTypes(bytecode);
688 for (int i = 0; i < operand_count; ++i) {
689 switch (operand_types[i]) {
690 case OperandType::kNone:
691 return false;
692 case OperandType::kRegCount: {
693 CHECK_NE(i, 0);
694 CHECK(operand_types[i - 1] == OperandType::kMaybeReg ||
695 operand_types[i - 1] == OperandType::kReg);
696 if (i > 0 && operands[i] > 0) {
697 Register start = Register::FromOperand(operands[i - 1]);
698 Register end(start.index() + static_cast<int>(operands[i]) - 1);
699 if (!RegisterIsValid(start) || !RegisterIsValid(end) || start > end) {
700 return false;
701 }
702 }
703 break;
704 }
705 case OperandType::kFlag8:
706 case OperandType::kIntrinsicId:
707 if (Bytecodes::SizeForUnsignedOperand(operands[i]) >
708 OperandSize::kByte) {
709 return false;
710 }
711 break;
712 case OperandType::kRuntimeId:
713 if (Bytecodes::SizeForUnsignedOperand(operands[i]) >
714 OperandSize::kShort) {
715 return false;
716 }
717 break;
718 case OperandType::kIdx:
719 // TODO(oth): Consider splitting OperandType::kIdx into two
720 // operand types. One which is a constant pool index that can
721 // be checked, and the other is an unsigned value.
722 break;
723 case OperandType::kImm:
724 break;
725 case OperandType::kMaybeReg:
726 if (Register::FromOperand(operands[i]) == Register(0)) {
727 break;
728 }
729 // Fall-through to kReg case.
730 case OperandType::kReg:
731 case OperandType::kRegOut: {
732 Register reg = Register::FromOperand(operands[i]);
733 if (!RegisterIsValid(reg)) {
734 return false;
735 }
736 break;
737 }
738 case OperandType::kRegOutPair:
739 case OperandType::kRegPair: {
740 Register reg0 = Register::FromOperand(operands[i]);
741 Register reg1 = Register(reg0.index() + 1);
742 if (!RegisterIsValid(reg0) || !RegisterIsValid(reg1)) {
743 return false;
744 }
745 break;
746 }
747 case OperandType::kRegOutTriple: {
748 Register reg0 = Register::FromOperand(operands[i]);
749 Register reg1 = Register(reg0.index() + 1);
750 Register reg2 = Register(reg0.index() + 2);
751 if (!RegisterIsValid(reg0) || !RegisterIsValid(reg1) ||
752 !RegisterIsValid(reg2)) {
753 return false;
754 }
755 break;
756 }
757 }
758 }
759
760 return true;
761}
762
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000763// static
764Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) {
765 switch (op) {
766 case Token::Value::ADD:
767 return Bytecode::kAdd;
768 case Token::Value::SUB:
769 return Bytecode::kSub;
770 case Token::Value::MUL:
771 return Bytecode::kMul;
772 case Token::Value::DIV:
773 return Bytecode::kDiv;
774 case Token::Value::MOD:
775 return Bytecode::kMod;
776 case Token::Value::BIT_OR:
777 return Bytecode::kBitwiseOr;
778 case Token::Value::BIT_XOR:
779 return Bytecode::kBitwiseXor;
780 case Token::Value::BIT_AND:
781 return Bytecode::kBitwiseAnd;
782 case Token::Value::SHL:
783 return Bytecode::kShiftLeft;
784 case Token::Value::SAR:
785 return Bytecode::kShiftRight;
786 case Token::Value::SHR:
787 return Bytecode::kShiftRightLogical;
788 default:
789 UNREACHABLE();
Ben Murdochda12d292016-06-02 14:46:10 +0100790 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000791 }
792}
793
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000794// static
795Bytecode BytecodeArrayBuilder::BytecodeForCountOperation(Token::Value op) {
796 switch (op) {
797 case Token::Value::ADD:
798 return Bytecode::kInc;
799 case Token::Value::SUB:
800 return Bytecode::kDec;
801 default:
802 UNREACHABLE();
Ben Murdochda12d292016-06-02 14:46:10 +0100803 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000804 }
805}
806
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000807// static
808Bytecode BytecodeArrayBuilder::BytecodeForCompareOperation(Token::Value op) {
809 switch (op) {
810 case Token::Value::EQ:
811 return Bytecode::kTestEqual;
812 case Token::Value::NE:
813 return Bytecode::kTestNotEqual;
814 case Token::Value::EQ_STRICT:
815 return Bytecode::kTestEqualStrict;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000816 case Token::Value::LT:
817 return Bytecode::kTestLessThan;
818 case Token::Value::GT:
819 return Bytecode::kTestGreaterThan;
820 case Token::Value::LTE:
821 return Bytecode::kTestLessThanOrEqual;
822 case Token::Value::GTE:
823 return Bytecode::kTestGreaterThanOrEqual;
824 case Token::Value::INSTANCEOF:
825 return Bytecode::kTestInstanceOf;
826 case Token::Value::IN:
827 return Bytecode::kTestIn;
828 default:
829 UNREACHABLE();
Ben Murdochda12d292016-06-02 14:46:10 +0100830 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000831 }
832}
833
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000834// static
Ben Murdoch61f157c2016-09-16 13:49:30 +0100835Bytecode BytecodeArrayBuilder::BytecodeForStoreNamedProperty(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000836 LanguageMode language_mode) {
837 switch (language_mode) {
838 case SLOPPY:
Ben Murdoch61f157c2016-09-16 13:49:30 +0100839 return Bytecode::kStaNamedPropertySloppy;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000840 case STRICT:
Ben Murdoch61f157c2016-09-16 13:49:30 +0100841 return Bytecode::kStaNamedPropertyStrict;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000842 default:
843 UNREACHABLE();
844 }
Ben Murdochda12d292016-06-02 14:46:10 +0100845 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000846}
847
Ben Murdoch61f157c2016-09-16 13:49:30 +0100848// static
849Bytecode BytecodeArrayBuilder::BytecodeForStoreKeyedProperty(
850 LanguageMode language_mode) {
851 switch (language_mode) {
852 case SLOPPY:
853 return Bytecode::kStaKeyedPropertySloppy;
854 case STRICT:
855 return Bytecode::kStaKeyedPropertyStrict;
856 default:
857 UNREACHABLE();
858 }
859 return Bytecode::kIllegal;
860}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000861
862// static
Ben Murdoch097c5b22016-05-18 11:27:45 +0100863Bytecode BytecodeArrayBuilder::BytecodeForLoadGlobal(TypeofMode typeof_mode) {
864 return typeof_mode == INSIDE_TYPEOF ? Bytecode::kLdaGlobalInsideTypeof
865 : Bytecode::kLdaGlobal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000866}
867
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000868// static
869Bytecode BytecodeArrayBuilder::BytecodeForStoreGlobal(
870 LanguageMode language_mode) {
871 switch (language_mode) {
872 case SLOPPY:
873 return Bytecode::kStaGlobalSloppy;
874 case STRICT:
875 return Bytecode::kStaGlobalStrict;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000876 default:
877 UNREACHABLE();
878 }
Ben Murdochda12d292016-06-02 14:46:10 +0100879 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000880}
881
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000882// static
883Bytecode BytecodeArrayBuilder::BytecodeForStoreLookupSlot(
884 LanguageMode language_mode) {
885 switch (language_mode) {
886 case SLOPPY:
887 return Bytecode::kStaLookupSlotSloppy;
888 case STRICT:
889 return Bytecode::kStaLookupSlotStrict;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000890 default:
891 UNREACHABLE();
892 }
Ben Murdochda12d292016-06-02 14:46:10 +0100893 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000894}
895
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000896// static
897Bytecode BytecodeArrayBuilder::BytecodeForCreateArguments(
898 CreateArgumentsType type) {
899 switch (type) {
900 case CreateArgumentsType::kMappedArguments:
901 return Bytecode::kCreateMappedArguments;
902 case CreateArgumentsType::kUnmappedArguments:
903 return Bytecode::kCreateUnmappedArguments;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100904 case CreateArgumentsType::kRestParameter:
905 return Bytecode::kCreateRestParameter;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000906 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100907 UNREACHABLE();
Ben Murdochda12d292016-06-02 14:46:10 +0100908 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000909}
910
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000911// static
912Bytecode BytecodeArrayBuilder::BytecodeForDelete(LanguageMode language_mode) {
913 switch (language_mode) {
914 case SLOPPY:
915 return Bytecode::kDeletePropertySloppy;
916 case STRICT:
917 return Bytecode::kDeletePropertyStrict;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000918 default:
919 UNREACHABLE();
920 }
Ben Murdochda12d292016-06-02 14:46:10 +0100921 return Bytecode::kIllegal;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000922}
923
Ben Murdoch097c5b22016-05-18 11:27:45 +0100924// static
925Bytecode BytecodeArrayBuilder::BytecodeForCall(TailCallMode tail_call_mode) {
926 switch (tail_call_mode) {
927 case TailCallMode::kDisallow:
928 return Bytecode::kCall;
929 case TailCallMode::kAllow:
930 return Bytecode::kTailCall;
931 default:
932 UNREACHABLE();
933 }
Ben Murdochda12d292016-06-02 14:46:10 +0100934 return Bytecode::kIllegal;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100935}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000936
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000937} // namespace interpreter
938} // namespace internal
939} // namespace v8