Esempio n. 1
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, ')');
	}
}
Esempio n. 2
0
static METHOD knh__HashMap_get(Ctx *ctx, knh_sfp_t *sfp)
{
	HashMap *o = (HashMap*)sfp[0].o;
	knh_hcode_t hcode = knh_stack_hashCode(ctx, sfp + 1);
	knh_uintptr_t h =  hcode % DP(o)->hmax;
	knh_hashentry_t *e = DP(o)->array[h];

	while(e != NULL) {
		if(e->hcode == hcode
				&& knh_Object_cid(sfp[1].o) == knh_Object_cid(e->key)
				&& knh_stack_equals(ctx, sfp + 1, e->key)) {
			KNH_RETURN(ctx, sfp, e->value);
		}
		e = e->next;
	}
	KNH_RETURN(ctx, sfp, KNH_NULL);
}
METHOD Chardev_new(Ctx *ctx, knh_sfp_t *sfp)
{
	printk("%s:%d\n",__func__,__LINE__);
	knh_device_t *dev = new_device(ctx, sfp[1].s);
	knh_RawPtr_init(ctx, sfp[0].glue, dev, device_gfree);

	// set ref for object.
	// but we do not set ref because it becomes cyclic refalence.
	dev->self = sfp[0].o;
	printk("%s:%d, cid=%d\n",__func__,__LINE__, knh_Object_cid(sfp[0].o));
	KNH_RETURN(ctx, sfp, sfp[0].o);
}
Esempio n. 4
0
void knh_write_Object(Ctx *ctx, knh_OutputStream_t *w, knh_sfp_t *esp, knh_Method_t **mtdP, knh_Object_t *o)
{
	knh_class_t cid = knh_Object_cid(o);
	knh_Method_t *mtd = mtdP[0];
	if(!knh_Method_isPoly(mtd, cid)) {
		mtd = knh_getSystemFormatter(ctx, cid, DP(mtd)->mn);
		mtdP[0] = mtd;
	}
	KNH_SETv(ctx, esp[K_CALLDELTA].o, w);
	KNH_SETv(ctx, esp[K_CALLDELTA+1].o, o);
	esp[K_CALLDELTA+1].data = knh_Object_data(o); // this is necessary
	KNH_SCALL(ctx, esp, 0, mtd, 1);
}
//## method @Virtual void Chardev.read(File! file, OutputStream ous);
static ssize_t script_read (struct file* filp, char __user *user_buf,
		size_t count, loff_t *offset)
{
	printk("%s at %d\n",__func__,__LINE__);
	knh_device_t *dev = filp->private_data;
	knh_Object_t *self = dev->self;

	if(*offset > 0) return 0;
	Ctx *ctx = knh_getCurrentContext();
	knh_sfp_t *sfp = KNH_LOCAL(ctx);
	knh_Method_t *mtd = dev->read;
	if (!IS_Method(mtd) || knh_Method_isAbstract(mtd)) {
		knh_bytes_t fname = B("read");
		knh_methodn_t mn = knh_getmn(ctx, fname, METHODN_NONAME);
		mtd = knh_Class_getMethod(ctx, knh_Object_cid(self), mn);
		KNH_SETv(ctx, dev->read, mtd);
	}
	//knh_File_t *f = (knh_File_t*)new_Object_bcid(ctx, CLASS_File, 0);
	//f->file = filp;

	if (IS_Method(mtd)) {
		KNH_MOV(ctx, sfp[0].o, new_ExceptionHandler(ctx));
		KNH_TRY(ctx, L_CATCH, sfp, 0);
		{
			knh_cwb_t cwbbuf, *cwb = knh_cwb_open(ctx, &cwbbuf);
			// THIS IS DANGEROUS. DON'T USED by KIMIO
//			knh_OutputStream_t *o = new_BytesOutputStream(ctx, cwb->ba);
//			KNH_MOV(ctx, sfp[1].o, self);
//			//KNH_MOV(ctx, sfp[2].o, f);
//			KNH_MOV(ctx, sfp[2].o, KNH_NULL);
//			KNH_MOV(ctx, sfp[3].o, o);
//			KNH_SCALL(ctx, sfp, 0, mtd, 2);
//			{
//				size_t len  = knh_cwb_size(cwb);
//				char   *buf = knh_cwb_tochar(ctx, cwb);
//				if(copy_to_user(user_buf,buf,len)){
//					printk(KERN_ALERT "%s: copy_to_user failed\n",__func__);
//					return -EFAULT;
//				}
//				knh_cwb_close(cwb);
//				knh_Context_clearstack(ctx);
//				*offset += len;
//				return len;
//			}
		}
		/* catch */
		L_CATCH:;
		KNH_PRINT_STACKTRACE(ctx, sfp, 0);
	}
	return 0;
}
Esempio n. 6
0
static METHOD knh__HashMap_set(Ctx *ctx, knh_sfp_t *sfp)
{
	if(IS_IMM(sfp[0].o)) {
		if(IS_NULL(sfp[2].o)) {
			knh__HashMap_remove(ctx, sfp);
			return ;
		}

		knh_Hash_t *o = (knh_Hash_t*)sfp[0].o;
		knh_hcode_t hcode = knh_stack_hashCode(ctx, sfp + 1);
		knh_uintptr_t h =  hcode % DP(o)->hmax;
		knh_hashentry_t *e = DP(o)->array[h];

		while(e != NULL) {
			if(e->hcode == hcode
					&& knh_Object_cid(sfp[1].o) == knh_Object_cid(e->key)
					&& knh_stack_equals(ctx, sfp + 1, e->key)) {
				knh_sfp_boxing(ctx, sfp+2);
				KNH_SETv(ctx, e->value, sfp[2].o);
				KNH_RETURN_void(ctx, sfp);
			}
			e = e->next;
		}

		/* add newentry */ {
			e = new_hashentry(ctx, o);
			e->hcode = hcode;
			knh_sfp_boxing(ctx, sfp+1);
			KNH_INITv(e->key, sfp[1].o);
			knh_sfp_boxing(ctx, sfp+2);
			KNH_INITv(e->value, sfp[2].o);
			e->next = DP(o)->array[h];
			DP(o)->array[h] = e;
			DP(o)->size++;
		}
	}
	KNH_RETURN_void(ctx, sfp);
}
Esempio n. 7
0
static METHOD knh__HashMap_remove(Ctx *ctx, knh_sfp_t *sfp)
{
	if(IS_IMM(sfp[0].o)) {
		knh_Hash_t *o = (knh_Hash_t*)sfp[0].o;
		knh_hcode_t hcode = knh_stack_hashCode(ctx, sfp + 1);
		knh_uintptr_t h =  hcode % DP(o)->hmax;
		knh_hashentry_t *e = DP(o)->array[h];
		knh_hashentry_t **prev_next = &(DP(o)->array[h]);

		while(e != NULL) {
			if(e->hcode == hcode
					&& knh_Object_cid(sfp[1].o) == knh_Object_cid(e->key)
					&& knh_stack_equals(ctx, sfp + 1, e->key)) {
				prev_next[0] = e->next;
				knh_hashentry_collect(ctx, o, e);
				DP(o)->size--;
			}
			prev_next = &(e->next);
			e = e->next;
		}
	}
	KNH_RETURN_void(ctx, sfp);
}
Esempio n. 8
0
static METHOD knh__String_format(Ctx *ctx, knh_sfp_t *sfp)
{
	knh_bytes_t fmt = knh_String_tobytes(sfp[0].s);
	knh_sfp_t *param = sfp + 1;
	int ac = knh_stack_argc(ctx, param);
	knh_bytes_t mt, expr, next;

	if(!knh_bytes_findMT(ctx, fmt, &mt, &expr, &next)) {
		KNH_RETURN(ctx, sfp, sfp[0].s);
	}

	knh_cwb_t cwbbuf, *cwb = knh_cwb_open(ctx, &cwbbuf);
	int count;
	for(count = 0; ; count++) {
		if(mt.buf > fmt.buf + 1) {
			fmt.len = (mt.buf - fmt.buf) - 1;
			knh_Bytes_write(ctx, cwb->ba, fmt);
		}
		int index = count;
		if(expr.len > 0) {
			knh_int_t num;
			if(knh_bytes_parseint(expr, &num)) {
				index = (int)num;
			}
		}
		if(0 <= index && index < ac) {
			knh_sfp_t *esp = KNH_LOCAL(ctx);
			KNH_SETv(ctx, esp[1].o, param[index].o); esp[1].data = param[index].data;
			Object *m = KNH_NULL;
			if(knh_bytes_isOptionalMT(mt)) m = UP(new_String(ctx, mt, NULL));
			mt.buf = mt.buf - 1; mt.len++;   /* 's' == > '%s' */
			knh_methodn_t mn = knh_getmn(ctx, mt, METHODN__empty);
			knh_esp1_format(ctx, mn, cwb->w, m);
		}
		else {
			if(knh_Context_isDebug(ctx)) {
				KNH_THROW_OUTOFINDEX(ctx, index, ac);
			}
		}
		fmt.buf = next.buf; fmt.len = next.len;
		if(!knh_bytes_findMT(ctx, fmt, &mt, &expr, &next)) {
			break;
		}
	}
	if(fmt.len > 0) {
		knh_Bytes_write(ctx, cwb->ba, fmt);
	}
	KNH_RETURN(ctx, sfp, new_StringX__cwb(ctx, knh_Object_cid(sfp[0].o), cwb));
}
Esempio n. 9
0
static
void knh_String__k(Ctx *ctx, String *o, OutputStream *w, String *m)
{
	int quote = '\'';
	if(knh_Object_cid(o) == CLASS_String) quote = '"';
	knh_putc(ctx, w, quote);
	knh_bytes_t t = knh_String_tobytes(o);
	knh_bytes_t sub = t;
	size_t i, s = 0;
	for(i = 0; i < o->size; i++) {
		switch(t.buf[i]) {
			case '\t' :
				sub.buf = t.buf + s;
				sub.len = i - s;
				knh_print(ctx, w, sub); s = i + 1;
				knh_putc(ctx, w, '\\'); knh_putc(ctx, w, 't'); break ;
			case '\n' :
				sub.buf = t.buf + s;
				sub.len = i - s;
				knh_print(ctx, w, sub); s = i + 1;
				knh_putc(ctx, w, '\\'); knh_putc(ctx, w, 'n'); break ;
			case '\r' :
				sub.buf = t.buf + s;
				sub.len = i - s;
				knh_print(ctx, w, sub); s = i + 1;
				knh_putc(ctx, w, '\\'); knh_putc(ctx, w, 'r'); break ;
			case '\\' :
				sub.buf = t.buf + s;
				sub.len = i - s;
				knh_print(ctx, w, sub); s = i + 1;
				knh_putc(ctx, w, '\\'); knh_putc(ctx, w, '\\'); break ;
			default:
				if(t.buf[i] == quote) {
					sub.buf = t.buf + s;
					sub.len = i - s;
					knh_print(ctx, w, sub); s = i + 1;
					knh_putc(ctx, w, '\\'); knh_putc(ctx, w, quote);
				}
		}
	}
	if (s < t.len) {
		sub.buf = t.buf + s;
		sub.len = t.len - s;
		knh_print(ctx, w, sub);
	}
	knh_putc(ctx, w, quote);
}
Esempio n. 10
0
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);
	}
}
Esempio n. 11
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);
		}
	}
}