Skip to content

Commit

Permalink
Implement single byte OP_WRITE_RAW instruction
Browse files Browse the repository at this point in the history
  • Loading branch information
peterzhu2118 committed Oct 16, 2020
1 parent c95ba50 commit e85d5eb
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 14 deletions.
19 changes: 16 additions & 3 deletions ext/liquid_c/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,15 @@ static VALUE block_body_remove_blank_strings(VALUE self)

while (*ip != OP_LEAVE) {
if (*ip == OP_WRITE_RAW) {
if (ip[1] || ip[2] || ip[3]) { // if (size != 0)
if (ip[1]) { // if (size != 0)
ip[0] = OP_JUMP_FWD; // effectively a no-op
body->render_score--;
}
} else if (*ip == OP_WRITE_RAW_W) {
if (ip[1] || ip[2] || ip[3]) { // if (size != 0)
ip[0] = OP_JUMP_FWD_W; // effectively a no-op
body->render_score--;
}
}
liquid_vm_next_instruction((const uint8_t **)&ip, (const size_t **)&const_ptr);
}
Expand Down Expand Up @@ -320,10 +325,18 @@ static VALUE block_body_nodelist(VALUE self)
switch (*ip) {
case OP_LEAVE:
goto loop_break;
case OP_WRITE_RAW_W:
case OP_WRITE_RAW:
{
const char *text = (const char *)&ip[4];
size_t size = bytes_to_uint24(&ip[1]);
const char *text;
size_t size;
if (*ip == OP_WRITE_RAW_W) {
size = bytes_to_uint24(&ip[1]);
text = (const char *)&ip[4];
} else {
size = ip[1];
text = (const char *)&ip[2];
}
VALUE string = rb_enc_str_new(text, size, utf8_encoding);
rb_ary_push(nodelist, string);
break;
Expand Down
36 changes: 30 additions & 6 deletions ext/liquid_c/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,22 +356,38 @@ static VALUE vm_render_until_error(VALUE uncast_args)

// Rendering instructions

case OP_WRITE_RAW_W:
case OP_WRITE_RAW:
{
const char *text = (const char *)&ip[3];
size_t size = bytes_to_uint24(ip);
const char *text;
size_t size;
if (ip[-1] == OP_WRITE_RAW_W) {
size = bytes_to_uint24(ip);
text = (const char *)&ip[3];
ip += 3 + size;
} else {
size = *ip;
text = (const char *)&ip[1];
ip += 1 + size;
}
rb_str_cat(output, text, size);
resource_limits_increment_write_score(vm->resource_limits, output);
ip += 3 + size;
break;
}
case OP_JUMP_FWD:
case OP_JUMP_FWD_W:
{
size_t size = bytes_to_uint24(ip);
ip += 3 + size;
break;
}

case OP_JUMP_FWD:
{
uint8_t size = *ip;
ip += 1 + size;
break;
}

case OP_WRITE_NODE:
rb_funcall(cLiquidBlockBody, id_render_node, 3, args->context, output, (VALUE)*const_ptr++);
if (RARRAY_LEN(vm->interrupts)) {
Expand Down Expand Up @@ -468,14 +484,22 @@ void liquid_vm_next_instruction(const uint8_t **ip_ptr, const size_t **const_ptr
(*const_ptr_ptr)++;
break;

case OP_WRITE_RAW:
case OP_JUMP_FWD:
case OP_WRITE_RAW_W:
case OP_JUMP_FWD_W:
{
size_t size = bytes_to_uint24(ip);
ip += 3 + size;
break;
}

case OP_WRITE_RAW:
case OP_JUMP_FWD:
{
uint8_t size = *ip;
ip += 1 + size;
break;
}

default:
rb_bug("invalid opcode: %u", ip[-1]);
}
Expand Down
15 changes: 11 additions & 4 deletions ext/liquid_c/vm_assembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,18 @@ void vm_assembler_gc_mark(vm_assembler_t *code)

void vm_assembler_add_write_raw(vm_assembler_t *code, const char *string, size_t size)
{
uint8_t instructions[4];
instructions[0] = OP_WRITE_RAW;
uint24_to_bytes((unsigned int)size, &instructions[1]);
if (size > UINT8_MAX) {
uint8_t instructions[4];
instructions[0] = OP_WRITE_RAW_W;
uint24_to_bytes((unsigned int)size, &instructions[1]);

c_buffer_write(&code->instructions, &instructions, sizeof(instructions));
} else {
uint8_t instructions[2] = { OP_WRITE_RAW, size };

c_buffer_write(&code->instructions, &instructions, sizeof(instructions));
}

c_buffer_write(&code->instructions, &instructions, sizeof(instructions));
c_buffer_write(&code->instructions, (char *)string, size);
}

Expand Down
4 changes: 3 additions & 1 deletion ext/liquid_c/vm_assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

enum opcode {
OP_LEAVE = 0,
OP_WRITE_RAW = 1,
OP_WRITE_RAW_W = 1,
OP_WRITE_NODE = 2,
OP_POP_WRITE_VARIABLE,
OP_PUSH_CONST,
Expand All @@ -26,6 +26,8 @@ enum opcode {
OP_HASH_NEW, // rb_hash_new & rb_hash_bulk_insert
OP_FILTER,
OP_RENDER_VARIABLE_RESCUE, // setup state to rescue variable rendering
OP_WRITE_RAW,
OP_JUMP_FWD_W,
OP_JUMP_FWD,
};

Expand Down

0 comments on commit e85d5eb

Please sign in to comment.