2
0
Эх сурвалжийг харах

Fixed an issue with closure.apply method and _args special keyword.

Marco Bambini 8 жил өмнө
parent
commit
4149aeece3

+ 4 - 4
src/runtime/gravity_core.c

@@ -1807,7 +1807,7 @@ static bool system_random (gravity_vm *vm, gravity_value_t *args, uint16_t nargs
 	// Only Seed once
 	static bool already_seeded = false;
 	if (!already_seeded) {
-		srand(time(NULL));
+		srand((unsigned)time(NULL));
 		already_seeded = true;
 	}
 
@@ -1815,13 +1815,13 @@ static bool system_random (gravity_vm *vm, gravity_value_t *args, uint16_t nargs
 	// if num1 is lower, consider it min, otherwise, num2 is min
 	if (num1 < num2) {
 		// returns a random integer between num1 and num2 inclusive
-		r = (rand() % (num2 - num1 + 1)) + num1;
+		r = (int)((rand() % (num2 - num1 + 1)) + num1);
 	}
 	else if (num1 > num2) {
-		r = (rand() % (num1 - num2 + 1)) + num2;
+		r = (int)((rand() % (num1 - num2 + 1)) + num2);
 	}
 	else {
-		r = num1;
+		r = (int)num1;
 	}
 	RETURN_VALUE(VALUE_FROM_INT(r), rindex);
 }

+ 5 - 1
src/runtime/gravity_vm.c

@@ -1450,7 +1450,7 @@ bool gravity_vm_runclosure (gravity_vm *vm, gravity_closure_t *closure, gravity_
 		}
 		
 		STORE_FRAME();
-		PUSH_FRAME(closure, &stackstart[rwin], rwin, nparams);
+		PUSH_FRAME(closure, &stackstart[rwin], rwin, nparams+1);
 		SETFRAME_OUTLOOP(cframe);
 	} else {
 		// there are no execution frames when called outside main function
@@ -1462,6 +1462,10 @@ bool gravity_vm_runclosure (gravity_vm *vm, gravity_closure_t *closure, gravity_
 		for (uint16_t i=0; i<nparams; ++i) {
 			SETVALUE(rwin+i+1, params[i]);
 		}
+		
+		// check if closure uses the special _args instruction
+		gravity_callframe_t *frame = &fiber->frames[0];
+		frame->args = (USE_ARGS(closure)) ? gravity_list_from_array(vm, nparams, &stackstart[rwin]+1) : NULL;
 	}
 	
 	// f can be native, internal or bridge because this function

+ 5 - 4
src/runtime/gravity_vmmacros.h

@@ -157,14 +157,15 @@
 									func = frame->closure->f;																			\
 									DEBUG_VM_RAW("******\tEXEC %s (%p) ******\n", func->identifier, func);
 
-#define PUSH_FRAME(_c,_n,_r,_p)		gravity_callframe_t *cframe = gravity_new_callframe(vm, fiber);										\
+#define USE_ARGS(_c)				(_c->f->tag == EXEC_TYPE_NATIVE && _c->f->useargs)
+#define PUSH_FRAME(_c,_s,_r,_n)		gravity_callframe_t *cframe = gravity_new_callframe(vm, fiber);										\
 									cframe->closure = _c;																				\
-									cframe->stackstart = _n;																			\
+									cframe->stackstart = _s;																			\
 									cframe->ip = _c->f->bytecode;																		\
 									cframe->dest = _r;																					\
-									cframe->nargs = _p;																					\
+									cframe->nargs = _n;																					\
 									cframe->outloop = false;																			\
-									cframe->args = (_c->f->useargs) ? gravity_list_from_array(vm, _p-1, _n+1) : NULL;					\
+									cframe->args = (USE_ARGS(_c)) ? gravity_list_from_array(vm, _n-1, _s+1) : NULL;						\
 
 #define SYNC_STACKTOP(_c,_n)		if (_c->f->tag != EXEC_TYPE_NATIVE) fiber->stacktop -= _n
 #define SETFRAME_OUTLOOP(cframe)	(cframe)->outloop = true

+ 13 - 0
test/closure_args_apply.gravity

@@ -0,0 +1,13 @@
+#unittest {
+	name: "Simple closure.apply with _args.";
+	error: NONE;
+	result: 3;
+};
+
+func add() {
+	return _args[0] + _args[1];
+}
+
+func main() {
+	return add.apply(self, [1,2]);
+}