Skip to content

Commit d28a941

Browse files
committed
store constant index in instruction
1 parent 87a5385 commit d28a941

File tree

9 files changed

+214
-78
lines changed

9 files changed

+214
-78
lines changed

ext/liquid_c/block.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,6 @@ static VALUE block_body_remove_blank_strings(VALUE self)
365365
rb_raise(rb_eRuntimeError, "remove_blank_strings only support being called on a blank block body");
366366
}
367367

368-
VALUE *const_ptr = (VALUE *)body->as.intermediate.code->constants.data;
369368
uint8_t *ip = body->as.intermediate.code->instructions.data;
370369

371370
while (*ip != OP_LEAVE) {
@@ -380,7 +379,7 @@ static VALUE block_body_remove_blank_strings(VALUE self)
380379
body->as.intermediate.render_score--;
381380
}
382381
}
383-
liquid_vm_next_instruction((const uint8_t **)&ip, (const VALUE **)&const_ptr);
382+
liquid_vm_next_instruction((const uint8_t **)&ip);
384383
}
385384

386385
return Qnil;
@@ -410,7 +409,7 @@ static VALUE block_body_nodelist(VALUE self)
410409

411410
VALUE nodelist = rb_ary_new_capa(body_header->render_score);
412411

413-
const VALUE *const_ptr = document_body_get_constants_ptr(entry);
412+
const VALUE *constants = &entry->body->constants;
414413
const uint8_t *ip = block_body_instructions_ptr(body_header);
415414
while (true) {
416415
switch (*ip) {
@@ -434,15 +433,17 @@ static VALUE block_body_nodelist(VALUE self)
434433
}
435434
case OP_WRITE_NODE:
436435
{
437-
rb_ary_push(nodelist, const_ptr[0]);
436+
uint16_t constant_index = (ip[1] << 8) | ip[2];
437+
VALUE node = RARRAY_AREF(*constants, constant_index);
438+
rb_ary_push(nodelist, node);
438439
break;
439440
}
440441

441442
case OP_RENDER_VARIABLE_RESCUE:
442443
rb_ary_push(nodelist, variable_placeholder);
443444
break;
444445
}
445-
liquid_vm_next_instruction(&ip, &const_ptr);
446+
liquid_vm_next_instruction(&ip);
446447
}
447448
loop_break:
448449

@@ -458,8 +459,11 @@ static VALUE block_body_disassemble(VALUE self)
458459
document_body_entry_t *entry = &body->as.compiled.document_body_entry;
459460
block_body_header_t *header = document_body_get_block_body_header_ptr(entry);
460461
const uint8_t *start_ip = block_body_instructions_ptr(header);
461-
return vm_assembler_disassemble(start_ip, start_ip + header->instructions_bytes,
462-
document_body_get_constants_ptr(entry));
462+
return vm_assembler_disassemble(
463+
start_ip,
464+
start_ip + header->instructions_bytes,
465+
&entry->body->constants
466+
);
463467
}
464468

465469

ext/liquid_c/expression.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,16 @@ static VALUE expression_disassemble(VALUE self)
9494
{
9595
expression_t *expression;
9696
Expression_Get_Struct(self, expression);
97-
return vm_assembler_disassemble(expression->code.instructions.data, expression->code.instructions.data_end,
98-
(const VALUE *)expression->code.constants.data);
97+
98+
VALUE constants = rb_ary_new();
99+
uint32_t constants_len = (uint32_t)(c_buffer_size(&expression->code.constants) / sizeof(VALUE));
100+
rb_ary_cat(constants, (VALUE *)expression->code.constants.data, constants_len);
101+
102+
return vm_assembler_disassemble(
103+
expression->code.instructions.data,
104+
expression->code.instructions.data_end,
105+
&constants
106+
);
99107
}
100108

101109
void liquid_define_expression(void)

ext/liquid_c/variable.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,18 @@ static VALUE variable_strict_parse_rescue(VALUE uncast_args, VALUE exception)
9696
vm_assembler_t *code = parse_args->code;
9797

