void knh_throw(CTX ctx, ksfp_t *sfp, long start) { if(IS_Exception(ctx->e)) { ksfp_t *sp = (sfp == NULL) ? ctx->esp : sfp + start; kExceptionHandler *hdr = ctx->ehdrNC; if((ctx->e)->uline == 0) { (ctx->e)->uline = knh_stack_uline(ctx, sfp); } while(ctx->stack <= sp) { if(sp[0].mtdNC != NULL && isCalledMethod(ctx, sp)) { knh_Exception_addStackTrace(ctx, ctx->e, sp+1); sp[0].mtdNC = 0; } if(sp[0].hdr == hdr) { size_t i = 0, size = knh_Array_size(hdr->stacklist); for(i = 0; i < size; i++) { kObject *o = knh_Array_n(hdr->stacklist, i); O_cTBL(o)->cdef->checkout(ctx, RAWPTR(o), 1); } kArrayrimSize(ctx, hdr->stacklist, 0); #ifdef K_USING_SETJMP_ knh_longjmp(DP(hdr)->jmpbuf, 1); #else knh_ExceptionHandler_longjmp(ctx, hdr); #endif goto L_NOCATCH; } sp--; } L_NOCATCH:; knh_write_Object(ctx, KNH_STDERR, UPCAST(ctx->e), FMT_dump); knh_exit(ctx, 0); } }
static void knh_stack_writeStackTrace(Ctx *ctx, knh_sfp_t *sfp, knh_OutputStream_t *w) { knh_Method_t *mtd = sfp[K_MTDIDX].callmtd; knh_write_sname(ctx, w, DP(mtd)->cid); if(DP(mtd)->mn != MN_LAMBDA) { int i = 0, psize = knh_Method_psize(mtd); knh_putc(ctx, w, '.'); knh_write_mn(ctx, w, DP(mtd)->mn); knh_putc(ctx, w, '('); for(i = 0; i < psize; i++) { knh_param_t *p = knh_ParamArray_get(DP(mtd)->mp, i); knh_type_t type = knh_type_tocid(ctx, p->type, knh_Object_cid(sfp[0].o)); if(i > 0) { knh_putc(ctx, w, ','); } knh_write_fn(ctx, w, p->fn); knh_putc(ctx, w, '='); if(!knh_write_ndata(ctx, w, type, sfp[i+1].data)) { knh_Method_t *mtdf = knh_getSystemFormatter(ctx, type, MN__k); knh_write_Object(ctx, w, ctx->esp, &mtdf, sfp[i+1].o); } } knh_putc(ctx, w, ')'); } }
static void knh_shell(CTX ctx) { void *shell_status = NULL; BEGIN_LOCAL(ctx, lsfp, 2); // LOCAL_NEW(ctx, lsfp, 0, kInputStream *, bin, new_BytesInputStream(ctx, new_Bytes(ctx, "shell", K_PAGESIZE))); { CWB_t cwbbuf, *cwb = CWB_open(ctx, &cwbbuf); knh_showWelcome(ctx, cwb->w); knh_showSecurityAlert(ctx, cwb->w); shell_status = shell_init(ctx, CWB_totext(ctx, cwb), NULL); CWB_close(ctx, cwb); } while(1) { { CWB_t cwbbuf, *cwb = CWB_open(ctx, &cwbbuf); kstatus_t status = readstmt(ctx, cwb); if(status == K_BREAK) { CWB_close(ctx, cwb); break; } if(CWB_size(cwb) == 0) { CWB_close(ctx, cwb); continue; } status = shell_command(ctx, CWB_totext(ctx, cwb)); if(status == K_BREAK) { CWB_close(ctx, cwb); break; } if(status == K_REDO) { CWB_close(ctx, cwb); continue; } #ifdef K_USING_SUGAR kString *script = CWB_newString(ctx, cwb, 0); KNH_SETv(ctx, lsfp[0].o, script); knh_beval2(ctx, S_totext(script), 1); #else kInputStream *bin = new_BytesInputStream(ctx, CWB_totext(ctx, cwb), CWB_size(cwb)); KNH_SETv(ctx, lsfp[0].o, bin); knh_beval(ctx, bin, 1); #endif } knh_OutputStream_flush(ctx, ctx->out); if(ctx->isEvaled == 1) { CWB_t cwbbuf, *cwb = CWB_open(ctx, &cwbbuf); knh_write_Object(ctx, cwb->w, ctx->evaled, FMT_dump); knh_showSecurityAlert(ctx, cwb->w); if(CWB_size(cwb) !=0) { shell_display(ctx, shell_status, CWB_totext(ctx, cwb)); } CWB_close(ctx, cwb); WCTX(ctx)->isEvaled = 0; } } shell_cleanup(ctx, shell_status); END_LOCAL(ctx, lsfp); }
void knh_write_sfp(CTX ctx, kOutputStream *w, ktype_t type, ksfp_t *sfp, int level) { if(IS_Tunbox(type)) { if(IS_Tint(type)) { knh_write_ifmt(ctx, w, KINT_FMT, sfp[0].ivalue); } else if(IS_Tfloat(type)) { knh_write_ffmt(ctx, w, KFLOAT_FMT, sfp[0].fvalue); } else { knh_write_bool(ctx, w, sfp[0].bvalue); } } else { knh_write_Object(ctx, w, sfp[0].o, level); } }
void knh_throw(Ctx *ctx, knh_sfp_t *sfp, long start) { if(IS_Exception(ctx->e)) { knh_sfp_t *sp = (sfp == NULL) ? ctx->esp : sfp + start; while(ctx->stack <= sp) { DBG_P("[%d] cid=%s ivalue=%lld", (sp - ctx->stack), CLASS__(knh_Object_cid(sp[0].o)), sp[0].ivalue); if(sp[0].callmtd != NULL && isCalledMethod(ctx, sp)) { sp = knh_Exception_addStackTrace(ctx, ctx->e, sp+1); } if(IS_ExceptionHandler(sp[0].hdr) && DP(sp[0].hdr)->return_address != NULL) { knh_ExceptionHandler_longjmp(ctx, sp[0].hdr); goto L_NOCATCH; } sp--; } L_NOCATCH:; { knh_Method_t *mtdf = knh_getSystemFormatter(ctx, CLASS_Exception, MN__dump); knh_write_Object(ctx, KNH_STDERR, sfp, &mtdf, UPCAST(ctx->e)); } knh_exit(ctx, 0); } }
void knh_vprintf(Ctx *ctx, knh_OutputStream_t *w, const char *fmt, va_list ap) { knh_valist_t args[10]; const char *c = fmt; int i, ch, bindex = 0, bindex_max = 10; for(i = 0; i < bindex_max; i++) args[i].atype = 0; while((ch = *c) != '\0') { c++; if(ch == '%') { int index; ch = *c; if(ch == '%') { c++; continue; } index = bindex++; c = knh_vprintf_parseindex(c++, &index); //DBG_P("bindex=%d, index=%d", bindex, index); switch(ch) { case 'd': case 'u': args[index].atype = VA_DIGIT; break; case 'l': case 'i': args[index].atype = VA_LONG; break; case 'f': case 'e': args[index].atype = VA_FLOAT; break; case 's': args[index].atype = VA_CHAR; break; case 'p': args[index].atype = VA_POINTER; break; case 'L': case 'K': case 'k': case 'O': case 'o': args[index].atype = VA_OBJECT; break; case 'N': case 'F': args[index].atype = VA_FIELDN; break; case 'M': args[index].atype = VA_METHODN; break; case 'C': args[index].atype = VA_CLASS; break; case 'T': args[index].atype = VA_TYPE; break; case 'B': args[index].atype = VA_BYTES; break; // TODO // we should care if "fmt" has "%%". // sometimes, next args is NULL. case '%': index--; c++; default: bindex--; } if(bindex == 10) { DBG_ASSERT(bindex < 10); break; } } } for(i = 0; i < 10; i++) { switch(args[i].atype) { case VA_DIGIT: args[i].dvalue = (knh_intptr_t)va_arg(ap, knh_intptr_t); break; case VA_LONG: args[i].ivalue = (knh_int_t)va_arg(ap, knh_int_t); break; case VA_FLOAT: #if defined(K_USING_NOFLOAT) args[i].fvalue = (knh_float_t)va_arg(ap, knh_float_t); #else args[i].fvalue = (knh_float_t)va_arg(ap, double); #endif break; case VA_CHAR: args[i].svalue = (char*)va_arg(ap, char*); break; case VA_POINTER: args[i].pvalue = (void*)va_arg(ap, void*); break; case VA_OBJECT: args[i].ovalue = (Object*)va_arg(ap, Object*); break; case VA_FIELDN: args[i].fn = (knh_fieldn_t)va_arg(ap, int/*knh_fieldn_t*/); break; case VA_METHODN: args[i].mn = (knh_methodn_t)va_arg(ap, int/*knh_methodn_t*/); break; case VA_CLASS: args[i].cid = (knh_class_t)va_arg(ap, int/*knh_class_t*/); break; case VA_TYPE: args[i].type = (knh_type_t)va_arg(ap, int/*knh_type_t*/); break; case VA_BYTES: args[i].bvalue = (knh_bytes_t)va_arg(ap, knh_bytes_t); break; default: bindex_max = i; goto L_FORMAT; } } L_FORMAT: { knh_bytes_t b; knh_Method_t *mtd = NULL; knh_sfp_t *esp = ctx->esp; c = fmt; bindex = 0; b.text = c; b.len = 0; while((ch = *c) != '\0') { c++; if(ch == '\\') { if(b.len > 0) { knh_print(ctx, w, b); } ch = *c; switch(ch) { case '\0' : return ; case 'n': knh_println(ctx, w, STEXT("")); break; case 't': knh_write_TAB(ctx, w); break; default: knh_putc(ctx, w, '\\'); knh_putc(ctx, w, ch); } b.text = c; b.len = 0; } else if(ch == '%') { if(b.len > 0) { knh_print(ctx, w, b); } ch = *c; if(ch == '%') { knh_putc(ctx, w, '%'); c++; b.text = c; b.len = 0; continue; } int index = bindex++; c = knh_vprintf_parseindex(++c, &index); switch(ch) { case '\0' : return ; case 'd': DBG_ASSERT(args[index].atype == VA_DIGIT); knh_write_dfmt(ctx, w, K_INTPTR_FMT, args[index].dvalue); break; case 'u': DBG_ASSERT(args[index].atype == VA_DIGIT); knh_write_dfmt(ctx, w, K_INTPTR_UFMT, args[index].uvalue); break; case 'l': case 'i' : DBG_ASSERT(args[index].atype == VA_LONG); knh_write_ifmt(ctx, w, K_INT_FMT, args[index].ivalue); break; case 'f': DBG_ASSERT(args[index].atype == VA_FLOAT); knh_write_ffmt(ctx, w, K_FLOAT_FMT, args[index].fvalue); break; case 'e': DBG_ASSERT(args[index].atype == VA_FLOAT); knh_write_ffmt(ctx, w, K_FLOAT_FMTE, args[index].fvalue); break; case 's': DBG_ASSERT(args[index].atype == VA_CHAR); knh_write(ctx, w, B(args[index].svalue)); break; case 'p': DBG_ASSERT(args[index].atype == VA_POINTER); knh_write__p(ctx, w, args[index].pvalue); break; case 'L': DBG_ASSERT(args[index].atype == VA_OBJECT); if(IS_Token(args[index].ovalue)) { knh_write_token(ctx, w, (knh_Token_t*)args[index].ovalue); break; } case 'O': case 'o': DBG_ASSERT(args[index].atype == VA_OBJECT); mtd = knh_getSystemFormatter(ctx, knh_Object_cid(args[index].ovalue), MN__s); knh_write_Object(ctx, w, esp, &mtd, args[index].ovalue); break; case 'K': case 'k': DBG_ASSERT(args[index].atype == VA_OBJECT); mtd = knh_getSystemFormatter(ctx, knh_Object_cid(args[index].ovalue), MN__k); knh_write_Object(ctx, w, esp, &mtd, args[index].ovalue); break; case 'N': case 'F': DBG_ASSERT(args[index].atype == VA_FIELDN); knh_write_text(ctx, w, FN__(args[index].fn)); break; case 'M': DBG_ASSERT(args[index].atype == VA_METHODN); knh_write_mn(ctx, w, args[index].mn); break; case 'C': DBG_ASSERT(args[index].atype == VA_CLASS); knh_write_sname(ctx, w, args[index].cid); break; case 'T': DBG_ASSERT(args[index].atype == VA_TYPE); knh_write_type(ctx, w, args[index].type); break; case 'B': DBG_ASSERT(args[index].atype == VA_BYTES); knh_write(ctx,w, args[index].bvalue); break; case '%': index--; bindex--; default: //knh_putc(ctx, w, '%'); knh_putc(ctx, w, ch); } b.text = c; b.len = 0; if(!(bindex <= bindex_max)) { DBG_ASSERT(bindex <= bindex_max); break; } } else { b.len = b.len+1; } } if(b.len > 0) { knh_print(ctx, w, b); } } }