Block.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /*
  2. * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/String.h>
  7. #include <LibJS/Bytecode/Block.h>
  8. #include <LibJS/Bytecode/Op.h>
  9. #include <sys/mman.h>
  10. namespace JS::Bytecode {
  11. NonnullOwnPtr<Block> Block::create()
  12. {
  13. return adopt_own(*new Block);
  14. }
  15. Block::Block()
  16. {
  17. // FIXME: This is not the smartest solution ever. Find something cleverer!
  18. // The main issue we're working around here is that we don't want pointers into the bytecode stream to become invalidated
  19. // during code generation due to dynamic buffer resizing. Otherwise we could just use a Vector.
  20. m_buffer_capacity = 64 * KiB;
  21. m_buffer = (u8*)mmap(nullptr, m_buffer_capacity, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
  22. VERIFY(m_buffer != MAP_FAILED);
  23. }
  24. Block::~Block()
  25. {
  26. Bytecode::InstructionStreamIterator it(instruction_stream());
  27. while (!it.at_end()) {
  28. auto& to_destroy = (*it);
  29. ++it;
  30. Instruction::destroy(const_cast<Instruction&>(to_destroy));
  31. }
  32. }
  33. void Block::seal()
  34. {
  35. // FIXME: mprotect the instruction stream as PROT_READ
  36. // This is currently not possible because instructions can have destructors (that clean up strings)
  37. // Instructions should instead be destructor-less and refer to strings in a string table on the Bytecode::Block.
  38. }
  39. void Block::dump() const
  40. {
  41. Bytecode::InstructionStreamIterator it(instruction_stream());
  42. while (!it.at_end()) {
  43. warnln("[{:4x}] {}", it.offset(), (*it).to_string());
  44. ++it;
  45. }
  46. }
  47. void Block::grow(size_t additional_size)
  48. {
  49. m_buffer_size += additional_size;
  50. VERIFY(m_buffer_size <= m_buffer_capacity);
  51. }
  52. void InstructionStreamIterator::operator++()
  53. {
  54. m_offset += dereference().length();
  55. }
  56. }