} njs_code_name_t;
-static void njs_disassemble(njs_vm_code_t *code);
-
-
static njs_code_name_t code_names[] = {
{ NJS_VMCODE_OBJECT, sizeof(njs_vmcode_object_t),
while (n != 0) {
njs_printf("%V:%V\n", &code->file, &code->name);
- njs_disassemble(code);
+ njs_disassemble(code->start, code->end, -1, code->lines);
code++;
n--;
}
}
-static void
-njs_disassemble(njs_vm_code_t *code)
+void
+njs_disassemble(u_char *start, u_char *end, njs_int_t count, njs_arr_t *lines)
{
- u_char *p, *start, *end;
+ u_char *p;
uint32_t line;
njs_str_t *name;
njs_uint_t n;
njs_vmcode_try_trampoline_t *try_tramp;
njs_vmcode_function_frame_t *function;
- start = code->start;
- end = code->end;
-
/*
* On some 32-bit platform uintptr_t is int and compilers warn
* about %l format modifier. size_t has the size as pointer so
p = start;
- while (p < end) {
+ while (((p < end) && (count == -1)) || (count-- > 0)) {
operation = *(njs_vmcode_operation_t *) p;
- line = njs_lookup_line(code, p - start);
+ line = njs_lookup_line(lines, p - start);
if (operation == NJS_VMCODE_ARRAY) {
array = (njs_vmcode_array_t *) p;
njs_native_frame_t *native_frame)
{
njs_int_t ret;
- njs_uint_t i;
njs_vm_code_t *code;
njs_function_t *function;
njs_backtrace_entry_t *be;
return NJS_OK;
}
- code = vm->codes->start;
-
- for (i = 0; i < vm->codes->items; i++, code++) {
- if (code->start <= native_frame->pc
- && native_frame->pc < code->end)
- {
- be->name = code->name;
- be->line = njs_lookup_line(code, native_frame->pc - code->start);
- if (!vm->options.quiet) {
- be->file = code->file;
- }
+ code = njs_lookup_code(vm, native_frame->pc);
- return NJS_OK;
+ if (code != NULL) {
+ be->name = code->name;
+ be->line = njs_lookup_line(code->lines, native_frame->pc - code->start);
+ if (!vm->options.quiet) {
+ be->file = code->file;
}
+
+ return NJS_OK;
}
be->name = njs_entry_unknown;
}
+njs_vm_code_t *
+njs_lookup_code(njs_vm_t *vm, u_char *pc)
+{
+ njs_uint_t i;
+ njs_vm_code_t *code;
+
+ code = vm->codes->start;
+
+ for (i = 0; i < vm->codes->items; i++, code++) {
+ if (code->start <= pc && pc < code->end) {
+ return code;
+ }
+ }
+
+ return NULL;
+}
+
+
uint32_t
-njs_lookup_line(njs_vm_code_t *code, uint32_t offset)
+njs_lookup_line(njs_arr_t *lines, uint32_t offset)
{
njs_uint_t n;
njs_vm_line_num_t *map;
n = 0;
map = NULL;
- if (code->lines != NULL) {
- n = code->lines->items;
- map = (njs_vm_line_num_t *) code->lines->start;
+ if (lines != NULL) {
+ n = lines->items;
+ map = (njs_vm_line_num_t *) lines->start;
}
while (n != 0) {
njs_int_t depth, njs_bool_t runtime);
njs_vm_code_t *njs_generate_scope(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_scope_t *scope, const njs_str_t *name);
-uint32_t njs_lookup_line(njs_vm_code_t *code, uint32_t offset);
+njs_vm_code_t *njs_lookup_code(njs_vm_t *vm, u_char *pc);
+uint32_t njs_lookup_line(njs_arr_t *lines, uint32_t offset);
#endif /* _NJS_GENERATOR_H_INCLUDED_ */
njs_int_t njs_builtin_match_native_function(njs_vm_t *vm,
njs_function_t *function, njs_str_t *name);
+void njs_disassemble(u_char *start, u_char *end, njs_int_t count,
+ njs_arr_t *lines);
+
njs_arr_t *njs_vm_completions(njs_vm_t *vm, njs_str_t *expression);
void *njs_lvlhsh_alloc(void *data, size_t size);
} while (0)
+#ifdef NJS_OPCODE_DEBUG
+void njs_vmcode_debug(njs_vm_t *vm, u_char *pc, const char *prefix);
+#endif
+
+
njs_int_t
njs_vmcode_interpreter(njs_vm_t *vm, u_char *pc, void *promise_cap,
void *async_ctx)
njs_vmcode_try_trampoline_t *try_trampoline;
njs_vmcode_function_frame_t *function_frame;
+#ifdef NJS_OPCODE_DEBUG
+ njs_vmcode_debug(vm, pc, "ENTER");
+#endif
+
next:
for ( ;; ) {
* as a single unsigned comparision.
*/
+#ifdef NJS_OPCODE_DEBUG
+ njs_disassemble(pc, NULL, 1, NULL);
+#endif
+
if (op > NJS_VMCODE_NORET) {
if (op == NJS_VMCODE_MOVE) {
njs_vmcode_operand(vm, (njs_index_t) value2, value2);
vm->retval = *value2;
+#ifdef NJS_OPCODE_DEBUG
+ njs_vmcode_debug(vm, pc, "EXIT STOP");
+#endif
+
return NJS_OK;
case NJS_VMCODE_JUMP:
case NJS_VMCODE_RETURN:
njs_vmcode_operand(vm, (njs_index_t) value2, value2);
+
+#ifdef NJS_OPCODE_DEBUG
+ njs_vmcode_debug(vm, pc, "EXIT RETURN");
+#endif
+
return njs_vmcode_return(vm, NULL, value2);
case NJS_VMCODE_FUNCTION_COPY:
case NJS_VMCODE_AWAIT:
await = (njs_vmcode_await_t *) pc;
+
+#ifdef NJS_OPCODE_DEBUG
+ njs_vmcode_debug(vm, pc, "EXIT AWAIT");
+#endif
+
return njs_vmcode_await(vm, await, promise_cap, async_ctx);
case NJS_VMCODE_TRY_START:
switch (ret) {
case NJS_OK:
+
+#ifdef NJS_OPCODE_DEBUG
+ njs_vmcode_debug(vm, pc, "EXIT FINALLY");
+#endif
+
return NJS_OK;
case NJS_ERROR:
goto error;
}
}
+#ifdef NJS_OPCODE_DEBUG
+ njs_vmcode_debug(vm, pc, "EXIT ERROR");
+#endif
+
return NJS_ERROR;
}
njs_error_fmt_new(vm, &vm->retval, err->type, "%V", &err->u.message);
}
}
+
+
+#ifdef NJS_OPCODE_DEBUG
+void
+njs_vmcode_debug(njs_vm_t *vm, u_char *pc, const char *prefix)
+{
+ njs_vm_code_t *code;
+
+ code = njs_lookup_code(vm, pc);
+
+ njs_printf("%s %V\n", prefix,
+ (code != NULL) ? &code->name : &njs_entry_unknown);
+}
+#endif