浏览代码

self context is now correctly set when a closure is executed.

Marco Bambini 7 年之前
父节点
当前提交
4a455641e5
共有 3 个文件被更改,包括 13 次插入4 次删除
  1. 9 1
      src/runtime/gravity_vm.c
  2. 1 1
      src/runtime/gravity_vm.h
  3. 3 2
      src/shared/gravity_value.h

+ 9 - 1
src/runtime/gravity_vm.c

@@ -1272,6 +1272,9 @@ static bool gravity_vm_exec (gravity_vm *vm) {
 				// create closure
 				// create closure
 				gravity_closure_t *closure = gravity_closure_new(vm, f);
 				gravity_closure_t *closure = gravity_closure_new(vm, f);
 
 
+                // save current context (if any)
+                closure->context = gravity_value_isobject(STACK_GET(0)) ? VALUE_AS_OBJECT(STACK_GET(0)) : NULL;
+                
 				// loop for each upvalue setup instruction
 				// loop for each upvalue setup instruction
 				for (uint16_t i=0; i<f->nupvalues; ++i) {
 				for (uint16_t i=0; i<f->nupvalues; ++i) {
 					// code is generated by the compiler so op must be MOVE
 					// code is generated by the compiler so op must be MOVE
@@ -1470,7 +1473,7 @@ void gravity_vm_loadclosure (gravity_vm *vm, gravity_closure_t *closure) {
 	gravity_vm_exec(vm);
 	gravity_vm_exec(vm);
 }
 }
 
 
-bool gravity_vm_runclosure (gravity_vm *vm, gravity_closure_t *closure, gravity_value_t selfvalue, gravity_value_t params[], uint16_t nparams) {
+bool gravity_vm_runclosure (gravity_vm *vm, gravity_closure_t *closure, gravity_value_t sender, gravity_value_t params[], uint16_t nparams) {
 	if (!vm || !closure || vm->aborted) return false;
 	if (!vm || !closure || vm->aborted) return false;
 
 
 	// do not waste cycles on empty functions
 	// do not waste cycles on empty functions
@@ -1484,6 +1487,11 @@ bool gravity_vm_runclosure (gravity_vm *vm, gravity_closure_t *closure, gravity_
 
 
 	DEBUG_STACK();
 	DEBUG_STACK();
 
 
+    // self value is default to the context where the closure has been created
+    gravity_value_t selfvalue = (closure->context) ? VALUE_FROM_OBJECT(closure->context) : sender;
+    
+    // we need a way to give user the ability to access the sender value from a closure
+    
 	// if fiber->nframes is not zero it means that this event has been recursively called
 	// if fiber->nframes is not zero it means that this event has been recursively called
 	// from somewhere inside the main function so we need to protect and correctly setup
 	// from somewhere inside the main function so we need to protect and correctly setup
 	// the new activation frame
 	// the new activation frame

+ 1 - 1
src/runtime/gravity_vm.h

@@ -32,7 +32,7 @@ GRAVITY_API gravity_vm			*gravity_vm_newmini (void);
 GRAVITY_API void				gravity_vm_set_callbacks (gravity_vm *vm, vm_transfer_cb vm_transfer, vm_cleanup_cb vm_cleanup);
 GRAVITY_API void				gravity_vm_set_callbacks (gravity_vm *vm, vm_transfer_cb vm_transfer, vm_cleanup_cb vm_cleanup);
 GRAVITY_API void				gravity_vm_free (gravity_vm *vm);
 GRAVITY_API void				gravity_vm_free (gravity_vm *vm);
 GRAVITY_API void				gravity_vm_reset (gravity_vm *vm);
 GRAVITY_API void				gravity_vm_reset (gravity_vm *vm);
-GRAVITY_API bool				gravity_vm_runclosure (gravity_vm *vm, gravity_closure_t *closure, gravity_value_t selfvalue, gravity_value_t params[], uint16_t nparams);
+GRAVITY_API bool				gravity_vm_runclosure (gravity_vm *vm, gravity_closure_t *closure, gravity_value_t sender, gravity_value_t params[], uint16_t nparams);
 GRAVITY_API bool				gravity_vm_runmain (gravity_vm *vm, gravity_closure_t *closure);
 GRAVITY_API bool				gravity_vm_runmain (gravity_vm *vm, gravity_closure_t *closure);
 GRAVITY_API void				gravity_vm_loadclosure (gravity_vm *vm, gravity_closure_t *closure);
 GRAVITY_API void				gravity_vm_loadclosure (gravity_vm *vm, gravity_closure_t *closure);
 GRAVITY_API void				gravity_vm_setvalue (gravity_vm *vm, const char *key, gravity_value_t value);
 GRAVITY_API void				gravity_vm_setvalue (gravity_vm *vm, const char *key, gravity_value_t value);

+ 3 - 2
src/shared/gravity_value.h

@@ -66,8 +66,8 @@
 extern "C" {
 extern "C" {
 #endif
 #endif
 
 
-#define GRAVITY_VERSION						"0.4.4"     // git tag 0.4.4
-#define GRAVITY_VERSION_NUMBER				0x000404    // git push --tags
+#define GRAVITY_VERSION						"0.4.5"     // git tag 0.4.5
+#define GRAVITY_VERSION_NUMBER				0x000405    // git push --tags
 #define GRAVITY_BUILD_DATE					__DATE__
 #define GRAVITY_BUILD_DATE					__DATE__
 
 
 #ifndef GRAVITY_ENABLE_DOUBLE
 #ifndef GRAVITY_ENABLE_DOUBLE
@@ -288,6 +288,7 @@ typedef struct {
 	gravity_gc_t			gc;					// to be collectable by the garbage collector
 	gravity_gc_t			gc;					// to be collectable by the garbage collector
 
 
 	gravity_function_t		*f;					// function prototype
 	gravity_function_t		*f;					// function prototype
+    gravity_object_t        *context;           // context where the closure has been created
 	gravity_upvalue_t		**upvalue;			// upvalue array
 	gravity_upvalue_t		**upvalue;			// upvalue array
 } gravity_closure_t;
 } gravity_closure_t;