diff options
author | dptr1988 <junk_mail@dptr1988.mooo.com> | 2011-01-19 17:43:07 -0800 |
---|---|---|
committer | dptr1988 <junk_mail@dptr1988.mooo.com> | 2011-01-19 17:43:07 -0800 |
commit | 8ce207a848429e8581e8a900b645927f86e78435 (patch) | |
tree | c0eaced5fb675e25e697bb9ecc91326888c20f8d /src/tools.c | |
parent | 088834240ba6304ae930494e1be5f0c987c3c361 (diff) | |
download | lanes-8ce207a848429e8581e8a900b645927f86e78435.tar.gz lanes-8ce207a848429e8581e8a900b645927f86e78435.tar.bz2 lanes-8ce207a848429e8581e8a900b645927f86e78435.zip |
Changed luaG_push_proxy to cache deep userdata proxies.
Diffstat (limited to 'src/tools.c')
-rw-r--r-- | src/tools.c | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/src/tools.c b/src/tools.c index 2f3140d..6692890 100644 --- a/src/tools.c +++ b/src/tools.c | |||
@@ -188,6 +188,13 @@ const char *luaG_openlibs( lua_State *L, const char *libs ) { | |||
188 | #define DEEP_LOOKUP_KEY ((void*)set_deep_lookup) | 188 | #define DEEP_LOOKUP_KEY ((void*)set_deep_lookup) |
189 | // any unique light userdata | 189 | // any unique light userdata |
190 | 190 | ||
191 | |||
192 | /* | ||
193 | * The deep proxy cache is a weak valued table listing all deep UD proxies indexed by the deep UD that they are proxying | ||
194 | */ | ||
195 | #define DEEP_PROXY_CACHE_KEY ((void*)luaG_push_proxy) | ||
196 | |||
197 | static void push_registry_subtable_mode( lua_State *L, void *token, const char* mode ); | ||
191 | static void push_registry_subtable( lua_State *L, void *token ); | 198 | static void push_registry_subtable( lua_State *L, void *token ); |
192 | 199 | ||
193 | /* | 200 | /* |
@@ -350,6 +357,18 @@ int deep_userdata_gc( lua_State *L ) { | |||
350 | void luaG_push_proxy( lua_State *L, lua_CFunction idfunc, DEEP_PRELUDE *prelude ) { | 357 | void luaG_push_proxy( lua_State *L, lua_CFunction idfunc, DEEP_PRELUDE *prelude ) { |
351 | DEEP_PRELUDE **proxy; | 358 | DEEP_PRELUDE **proxy; |
352 | 359 | ||
360 | // Check if a proxy already exists | ||
361 | push_registry_subtable_mode(L, DEEP_PROXY_CACHE_KEY, "v"); | ||
362 | lua_pushlightuserdata(L, prelude->deep); | ||
363 | lua_rawget(L, -2); | ||
364 | if (!lua_isnil(L, -1)) { | ||
365 | lua_remove(L, -2); // deep proxy cache table | ||
366 | return; | ||
367 | } else { | ||
368 | lua_pop(L, 2); // Pop the nil and proxy cache table | ||
369 | } | ||
370 | |||
371 | |||
353 | MUTEX_LOCK( &deep_lock ); | 372 | MUTEX_LOCK( &deep_lock ); |
354 | ++(prelude->refcount); // one more proxy pointing to this deep data | 373 | ++(prelude->refcount); // one more proxy pointing to this deep data |
355 | MUTEX_UNLOCK( &deep_lock ); | 374 | MUTEX_UNLOCK( &deep_lock ); |
@@ -413,6 +432,13 @@ void luaG_push_proxy( lua_State *L, lua_CFunction idfunc, DEEP_PRELUDE *prelude | |||
413 | 432 | ||
414 | lua_setmetatable( L, -2 ); | 433 | lua_setmetatable( L, -2 ); |
415 | 434 | ||
435 | // If we're here, we obviously had to create a new proxy, so cache it. | ||
436 | push_registry_subtable_mode(L, DEEP_PROXY_CACHE_KEY, "v"); | ||
437 | lua_pushlightuserdata(L, (*proxy)->deep); | ||
438 | lua_pushvalue(L, -3); // Copy of the proxy | ||
439 | lua_rawset(L, -3); | ||
440 | lua_pop(L, 1); // Remove the cache proxy table | ||
441 | |||
416 | STACK_END(L,1) | 442 | STACK_END(L,1) |
417 | // [-1]: proxy userdata | 443 | // [-1]: proxy userdata |
418 | } | 444 | } |
@@ -544,11 +570,10 @@ lua_CFunction luaG_copydeep( lua_State *L, lua_State *L2, int index ) { | |||
544 | */ | 570 | */ |
545 | 571 | ||
546 | /* | 572 | /* |
547 | * Push a registry subtable (keyed by unique 'token') onto the stack. | 573 | * Does what the original 'push_registry_subtable' function did, but adds an optional mode argument to it |
548 | * If the subtable does not exist, it is created and chained. | ||
549 | */ | 574 | */ |
550 | static | 575 | static |
551 | void push_registry_subtable( lua_State *L, void *token ) { | 576 | void push_registry_subtable_mode( lua_State *L, void *token, const char* mode ) { |
552 | 577 | ||
553 | STACK_GROW(L,3); | 578 | STACK_GROW(L,3); |
554 | 579 | ||
@@ -570,12 +595,30 @@ void push_registry_subtable( lua_State *L, void *token ) { | |||
570 | // [-1]: value | 595 | // [-1]: value |
571 | 596 | ||
572 | lua_rawset( L, LUA_REGISTRYINDEX ); | 597 | lua_rawset( L, LUA_REGISTRYINDEX ); |
598 | |||
599 | // Set it's metatable if requested | ||
600 | if (mode) { | ||
601 | lua_newtable(L); | ||
602 | lua_pushliteral(L, "__mode"); | ||
603 | lua_pushstring(L, mode); | ||
604 | lua_rawset(L, -3); | ||
605 | lua_setmetatable(L, -2); | ||
606 | } | ||
573 | } | 607 | } |
574 | STACK_END(L,1) | 608 | STACK_END(L,1) |
575 | 609 | ||
576 | ASSERT_L( lua_istable(L,-1) ); | 610 | ASSERT_L( lua_istable(L,-1) ); |
577 | } | 611 | } |
578 | 612 | ||
613 | /* | ||
614 | * Push a registry subtable (keyed by unique 'token') onto the stack. | ||
615 | * If the subtable does not exist, it is created and chained. | ||
616 | */ | ||
617 | static | ||
618 | void push_registry_subtable( lua_State *L, void *token ) { | ||
619 | push_registry_subtable_mode(L, token, NULL); | ||
620 | } | ||
621 | |||
579 | #define REG_MTID ( (void*) get_mt_id ) | 622 | #define REG_MTID ( (void*) get_mt_id ) |
580 | 623 | ||
581 | /* | 624 | /* |