Skip to content

Instantly share code, notes, and snippets.

@feliwir
Last active November 16, 2023 09:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save feliwir/5b1b8313358d7ccc66ca26a0a5449648 to your computer and use it in GitHub Desktop.
Save feliwir/5b1b8313358d7ccc66ca26a0a5449648 to your computer and use it in GitHub Desktop.
5:a8 SetVariable env:Lexical init:Set 6 (n):
0x00007f33e5c964c5 be b0 92 a8 00 mov esi, 0x00a892b0
0x00007f33e5c964ca 4c 89 e2 mov rdx,r12
0x00007f33e5c964cd 41 b9 a4 91 a8 00 mov r9d, 0x00a891a4
0x00007f33e5c964d3 41 0f b6 41 08 movzx eax,[r9+0x8]
0x00007f33e5c964d8 48 85 c0 test rax,rax
0x00007f33e5c964db 0f 84 59 00 00 00 jz near e5c9653a <5:a8+0x75>
0x00007f33e5c964e1 49 8b 4f 20 mov rcx,[r15+0x20]
0x00007f33e5c964e5 8b 02 mov eax,[rdx]
0x00007f33e5c964e7 48 85 c0 test rax,rax
0x00007f33e5c964ea 0f 84 0d 00 00 00 jz near e5c964fd <5:a8+0x38>
0x00007f33e5c964f0 48 83 e8 01 sub rax,0x01
0x00007f33e5c964f4 48 8b 49 10 mov rcx,[rcx+0x10]
0x00007f33e5c964f8 e9 ea ff ff ff jmp e5c964e7 <5:a8+0x22>
0x00007f33e5c964fd 0f b6 41 09 movzx eax,[rcx+0x9]
0x00007f33e5c96501 48 85 c0 test rax,rax
0x00007f33e5c96504 0f 85 30 00 00 00 jnz near e5c9653a <5:a8+0x75>
0x00007f33e5c9650a 48 8b 49 28 mov rcx,[rcx+0x28]
0x00007f33e5c9650e 8b 42 04 mov eax,[rdx+0x4]
0x00007f33e5c96511 6b c0 18 imul eax,eax,0x18
0x00007f33e5c96514 0f 80 20 00 00 00 jo near e5c9653a <5:a8+0x75>
0x00007f33e5c9651a 48 01 c1 add rcx,rax
0x00007f33e5c9651d 48 8b 41 13 mov rax,[rcx+0x13]
0x00007f33e5c96521 48 81 e0 ff 00 00 00 and rax,0x000000ff
0x00007f33e5c96528 48 85 c0 test rax,rax
0x00007f33e5c9652b 0f 84 09 00 00 00 jz near e5c9653a <5:a8+0x75>
0x00007f33e5c96531 48 89 51 08 mov [rcx+0x8],rdx
0x00007f33e5c96535 e9 33 00 00 00 jmp e5c9656d <5:d8>
0x00007f33e5c9653a 31 c9 xor ecx,ecx
0x00007f33e5c9653c 41 b8 01 00 00 00 mov r8d, 0x00000001
0x00007f33e5c96542 57 push rdi
0x00007f33e5c96543 6a 00 push 0x00
0x00007f33e5c96545 48 b8 c0 83 87 e5 33 mov rax, 0x00007f33e58783c0
0x00007f33e5c9654c 7f 00 00
0x00007f33e5c9654f ff d0 call eax
0x00007f33e5c96551 48 83 c4 08 add rsp,0x08
0x00007f33e5c96555 5f pop rdi
0x00007f33e5c96556 48 8b 43 10 mov rax,[rbx+0x10]
0x00007f33e5c9655a 48 b9 00 00 00 00 00 mov rcx, 0x7ffb000000000000
0x00007f33e5c96561 00 fb 7f
0x00007f33e5c96564 48 39 c8 cmp rax,rcx
0x00007f33e5c96567 0f 85 11 00 00 00 jnz near e5c9657e <common_exit>
void Compiler::compile_set_variable(Bytecode::Op::SetVariable const& op)
{
Assembler::Label slow_case;
// Load the identifier in ARG1 for both cases
m_assembler.mov(
Assembler::Operand::Register(ARG1),
Assembler::Operand::Imm(bit_cast<u64>(&m_bytecode_executable.get_identifier(op.identifier().value()))));
// Load the value in ARG2 for both cases
load_accumulator(ARG2);
// if (!cache.has_value()) goto slow_case;
m_assembler.mov(
Assembler::Operand::Register(ARG5),
Assembler::Operand::Imm(bit_cast<u64>(&m_bytecode_executable.environment_variable_caches[op.cache_index()])));
m_assembler.mov8(
Assembler::Operand::Register(GPR0),
Assembler::Operand::Mem64BaseAndOffset(ARG5, Bytecode::EnvironmentVariableCache::has_value_offset()));
m_assembler.jump_if(
Assembler::Operand::Register(GPR0),
Assembler::Condition::EqualTo,
Assembler::Operand::Imm(0),
slow_case);
if (op.mode() == Bytecode::Op::EnvironmentMode::Lexical) {
// auto environment = vm.running_execution_context().lexical_environment;
// GPR1 = current lexical environment
m_assembler.mov(
Assembler::Operand::Register(GPR1),
Assembler::Operand::Mem64BaseAndOffset(RUNNING_EXECUTION_CONTEXT_BASE, ExecutionContext::lexical_environment_offset()));
} else {
// auto environment = vm.running_execution_context().variable_environment;
// GPR1 = current variable environment
m_assembler.mov(
Assembler::Operand::Register(GPR1),
Assembler::Operand::Mem64BaseAndOffset(RUNNING_EXECUTION_CONTEXT_BASE, ExecutionContext::variable_environment_offset()));
}
// for (size_t i = 0; i < cache->hops; ++i)
// environment = environment->outer_environment();
// GPR0 = hops
m_assembler.mov32(
Assembler::Operand::Register(GPR0),
Assembler::Operand::Mem64BaseAndOffset(ARG2, Bytecode::EnvironmentVariableCache::value_offset() + EnvironmentCoordinate::hops_offset()));
{
// while (GPR0--)
// GPR1 = GPR1->outer_environment()
Assembler::Label loop_start;
Assembler::Label loop_end;
loop_start.link(m_assembler);
m_assembler.jump_if(
Assembler::Operand::Register(GPR0),
Assembler::Condition::EqualTo,
Assembler::Operand::Imm(0),
loop_end);
m_assembler.sub(
Assembler::Operand::Register(GPR0),
Assembler::Operand::Imm(1));
m_assembler.mov(
Assembler::Operand::Register(GPR1),
Assembler::Operand::Mem64BaseAndOffset(GPR1, Environment::outer_environment_offset()));
m_assembler.jump(loop_start);
loop_end.link(m_assembler);
}
// GPR1 now points to the environment holding our binding.
// if (environment->is_permanently_screwed_by_eval()) goto slow_case;
m_assembler.mov8(
Assembler::Operand::Register(GPR0),
Assembler::Operand::Mem64BaseAndOffset(GPR1, Environment::is_permanently_screwed_by_eval_offset()));
m_assembler.jump_if(
Assembler::Operand::Register(GPR0),
Assembler::Condition::NotEqualTo,
Assembler::Operand::Imm(0),
slow_case);
// GPR1 = environment->m_bindings.outline_buffer()
m_assembler.mov(
Assembler::Operand::Register(GPR1),
Assembler::Operand::Mem64BaseAndOffset(GPR1, DeclarativeEnvironment::bindings_offset() + Vector<DeclarativeEnvironment::Binding>::outline_buffer_offset()));
// GPR0 = index
m_assembler.mov32(
Assembler::Operand::Register(GPR0),
Assembler::Operand::Mem64BaseAndOffset(ARG2, Bytecode::EnvironmentVariableCache::value_offset() + EnvironmentCoordinate::index_offset()));
// GPR0 *= sizeof(DeclarativeEnvironment::Binding)
m_assembler.mul32(
Assembler::Operand::Register(GPR0),
Assembler::Operand::Imm(sizeof(DeclarativeEnvironment::Binding)),
slow_case);
// GPR1 = &binding
m_assembler.add(
Assembler::Operand::Register(GPR1),
Assembler::Operand::Register(GPR0));
// if (!binding.initialized) goto slow_case;
m_assembler.mov(
Assembler ::Operand::Register(GPR0),
Assembler::Operand::Mem64BaseAndOffset(GPR1, DeclarativeEnvironment::Binding::initialized_offset()));
m_assembler.bitwise_and(
Assembler::Operand::Register(GPR0),
Assembler::Operand::Imm(0xff));
m_assembler.jump_if(
Assembler::Operand::Register(GPR0),
Assembler::Condition::EqualTo,
Assembler::Operand::Imm(0),
slow_case);
// binding.value = accumulator;
m_assembler.mov(
Assembler::Operand::Mem64BaseAndOffset(GPR1, DeclarativeEnvironment::Binding::value_offset()),
Assembler::Operand::Register(ARG2));
Assembler::Label end;
m_assembler.jump(end);
// Slow case: Uncached access. Call C++ helper.
slow_case.link(m_assembler);
m_assembler.mov(
Assembler::Operand::Register(ARG3),
Assembler::Operand::Imm(to_underlying(op.mode())));
m_assembler.mov(
Assembler::Operand::Register(ARG4),
Assembler::Operand::Imm(to_underlying(op.initialization_mode())));
native_call((void*)cxx_set_variable);
check_exception();
end.link(m_assembler);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment