void main() { int v,a=5,val; v=fun1(a); val=fun2(v); printf("fun1:%d\n",v); printf("func2:%d\n",val); funstr(); }
void err_explain(int err, lframe_t *frame) { lclosure_t *caller; lfunc_t *func; lframe_t *caller_frame = frame; assert(frame != NULL); while (caller_frame->closure->type != LUAF_LUA) { assert(caller_frame->caller != NULL); assert(caller_frame->caller != caller_frame); caller_frame = caller_frame->caller; } caller = caller_frame->closure; func = caller->function.lua; int len = 0; u32 pc = GETPC(caller_frame, func); /* TODO: this is a result of JIT code not updating its PC, we should change in the JIT code? */ pc -= !!pc; /* Figure out debug information from the luac file of where the call came from (source line) */ assert(pc < func->num_lines); switch (err) { case ERR_MISSING: len = sprintf(err_desc, "%.25s:%u: bad argument #%d to '%s' (%s expected, " "got no value)", func->file, func->lines[pc], err_info[0] + 1, funstr(vm_running->closure), err_typestr(err_info[1])); break; case ERR_BADTYPE: len = sprintf(err_desc, "%.25s:%u: bad argument #%d to '%s' (%s expected, got %s)", func->file, func->lines[pc], err_info[0] + 1, funstr(vm_running->closure), err_typestr(err_info[1]), err_typestr(err_info[2])); break; case ERR_STR: len = sprintf(err_desc, "%.25s:%u: bad argument #%d to '%s' (%s)", func->file, func->lines[pc], err_info[0] + 1, funstr(vm_running->closure), err_custom); break; case ERR_RAWSTR: if (err_info[0]) { len = sprintf(err_desc, "%.25s:%u: %s", func->file, func->lines[pc], err_custom); } else { len = sprintf(err_desc, "%s", err_custom); } break; case ERR_LUAV: if (err_catcher) { if (lv_isstring(err_value) && frame->closure->type == LUAF_LUA) { len = sprintf(err_desc, "%.25s:%u: %s", func->file, func->lines[pc], lv_caststring(err_value, 0)->data); err_desc[len] = 0; err_value = lv_string(lstr_literal(err_desc, FALSE)); } } else { len = sprintf(err_desc, "(error object is not a string)"); } break; default: panic("Unknown error type: %d", err); } if (err_catcher != NULL) { if (err != ERR_LUAV) { err_desc[len] = 0; err_value = lv_string(lstr_literal(err_desc, FALSE)); } _longjmp(*err_catcher, 1); } assert(lua_program != NULL); printf("%s: %s\n", lua_program, err_desc); printf("stack traceback:\n"); while (frame != NULL) { lclosure_t *closure = frame->closure; printf("\t"); if (closure->type == LUAF_C) { printf("[C]: in function '%s'", closure->function.c->name); } else { lfunc_t *function = closure->function.lua; pc = GETPC(frame, function); pc -= !!pc; assert(pc < function->num_lines); printf("%s:%d: ", function->file, function->lines[pc]); lstring_t *fname = function->name; if (fname->length == 0) { printf("in function <%s:%d>", function->file, function->start_line); } else if (fname->data[0] == '@') { printf("in main chunk"); } else { printf("in function '%.*s'", (int) fname->length, fname->data); } } printf("\n"); frame = frame->caller; } exit(1); }