shithub: libmujs

Download patch

ref: d8576fe02cf8abda964603386fd2f6fae9c787c0
parent: 52f78c568760d8157e0f4dd780f7ffe6c521bc65
author: Tor Andersson <[email protected]>
date: Sun Jan 12 11:25:22 EST 2014

Create var bindings for self function and function declarations.

--- a/jscompile.c
+++ b/jscompile.c
@@ -181,6 +181,10 @@
 		cexp(J, F, exp->a);
 		emitname(J, F, OP_AMEMBER, exp->b->string);
 		break;
+	case EXP_CALL:
+		/* host functions may return an assignable l-value */
+		cexp(J, F, exp);
+		break;
 	default:
 		jsC_error(J, exp, "invalid l-value in assignment");
 		break;
@@ -256,7 +260,7 @@
 		break;
 
 	case EXP_FUNC:
-		emitfunction(J, F, OP_FUNEXP, newfun(J, exp->a, exp->b, exp->c));
+		emitfunction(J, F, OP_CLOSURE, newfun(J, exp->a, exp->b, exp->c));
 		break;
 
 	case EXP_DELETE:
@@ -385,7 +389,6 @@
 
 	switch (stm->type) {
 	case STM_FUNC:
-		emitfunction(J, F, OP_FUNDEC, newfun(J, stm->a, stm->b, stm->c));
 		break;
 
 	case STM_BLOCK:
@@ -459,6 +462,34 @@
 	}
 }
 
+static void cfundecs(JF, js_Ast *list)
+{
+	while (list) {
+		js_Ast *stm = list->a;
+		if (stm->type == STM_FUNC) {
+			emitfunction(J, F, OP_CLOSURE, newfun(J, stm->a, stm->b, stm->c));
+			emitname(J, F, OP_VARDEC, stm->a->string);
+		}
+		list = list->b;
+	}
+}
+
+static void cfunbody(JF, js_Ast *name, js_Ast *params, js_Ast *body)
+{
+	if (name) {
+		emitfunction(J, F, OP_CLOSURE, F);
+		emitname(J, F, OP_VARDEC, name->string);
+	}
+
+	cfundecs(J, F, body);
+
+	cstmlist(J, F, body);
+	if (F->len == 0 || F->code[F->len - 1] != OP_RETURN) {
+		emit(J, F, OP_UNDEF);
+		emit(J, F, OP_RETURN);
+	}
+}
+
 static js_Function *newfun(js_State *J, js_Ast *name, js_Ast *params, js_Ast *body)
 {
 	js_Function *F = malloc(sizeof(js_Function));
@@ -477,11 +508,7 @@
 	F->next = J->fun;
 	J->fun = F;
 
-	cstmlist(J, F, body);
-	if (F->len == 0 || F->code[F->len - 1] != OP_RETURN) {
-		emit(J, F, OP_UNDEF);
-		emit(J, F, OP_RETURN);
-	}
+	cfunbody(J, F, name, params, body);
 
 	return F;
 }
--- a/jscompile.h
+++ b/jscompile.h
@@ -6,6 +6,7 @@
 	OP_POP,
 	OP_DUP,
 
+	OP_CLOSURE,
 	OP_CONST,
 	OP_UNDEF,
 	OP_NULL,
@@ -19,8 +20,6 @@
 	OP_OBJECTPUT,
 
 	OP_VARDEC,
-	OP_FUNDEC,
-	OP_FUNEXP,
 
 	OP_LOADVAR,	/* -(name)- <value> */
 	OP_LOADINDEX,	/* <obj> <idx> -- <value> */
--- a/jsdump.c
+++ b/jsdump.c
@@ -626,8 +626,7 @@
 		case OP_LOADMEMBER:
 		case OP_AVAR:
 		case OP_AMEMBER:
-		case OP_FUNDEC:
-		case OP_FUNEXP:
+		case OP_CLOSURE:
 			pc(' ');
 			jsC_dumpvalue(J, fun->klist[*p++]);
 			break;
@@ -650,8 +649,10 @@
 
 	for (i = 0; i < fun->klen; i++) {
 		if (fun->klist[i].type == JS_TFUNCTION) {
-			nl();
-			jsC_dumpfunction(J, fun->klist[i].u.function);
+			if (fun->klist[i].u.function != fun) {
+				nl();
+				jsC_dumpfunction(J, fun->klist[i].u.function);
+			}
 		}
 	}
 }