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 | |
| 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')
| -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 | /* |