9898
// undo partial strict parse
99+
uint8_t *last_constants_data_end = (uint8_t *)code->constants.data + rescue_args->constants_size;
100+
VALUE *const_ptr = (VALUE *)last_constants_data_end;
101+
st_table *constants_table = code->constants_table;
102+
103+
while((uint8_t *)const_ptr < code->constants.data_end) {
104+
st_data_t key = (st_data_t)const_ptr[0];
105+
st_delete(constants_table, &key, 0);
106+
const_ptr++;
107+
}
108+
99109
code->instructions.data_end = code->instructions.data + rescue_args->instructions_size;
100-
code->constants.data_end = code->constants.data + rescue_args->constants_size;
110+
code->constants.data_end = last_constants_data_end;
101111
code->stack_size = rescue_args->stack_size;
102112

103113
if (rb_obj_is_kind_of(exception, cLiquidSyntaxError) == Qfalse)

ext/liquid_c/vm.c

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -231,20 +231,18 @@ static void hash_bulk_insert(long argc, const VALUE *argv, VALUE hash)
231231
static VALUE vm_render_until_error(VALUE uncast_args)
232232
{
233233
vm_render_until_error_args_t *args = (void *)uncast_args;
234-
const VALUE *const_ptr = args->const_ptr;
234+
const VALUE *constants = args->const_ptr;
235235
const uint8_t *ip = args->ip;
236236
vm_t *vm = args->vm;
237237
VALUE output = args->output;
238+
uint16_t constant_index;
239+
VALUE constant = Qnil;
238240
args->ip = NULL; // used by vm_render_rescue, NULL to indicate that it isn't in a rescue block
239241

240242
while (true) {
241243
switch (*ip++) {
242244
case OP_LEAVE:
243245
return false;
244-
245-
case OP_PUSH_CONST:
246-
vm_stack_push(vm, *const_ptr++);
247-
break;
248246
case OP_PUSH_NIL:
249247
vm_stack_push(vm, Qnil);
250248
break;
@@ -268,8 +266,14 @@ static VALUE vm_render_until_error(VALUE uncast_args)
268266
break;
269267
}
270268
case OP_FIND_STATIC_VAR:
271-
vm_stack_push(vm, *const_ptr++);
272-
/* fallthrough */
269+
{
270+
constant_index = (ip[0] << 8) | ip[1];
271+
constant = constants[constant_index];
272+
ip += 2;
273+
VALUE value = context_find_variable(&vm->context, constant, Qtrue);
274+
vm_stack_push(vm, value);
275+
break;
276+
}
273277
case OP_FIND_VAR:
274278
{
275279
VALUE key = vm_stack_pop(vm);
@@ -279,11 +283,16 @@ static VALUE vm_render_until_error(VALUE uncast_args)
279283
}
280284
case OP_LOOKUP_CONST_KEY:
281285
case OP_LOOKUP_COMMAND:
282-
vm_stack_push(vm, *const_ptr++);
283-
/* fallthrough */
286+
{
287+
constant_index = (ip[0] << 8) | ip[1];
288+
constant = constants[constant_index];
289+
ip += 2;
290+
vm_stack_push(vm, constant);
291+
}
292+
/* fallthrough */
284293
case OP_LOOKUP_KEY:
285294
{
286-
bool is_command = ip[-1] == OP_LOOKUP_COMMAND;
295+
bool is_command = ip[-3] == OP_LOOKUP_COMMAND;
287296
VALUE key = vm_stack_pop(vm);
288297
VALUE object = vm_stack_pop(vm);
289298
VALUE result = variable_lookup_key(vm->context.self, object, key, is_command);
@@ -313,13 +322,20 @@ static VALUE vm_render_until_error(VALUE uncast_args)
313322
case OP_BUILTIN_FILTER:
314323
{
315324
VALUE filter_name;
325+
uint8_t num_args;
326+
316327
if (ip[-1] == OP_FILTER) {
317-
filter_name = *const_ptr++;
328+
constant_index = (ip[0] << 8) | ip[1];
329+
constant = constants[constant_index];
330+
filter_name = RARRAY_AREF(constant, 0);
331+
num_args = RARRAY_AREF(constant, 1);
332+
ip += 2;
318333
} else {
319334
assert(ip[-1] == OP_BUILTIN_FILTER);
320335
filter_name = builtin_filters[*ip++].sym;
336+
num_args = *ip++; // includes input argument
321337
}
322-
uint8_t num_args = *ip++; // includes input argument
338+
323339
VALUE *args_ptr = vm_stack_pop_n_use_in_place(vm, num_args);
324340
VALUE result = vm_invoke_filter(vm, filter_name, num_args, args_ptr);
325341
vm_stack_push(vm, result);
@@ -360,21 +376,36 @@ static VALUE vm_render_until_error(VALUE uncast_args)
360376
break;
361377
}
362378

379+
case OP_PUSH_CONST:
380+
{
381+
constant_index = (ip[0] << 8) | ip[1];
382+
constant = constants[constant_index];
383+
ip += 2;
384+
vm_stack_push(vm, constant);
385+
break;
386+
}
387+
363388
case OP_WRITE_NODE:
364-
rb_funcall(cLiquidBlockBody, id_render_node, 3, vm->context.self, output, (VALUE)*const_ptr++);
389+
{
390+
constant_index = (ip[0] << 8) | ip[1];
391+
constant = constants[constant_index];
392+
ip += 2;
393+
rb_funcall(cLiquidBlockBody, id_render_node, 3, vm->context.self, output, constant);
394+
365395
if (RARRAY_LEN(vm->context.interrupts)) {
366396
return false;
367397
}
398+
368399
resource_limits_increment_write_score(vm->context.resource_limits, output);
369400
break;
401+
}
370402
case OP_RENDER_VARIABLE_RESCUE:
371403
// Save state used by vm_render_rescue to rescue from a variable rendering exception
372404
args->node_line_number = ip;
373405
// vm_render_rescue will iterate from this instruction to the instruction
374406
// following OP_POP_WRITE_VARIABLE to resume rendering from
375407
ip += 3;
376408
args->ip = ip;
377-
args->const_ptr = const_ptr;
378409
break;
379410
case OP_POP_WRITE:
380411
{
@@ -414,7 +445,7 @@ VALUE liquid_vm_evaluate(VALUE context, vm_assembler_t *code)
414445
return ret;
415446
}
416447

417-
void liquid_vm_next_instruction(const uint8_t **ip_ptr, const VALUE **const_ptr_ptr)
448+
void liquid_vm_next_instruction(const uint8_t **ip_ptr)
418449
{
419450
const uint8_t *ip = *ip_ptr;
420451

@@ -436,26 +467,19 @@ void liquid_vm_next_instruction(const uint8_t **ip_ptr, const VALUE **const_ptr_
436467

437468
case OP_BUILTIN_FILTER:
438469
case OP_PUSH_INT16:
439-
ip += 2;
440-
break;
441-
442-
case OP_WRITE_NODE:
443470
case OP_PUSH_CONST:
471+
case OP_WRITE_NODE:
444472
case OP_FIND_STATIC_VAR:
445473
case OP_LOOKUP_CONST_KEY:
446474
case OP_LOOKUP_COMMAND:
447-
(*const_ptr_ptr)++;
475+
case OP_FILTER:
476+
ip += 2;
448477
break;
449478

450479
case OP_RENDER_VARIABLE_RESCUE:
451480
ip += 3;
452481
break;
453482

454-
case OP_FILTER:
455-
ip++;
456-
(*const_ptr_ptr)++;
457-
break;
458-
459483
case OP_WRITE_RAW_W:
460484
case OP_JUMP_FWD_W:
461485
{
@@ -514,7 +538,7 @@ static VALUE vm_render_rescue(VALUE uncast_args, VALUE exception)
514538
enum opcode last_op;
515539
do {
516540
last_op = *ip;
517-
liquid_vm_next_instruction(&ip, &render_args->const_ptr);
541+
liquid_vm_next_instruction(&ip);
518542
} while (last_op != OP_POP_WRITE);
519543
render_args->ip = ip;
520544
// remove temporary stack values from variable evaluation

ext/liquid_c/vm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ typedef struct vm {
1515
void liquid_define_vm(void);
1616
vm_t *vm_from_context(VALUE context);
1717
void liquid_vm_render(block_body_header_t *block, const VALUE *const_ptr, VALUE context, VALUE output);
18-
void liquid_vm_next_instruction(const uint8_t **ip_ptr, const size_t **const_ptr_ptr);
18+
void liquid_vm_next_instruction(const uint8_t **ip_ptr);
1919
bool liquid_vm_filtering(VALUE context);
2020
VALUE liquid_vm_evaluate(VALUE context, vm_assembler_t *code);
2121

0 commit comments

Comments
 (0)