diff --git a/src/docode.c b/src/docode.c
index a99b16402f7fed9264e74a5ee9879bc9108e4dbc..c7b606bb575e3d3af38a7cbba20e00b15d0a7b68 100644
--- a/src/docode.c
+++ b/src/docode.c
@@ -130,10 +130,6 @@ static int do_jump(int token,INT32 lbl)
 
 static int do_docode2(node *n,int flags);
 
-#define DO_LVALUE 1
-#define DO_NOT_COPY 2
-#define DO_POP 4
-
 #define ins_label(L) do_jump(F_LABEL, L)
 
 static void do_pop(int x)
@@ -266,6 +262,8 @@ static int do_docode2(node *n,int flags)
 
   case '?':
   {
+    int adroppings , bdroppings;
+
     if(!CDDR(n))
     {
       tmp1=do_jump_when_zero(CAR(n), -1);
@@ -282,28 +280,29 @@ static int do_docode2(node *n,int flags)
       return 0;
     }
 
-    tmp1=count_args(CDDR(n));
-    tmp2=count_args(CADR(n));
+    tmp1=do_jump_when_zero(CAR(n),-1);
 
-    if(tmp2 < tmp1) tmp1=tmp2;
+    adroppings=do_docode(CADR(n), flags);
+    tmp3=emit(F_POP_N_ELEMS,0);
 
-    if(tmp1 == -1)
-      fatal("Unknown number of args in ? :\n");
+    /* Else */
+    tmp2=do_jump(F_BRANCH,-1);
+    emit(F_LABEL, tmp1);
 
-    tmp2=do_jump_when_zero(CAR(n),-1);
+    bdroppings=do_docode(CDDR(n), flags);
+    if(adroppings < bdroppings)
+    {
+      do_pop(bdroppings - adroppings);
+    }
 
-    tmp3=do_docode(CADR(n), flags);
-    if(tmp3 < tmp1) fatal("Count arguments was wrong.\n");
-    do_pop(tmp3 - tmp1);
+    if(adroppings > bdroppings)
+    {
+      update_arg(tmp3,adroppings-bdroppings);
+      adroppings=bdroppings;
+    }
 
-    tmp3=do_jump(F_BRANCH,-1);
     emit(F_LABEL, tmp2);
-
-    tmp2=do_docode(CDDR(n), flags);
-    if(tmp2 < tmp1) fatal("Count arguments was wrong.\n");
-    do_pop(tmp2 - tmp1);
-    emit(F_LABEL, tmp3);
-    return tmp1;
+    return adroppings;
   }
       
   case F_AND_EQ:
@@ -499,14 +498,13 @@ static int do_docode2(node *n,int flags)
 
     if(CDR(n))
     {
-      tmp1=do_jump(F_BRANCH,-1);
+      do_jump_when_zero(CAR(n),current_break);
       tmp2=ins_label(-1);
-      if(CDR(n)) DO_CODE_BLOCK(CADR(n));
+      DO_CODE_BLOCK(CADR(n));
       ins_label(current_continue);
-      if(CDR(n)) DO_CODE_BLOCK(CDDR(n));
-      emit(F_LABEL,tmp1);
+      DO_CODE_BLOCK(CDDR(n));
     }else{
-      tmp2=PC;
+      tmp2=ins_label(-1);
     }
     do_jump_when_non_zero(CAR(n),tmp2);
     ins_label(current_break);
@@ -882,8 +880,8 @@ static int do_docode2(node *n,int flags)
     DO_CODE_BLOCK(CAR(n));
     ins_label(current_continue);
     ins_label(current_break);
-    emit2(F_DUMB_RETURN);
-    emit(F_LABEL,tmp1);
+    emit2(F_THROW_ZERO);
+    ins_label(tmp1);
 
     current_break=break_save;
     current_continue=continue_save;