11cb0ef41Sopenharmony_ci// Copyright 2015 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_INTERPRETER_BYTECODE_ARRAY_WRITER_H_
61cb0ef41Sopenharmony_ci#define V8_INTERPRETER_BYTECODE_ARRAY_WRITER_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/base/compiler-specific.h"
91cb0ef41Sopenharmony_ci#include "src/codegen/source-position-table.h"
101cb0ef41Sopenharmony_ci#include "src/common/globals.h"
111cb0ef41Sopenharmony_ci#include "src/interpreter/bytecodes.h"
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_cinamespace v8 {
141cb0ef41Sopenharmony_cinamespace internal {
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ciclass BytecodeArray;
171cb0ef41Sopenharmony_ciclass SourcePositionTableBuilder;
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_cinamespace interpreter {
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ciclass BytecodeLabel;
221cb0ef41Sopenharmony_ciclass BytecodeLoopHeader;
231cb0ef41Sopenharmony_ciclass BytecodeNode;
241cb0ef41Sopenharmony_ciclass BytecodeJumpTable;
251cb0ef41Sopenharmony_ciclass ConstantArrayBuilder;
261cb0ef41Sopenharmony_ciclass HandlerTableBuilder;
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_cinamespace bytecode_array_writer_unittest {
291cb0ef41Sopenharmony_ciclass BytecodeArrayWriterUnittest;
301cb0ef41Sopenharmony_ci}  // namespace bytecode_array_writer_unittest
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci// Class for emitting bytecode as the final stage of the bytecode
331cb0ef41Sopenharmony_ci// generation pipeline.
341cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE BytecodeArrayWriter final {
351cb0ef41Sopenharmony_ci public:
361cb0ef41Sopenharmony_ci  BytecodeArrayWriter(
371cb0ef41Sopenharmony_ci      Zone* zone, ConstantArrayBuilder* constant_array_builder,
381cb0ef41Sopenharmony_ci      SourcePositionTableBuilder::RecordingMode source_position_mode);
391cb0ef41Sopenharmony_ci  BytecodeArrayWriter(const BytecodeArrayWriter&) = delete;
401cb0ef41Sopenharmony_ci  BytecodeArrayWriter& operator=(const BytecodeArrayWriter&) = delete;
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  void Write(BytecodeNode* node);
431cb0ef41Sopenharmony_ci  void WriteJump(BytecodeNode* node, BytecodeLabel* label);
441cb0ef41Sopenharmony_ci  void WriteJumpLoop(BytecodeNode* node, BytecodeLoopHeader* loop_header);
451cb0ef41Sopenharmony_ci  void WriteSwitch(BytecodeNode* node, BytecodeJumpTable* jump_table);
461cb0ef41Sopenharmony_ci  void BindLabel(BytecodeLabel* label);
471cb0ef41Sopenharmony_ci  void BindLoopHeader(BytecodeLoopHeader* loop_header);
481cb0ef41Sopenharmony_ci  void BindJumpTableEntry(BytecodeJumpTable* jump_table, int case_value);
491cb0ef41Sopenharmony_ci  void BindHandlerTarget(HandlerTableBuilder* handler_table_builder,
501cb0ef41Sopenharmony_ci                         int handler_id);
511cb0ef41Sopenharmony_ci  void BindTryRegionStart(HandlerTableBuilder* handler_table_builder,
521cb0ef41Sopenharmony_ci                          int handler_id);
531cb0ef41Sopenharmony_ci  void BindTryRegionEnd(HandlerTableBuilder* handler_table_builder,
541cb0ef41Sopenharmony_ci                        int handler_id);
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci  void SetFunctionEntrySourcePosition(int position);
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci  template <typename IsolateT>
591cb0ef41Sopenharmony_ci  EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
601cb0ef41Sopenharmony_ci  Handle<BytecodeArray> ToBytecodeArray(IsolateT* isolate, int register_count,
611cb0ef41Sopenharmony_ci                                        int parameter_count,
621cb0ef41Sopenharmony_ci                                        Handle<ByteArray> handler_table);
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  template <typename IsolateT>
651cb0ef41Sopenharmony_ci  EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
661cb0ef41Sopenharmony_ci  Handle<ByteArray> ToSourcePositionTable(IsolateT* isolate);
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci#ifdef DEBUG
691cb0ef41Sopenharmony_ci  // Returns -1 if they match or the offset of the first mismatching byte.
701cb0ef41Sopenharmony_ci  int CheckBytecodeMatches(BytecodeArray bytecode);
711cb0ef41Sopenharmony_ci#endif
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  bool RemainderOfBlockIsDead() const { return exit_seen_in_block_; }
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci private:
761cb0ef41Sopenharmony_ci  // Maximum sized packed bytecode is comprised of a prefix bytecode,
771cb0ef41Sopenharmony_ci  // plus the actual bytecode, plus the maximum number of operands times
781cb0ef41Sopenharmony_ci  // the maximum operand size.
791cb0ef41Sopenharmony_ci  static const size_t kMaxSizeOfPackedBytecode =
801cb0ef41Sopenharmony_ci      2 * sizeof(Bytecode) +
811cb0ef41Sopenharmony_ci      Bytecodes::kMaxOperands * static_cast<size_t>(OperandSize::kLast);
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci  // Constants that act as placeholders for jump operands to be
841cb0ef41Sopenharmony_ci  // patched. These have operand sizes that match the sizes of
851cb0ef41Sopenharmony_ci  // reserved constant pool entries.
861cb0ef41Sopenharmony_ci  const uint32_t k8BitJumpPlaceholder = 0x7f;
871cb0ef41Sopenharmony_ci  const uint32_t k16BitJumpPlaceholder =
881cb0ef41Sopenharmony_ci      k8BitJumpPlaceholder | (k8BitJumpPlaceholder << 8);
891cb0ef41Sopenharmony_ci  const uint32_t k32BitJumpPlaceholder =
901cb0ef41Sopenharmony_ci      k16BitJumpPlaceholder | (k16BitJumpPlaceholder << 16);
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci  void PatchJump(size_t jump_target, size_t jump_location);
931cb0ef41Sopenharmony_ci  void PatchJumpWith8BitOperand(size_t jump_location, int delta);
941cb0ef41Sopenharmony_ci  void PatchJumpWith16BitOperand(size_t jump_location, int delta);
951cb0ef41Sopenharmony_ci  void PatchJumpWith32BitOperand(size_t jump_location, int delta);
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci  void EmitBytecode(const BytecodeNode* const node);
981cb0ef41Sopenharmony_ci  void EmitJump(BytecodeNode* node, BytecodeLabel* label);
991cb0ef41Sopenharmony_ci  void EmitJumpLoop(BytecodeNode* node, BytecodeLoopHeader* loop_header);
1001cb0ef41Sopenharmony_ci  void EmitSwitch(BytecodeNode* node, BytecodeJumpTable* jump_table);
1011cb0ef41Sopenharmony_ci  void UpdateSourcePositionTable(const BytecodeNode* const node);
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci  void UpdateExitSeenInBlock(Bytecode bytecode);
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci  void MaybeElideLastBytecode(Bytecode next_bytecode, bool has_source_info);
1061cb0ef41Sopenharmony_ci  void InvalidateLastBytecode();
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci  void StartBasicBlock();
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; }
1111cb0ef41Sopenharmony_ci  SourcePositionTableBuilder* source_position_table_builder() {
1121cb0ef41Sopenharmony_ci    return &source_position_table_builder_;
1131cb0ef41Sopenharmony_ci  }
1141cb0ef41Sopenharmony_ci  ConstantArrayBuilder* constant_array_builder() {
1151cb0ef41Sopenharmony_ci    return constant_array_builder_;
1161cb0ef41Sopenharmony_ci  }
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_ci  ZoneVector<uint8_t> bytecodes_;
1191cb0ef41Sopenharmony_ci  int unbound_jumps_;
1201cb0ef41Sopenharmony_ci  SourcePositionTableBuilder source_position_table_builder_;
1211cb0ef41Sopenharmony_ci  ConstantArrayBuilder* constant_array_builder_;
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci  Bytecode last_bytecode_;
1241cb0ef41Sopenharmony_ci  size_t last_bytecode_offset_;
1251cb0ef41Sopenharmony_ci  bool last_bytecode_had_source_info_;
1261cb0ef41Sopenharmony_ci  bool elide_noneffectful_bytecodes_;
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci  bool exit_seen_in_block_;
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci  friend class bytecode_array_writer_unittest::BytecodeArrayWriterUnittest;
1311cb0ef41Sopenharmony_ci};
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci}  // namespace interpreter
1341cb0ef41Sopenharmony_ci}  // namespace internal
1351cb0ef41Sopenharmony_ci}  // namespace v8
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci#endif  // V8_INTERPRETER_BYTECODE_ARRAY_WRITER_H_
138