Tamar 0.7.3 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1623 @@
1
+ /*
2
+ * RubyLuaBridge
3
+ *
4
+ * Licensed under the BSD License:
5
+ *
6
+ * Copyright (c) 2007, Evan Wies
7
+ * All rights reserved.
8
+ *
9
+ * Redistribution and use in source and binary forms, with or without
10
+ * modification, are permitted provided that the following conditions are met:
11
+ * * Redistributions of source code must retain the above copyright
12
+ * notice, this list of conditions and the following disclaimer.
13
+ * * Redistributions in binary form must reproduce the above copyright
14
+ * notice, this list of conditions and the following disclaimer in the
15
+ * documentation and/or other materials provided with the distribution.
16
+ * * Neither the name of 'neomantra' nor the
17
+ * names of its contributors may be used to endorse or promote products
18
+ * derived from this software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY Evan Wies ``AS IS'' AND ANY
21
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ * DISCLAIMED. IN NO EVENT SHALL Evan Wies BE LIABLE FOR ANY
24
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ */
31
+
32
+ #include <assert.h>
33
+ extern "C" {
34
+ #include <lua.h>
35
+ #include <lualib.h>
36
+ #include <lauxlib.h>
37
+ }
38
+ #include "rubyluabridge.h"
39
+ #include "st.h"
40
+
41
+ // Debug Scaffolding
42
+ #ifdef RLB_DEBUG
43
+ #define RLB_DEBUG_PRINT(fmt, ...) printf(fmt, __VA_ARGS__)
44
+ #else
45
+ #define RLB_DEBUG_PRINT(fmt, ...)
46
+ #endif
47
+
48
+
49
+ /*****************************************************************************/
50
+ //
51
+ // Global Variables and Typedefs
52
+ //
53
+ /*****************************************************************************/
54
+
55
+ VALUE mLua;
56
+ VALUE cLua_State;
57
+ VALUE cLua_RefObject;
58
+ VALUE cLua_Table; // derives from Lua::RefObject
59
+
60
+
61
+ /// A place to stash error messages
62
+ #define RUBYLUABRIDGE_ERROR_BUFFER_SIZE 4096
63
+ char gszErrorBuffer[RUBYLUABRIDGE_ERROR_BUFFER_SIZE];
64
+
65
+
66
+ /// WE DON"T DO THIS YET BUT PROBABLY WILL
67
+ /// In general, I'm doing a little cheating.
68
+ /// Since cLua_State is just a wrapper around a lua_State*,
69
+ /// and always can always extract the lua_State
70
+ /// meaning, take advantage the lua_State is ALWAYS there...
71
+ ///
72
+
73
+
74
+
75
+ /*****************************************************************************/
76
+ //
77
+ // Library Infrastructure
78
+ //
79
+ /*****************************************************************************/
80
+
81
+ // Fwd: Ruby Hash iterator, inserting elements to a table
82
+ static int _rhash_to_table_iter_func( VALUE rkey, VALUE rvalue, lua_State* L );
83
+
84
+
85
+ /// Copies the top of the stack to gszErrorBuffer,
86
+ /// pops the top of the stack, and returns the address to gszErrorBuffer.
87
+ /// This is useful for error handling functions.
88
+ char* pop_error_to_buffer( lua_State* L )
89
+ {
90
+ const char* szerr = lua_tostring( L, -1 );
91
+ strncpy( gszErrorBuffer, szerr, RUBYLUABRIDGE_ERROR_BUFFER_SIZE );
92
+ lua_pop(L, 1);
93
+ return gszErrorBuffer;
94
+ }
95
+
96
+
97
+ /// return whether the value at a given index is "callable",
98
+ /// meaning that we can try to invoke it like a method
99
+ int is_callable( lua_State* L, int idx )
100
+ {
101
+ // functions are callable
102
+ if ( lua_type(L, idx) == LUA_TFUNCTION )
103
+ return 1;
104
+
105
+ // check if it is supports the __call metamethod
106
+ if ( !lua_getmetatable(L, idx) ) // no metatable?
107
+ return 0;
108
+
109
+ lua_pushstring( L, "__call" );
110
+ lua_rawget(L, -2);
111
+ int callable = (lua_isnil(L, -1) == 0);
112
+
113
+ lua_pop( L, 2 ); // remove metatable and metafield
114
+ return callable;
115
+ }
116
+
117
+
118
+ /// return whether the value at a given index is "indexable",
119
+ /// that means will doing a table-like lookup not crash
120
+ int is_indexable( lua_State* L, int idx )
121
+ {
122
+ // tables are obviously indexable
123
+ if ( lua_type(L, idx) == LUA_TTABLE )
124
+ return 1;
125
+
126
+ // check if it is supports the __index metamethod
127
+ if ( !lua_getmetatable(L, idx) ) // no metatable?
128
+ return 0;
129
+
130
+ lua_pushstring( L, "__index" );
131
+ lua_rawget(L, -2);
132
+ int indexable = (lua_isnil(L, -1) == 0);
133
+
134
+ lua_pop( L, 2 ); // remove metatable and metafield
135
+ return indexable;
136
+ }
137
+
138
+
139
+ /// return whether the value at a given index is "new_indexable",
140
+ /// that means will doing a table-like lookup not crash
141
+ int is_new_indexable( lua_State* L, int idx )
142
+ {
143
+ // tables are obviously indexable
144
+ if ( lua_type(L, idx) == LUA_TTABLE )
145
+ return 1;
146
+
147
+ // check if it is supports the __index metamethod
148
+ if ( !lua_getmetatable(L, idx) ) // no metatable?
149
+ return 0;
150
+
151
+ lua_pushstring( L, "__newindex" );
152
+ lua_rawget(L, -2);
153
+ int new_indexable = (lua_isnil(L, -1) == 0);
154
+
155
+ lua_pop( L, 2 ); // remove metatable and metafield
156
+ return new_indexable;
157
+ }
158
+
159
+
160
+ /// marshals the given stack value to Ruby
161
+ /// leaves the stack unchanged
162
+ VALUE marshal_lua_to_ruby( VALUE Rstate, lua_State* L, int idx )
163
+ {
164
+ int ltype = lua_type( L, idx );
165
+ switch ( ltype )
166
+ {
167
+ // primitive types -> marshal directly
168
+ case LUA_TNONE:
169
+ case LUA_TNIL:
170
+ return Qnil;
171
+ case LUA_TBOOLEAN:
172
+ return lua_toboolean(L,idx) ? Qtrue : Qfalse;
173
+ case LUA_TNUMBER:
174
+ return rb_float_new( lua_tonumber(L,idx) );
175
+ case LUA_TSTRING:
176
+ {
177
+ size_t len = 0;
178
+ const char* str = lua_tolstring(L, idx, &len);
179
+ return rb_str_new( str, len );
180
+ }
181
+
182
+ // complex types
183
+ // these are stored in Lua::RefObjects
184
+ // except tables, which are stored in Lua::Table
185
+ case LUA_TLIGHTUSERDATA:
186
+ case LUA_TFUNCTION:
187
+ case LUA_TUSERDATA:
188
+ case LUA_TTHREAD:
189
+ case LUA_TTABLE:
190
+ {
191
+ // make a Lua reference for this
192
+ lua_pushvalue( L, idx );
193
+ int ref = luaL_ref( L, LUA_REGISTRYINDEX );
194
+ RLB_DEBUG_PRINT( "ref created: L:%p r:%d\n", L, ref);
195
+ // create a new lua_Ref object holding it
196
+ VALUE args[2] = { Rstate, INT2NUM(ref) };
197
+ VALUE res = rb_class_new_instance( 2, args,
198
+ (ltype == LUA_TTABLE) ? cLua_Table : cLua_RefObject );
199
+ return res;
200
+ }
201
+ default:
202
+ return Qnil;
203
+ }
204
+ }
205
+
206
+
207
+ /// marshals the given Ruby value to Lua, leaving it on the top
208
+ /// returns a non-zero error code on failure
209
+ int marshal_ruby_to_lua_top( lua_State* L, VALUE val )
210
+ {
211
+ int rtype = TYPE(val);
212
+ switch ( rtype )
213
+ {
214
+ case T_NONE: lua_pushnil( L ); break;
215
+ case T_NIL: lua_pushnil( L ); break;
216
+ case T_TRUE: lua_pushboolean( L, 1 ); break;
217
+ case T_FALSE: lua_pushboolean( L, 0 ); break;
218
+ case T_FIXNUM: lua_pushnumber( L, FIX2INT(val) ); break;
219
+ case T_BIGNUM: lua_pushnumber( L, NUM2DBL(val) ); break;
220
+ case T_FLOAT:
221
+ lua_pushnumber( L, (lua_Number)RFLOAT(val)->value );
222
+ break;
223
+ case T_STRING:
224
+ lua_pushlstring( L, RSTRING(val)->ptr, RSTRING(val)->len );
225
+ break;
226
+ case T_SYMBOL:
227
+ lua_pushstring( L, rb_id2name( SYM2ID(val) ) );
228
+ break;
229
+ // Hash becomes a table
230
+ case T_HASH:
231
+ {
232
+ lua_newtable( L );
233
+ rb_hash_foreach( val, (int (*)(ANYARGS))_rhash_to_table_iter_func, VALUE(L) );
234
+ break;
235
+ }
236
+ // Array becomes a table-array.
237
+ // note in Lua, the first index is 1, whereas in Ruby the first index is 0
238
+ case T_ARRAY:
239
+ {
240
+ long i;
241
+ VALUE array = val;
242
+ lua_newtable( L );
243
+ for ( i = 0; i < RARRAY(array)->len; i++ )
244
+ {
245
+ marshal_ruby_to_lua_top( L, RARRAY(array)->ptr[i] );
246
+ lua_rawseti( L, -2, i+1 ); // Lua is 1-based
247
+ }
248
+ break;
249
+ }
250
+ case T_OBJECT:
251
+ {
252
+ // if it's a Lua::RefObject, put it on the stack
253
+ if ( rb_obj_is_kind_of(val, cLua_RefObject) == Qtrue )
254
+ {
255
+ rlua_RefObject* pRefObject;
256
+ Data_Get_Struct( val, rlua_RefObject, pRefObject );
257
+ if ( pRefObject->getState() != L )
258
+ {
259
+ // TODO: handle this better
260
+ rb_warning( "Marshalling Lua::RefObject between two different states. Pushing nil." );
261
+ break;
262
+ }
263
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
264
+ break;
265
+ }
266
+ // else, flow through to default...
267
+ }
268
+ default:
269
+ // just throw the Ruby object up as a light userdata
270
+ lua_pushlightuserdata( L, (void*)val );
271
+ break;
272
+ }
273
+ return 0;
274
+ }
275
+
276
+
277
+ // dispatches method_missing
278
+ //
279
+ // assumes that the Lua object (RefObject) is on the top of the stack
280
+ // leaves the stack clean and returns the corresponding value
281
+ //
282
+ // an = at the end of the key makes it an assignment
283
+ // an ! at the end of the key makes it a method call with self
284
+ // an _ at the end of the key forces it as a method call without self
285
+ // nothing at the end of the key will make a function call,
286
+ // unless there are no arguments in which case it simply returns obj[key]
287
+ //
288
+ VALUE rlua_method_missing_dispatch( lua_State* L, const char* key, VALUE Rstate, int argc, VALUE* argv )
289
+ {
290
+ int keylen = strlen( key );
291
+
292
+ // if method ends "=", then it's an assignment
293
+ if ( key[keylen-1] == '=' )
294
+ {
295
+ assert( argc >= 2 );
296
+ lua_pushlstring( L, key, keylen-1 ); // strip off =
297
+ marshal_ruby_to_lua_top( L, argv[1] );
298
+ lua_settable( L, -3 );
299
+
300
+ lua_pop( L, 1 );
301
+ return argv[1];
302
+ }
303
+
304
+ //
305
+ // otherwise read the index and return the value or invoke the function
306
+ //
307
+
308
+ // determine any special treatment and retrieve the value
309
+ int pushself = (key[keylen-1] == '!');
310
+ int forcecall = (key[keylen-1] == '_'); // keylen-1 to strip ! or _
311
+ lua_pushlstring( L, key, (pushself || forcecall) ? keylen-1 : keylen );
312
+ lua_gettable( L, -2 );
313
+
314
+ // if there are no arguments (besides self) and the method doesn't ends with a special char
315
+ // and it is not a function, then just return the indexed value.
316
+ if ( !pushself && !forcecall && argc == 1 && (lua_type(L,-1) != LUA_TFUNCTION) )
317
+ {
318
+ // marshal the result to Ruby
319
+ VALUE result = marshal_lua_to_ruby( Rstate, L, -1 );
320
+ lua_pop( L, 2 );
321
+ return result;
322
+ }
323
+
324
+ //
325
+ // otherwise, we're gonna pcall the indexed value
326
+ //
327
+
328
+ // make sure it is callable
329
+ if ( !is_callable(L,-1) )
330
+ {
331
+ int ltype = lua_type( L, -1 );
332
+ lua_pop( L, 2 );
333
+ rb_raise( rb_eRuntimeError,
334
+ "Value is not callable (not a function and no __call metamethod), ltype: %d, key: %s",
335
+ ltype, key );
336
+ }
337
+
338
+ // push the arguments on the stack
339
+ int args_bottom = lua_gettop(L) - 1;
340
+ if ( pushself )
341
+ lua_pushvalue( L, -2 ); // push self as arg with method!
342
+ int i;
343
+ for ( i = 1; i < argc; ++i )
344
+ marshal_ruby_to_lua_top( L, argv[i] );
345
+
346
+ // pcall and handle errors
347
+ int err = lua_pcall( L, (pushself ? argc : argc-1), LUA_MULTRET, 0 );
348
+ if ( err == LUA_ERRRUN ) {
349
+ lua_remove( L, -2 );
350
+ rb_raise( rb_eRuntimeError, pop_error_to_buffer(L) );
351
+ } else if ( err == LUA_ERRMEM ) {
352
+ lua_remove( L, -2 );
353
+ rb_raise( rb_eNoMemError, pop_error_to_buffer(L) );
354
+ } else if ( err == LUA_ERRERR ) {
355
+ lua_remove( L, -2 );
356
+ rb_raise( rb_eFatal, pop_error_to_buffer(L) );
357
+ }
358
+
359
+ // if there is one result, return that alone
360
+ // otherwise put them in an Array
361
+ int args_top = lua_gettop(L);
362
+ int nres = args_top - args_bottom;
363
+ if ( nres == 1 )
364
+ {
365
+ // marshal the result to Ruby
366
+ VALUE result = marshal_lua_to_ruby( Rstate, L, -1 );
367
+ lua_pop( L, 2 );
368
+ return result;
369
+ }
370
+ else
371
+ {
372
+ int li, ri;
373
+ VALUE ary_result = rb_ary_new2( nres );
374
+ for ( li = args_bottom+1, ri = 0; li <= args_top; ++li, ++ri )
375
+ rb_ary_store( ary_result, ri, marshal_lua_to_ruby(Rstate, L, li) );
376
+ lua_pop( L, 1+nres );
377
+ return ary_result;
378
+ }
379
+ }
380
+
381
+
382
+ /// Ruby Hash iterator, mapping pairs into a table
383
+ static int _rhash_to_table_iter_func( VALUE rkey, VALUE rvalue, lua_State* L )
384
+ {
385
+ marshal_ruby_to_lua_top( L, rkey );
386
+ marshal_ruby_to_lua_top( L, rvalue );
387
+ lua_settable( L, -3 );
388
+ return ST_CONTINUE;
389
+ }
390
+
391
+
392
+ // copied from:
393
+ // http://www.lua.org/source/5.1/lbaselib.c.html#luaB_tostring
394
+ static int rluaB_tostring(lua_State *L)
395
+ {
396
+ luaL_checkany(L, 1);
397
+ if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */
398
+ return 1; /* use its value */
399
+ switch (lua_type(L, 1))
400
+ {
401
+ case LUA_TNUMBER:
402
+ lua_pushstring(L, lua_tostring(L, 1));
403
+ break;
404
+ case LUA_TSTRING:
405
+ lua_pushvalue(L, 1);
406
+ break;
407
+ case LUA_TBOOLEAN:
408
+ lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
409
+ break;
410
+ case LUA_TNIL:
411
+ lua_pushliteral(L, "nil");
412
+ break;
413
+ default:
414
+ lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1));
415
+ break;
416
+ }
417
+ return 1;
418
+ }
419
+
420
+
421
+ // mapping of Lua Standard Library names to their registration functions
422
+ static const luaL_Reg rubylua_lualibs[] = {
423
+ {"", luaopen_base},
424
+ {LUA_LOADLIBNAME, luaopen_package},
425
+ {LUA_TABLIBNAME, luaopen_table},
426
+ {LUA_IOLIBNAME, luaopen_io},
427
+ {LUA_OSLIBNAME, luaopen_os},
428
+ {LUA_STRLIBNAME, luaopen_string},
429
+ {LUA_MATHLIBNAME, luaopen_math},
430
+ {LUA_DBLIBNAME, luaopen_debug},
431
+ {NULL, NULL}
432
+ };
433
+
434
+
435
+ /// loads the specified standard Lua library
436
+ void load_std_library_by_name( lua_State* L, const char* libname )
437
+ {
438
+ // special-case: base
439
+ const luaL_Reg* libreg = NULL;
440
+ if ( !strcmp(libname, "base") )
441
+ libreg = &rubylua_lualibs[0];
442
+ // otherwise search for it
443
+ else
444
+ {
445
+ for ( libreg = &rubylua_lualibs[1]; libreg->func; libreg++ )
446
+ if ( !strcmp(libname, libreg->name) )
447
+ break;
448
+ }
449
+
450
+ // register if found
451
+ if ( libreg && libreg->func )
452
+ {
453
+ lua_pushcfunction( L, libreg->func );
454
+ lua_pushstring( L, libreg->name );
455
+ lua_call( L, 1, 0 );
456
+ }
457
+ }
458
+
459
+
460
+
461
+ /*****************************************************************************
462
+
463
+ Document-class: Lua::State
464
+
465
+ The Ruby representation of a lua_State.
466
+
467
+ *****************************************************************************/
468
+
469
+ // Forward declaration
470
+ static VALUE rlua_State_loadlibs( VALUE self, VALUE libs );
471
+
472
+ /* call-seq:
473
+ * Lua::State.new( options )
474
+ *
475
+ * Creates a new Lua::State.
476
+ *
477
+ * _options_ is a hash of options. If no _options_ are specified, the default is { :loadlibs => :all }.
478
+ *
479
+ * <b>loadlibs:</b>
480
+ * Invokes Lua::State.__loadlibs on the new Lua::State, passing the value of :loadlibs.
481
+ *
482
+ * Raises NoMemoryError if the state cannot be allocated, or ArgumentError if the value of :loadlibs
483
+ * is invalid.
484
+ */
485
+ static VALUE rlua_State_initialize( int argc, VALUE* argv, VALUE self )
486
+ {
487
+ rlua_State* pRLState;
488
+ Data_Get_Struct( self, rlua_State, pRLState );
489
+
490
+ // create new Lua state
491
+ pRLState->Lstate.reset( luaL_newstate(), lua_close_deleter() );
492
+ if ( !pRLState->getState() )
493
+ rb_raise( rb_eNoMemError, "lua_State memory allocation failed" );
494
+
495
+ RLB_DEBUG_PRINT( "state init: ptr:%p L:%p\n", pRLState, pRLState->getState() );
496
+
497
+ // if there is no arguments (or nil first value), load all
498
+ if ( argc == 0 || NIL_P(argv[0]) ) {
499
+ luaL_openlibs( pRLState->getState() );
500
+ return self;
501
+ }
502
+ // otherwise, it has to be a hash
503
+ Check_Type( argv[0], T_HASH );
504
+
505
+ // process "loadlibs"
506
+ VALUE libs = rb_hash_aref( argv[0], ID2SYM(rb_intern("loadlibs")) );
507
+ rlua_State_loadlibs( self, libs ); // OK if nil
508
+
509
+ return self;
510
+ }
511
+
512
+
513
+ /// free the lua_State, create with lua_State_alloc
514
+ static void rlua_State_free( rlua_State* pRLState )
515
+ {
516
+ RLB_DEBUG_PRINT( "state free : ptr:%p L:%p\n", pRLState, pRLState->getState() );
517
+ }
518
+
519
+
520
+ /// allocate a new Lua::State
521
+ /// this actually performs the luaL_newstate allocation
522
+ static VALUE rlua_State_alloc( VALUE klass )
523
+ {
524
+ rlua_State* pRLState = new rlua_State();
525
+ if ( !pRLState )
526
+ rb_raise( rb_eNoMemError, "Out of memory when allocating rlua_State" );
527
+ RLB_DEBUG_PRINT( "state malloc: ptr:%p\n", pRLState );
528
+ // wrap it inside a Ruby object
529
+ VALUE obj = Data_Wrap_Struct( klass, NULL, rlua_State_free, pRLState );
530
+ return obj;
531
+ }
532
+
533
+
534
+ /* call-seq:
535
+ * Lua::State.__state -> Lua::State
536
+ *
537
+ * Returns this Lua::State itself.
538
+ *
539
+ * Introduced for parallelism with Lua::RefObject.__state.
540
+ */
541
+ static VALUE rlua_State_state( VALUE self )
542
+ {
543
+ return self;
544
+ }
545
+
546
+
547
+ /* call-seq:
548
+ * Lua::State.__top -> int
549
+ *
550
+ * Return the absolute position of the top of the lua_State's stack.
551
+ *
552
+ * This is mainly for debugging/testing purposes.
553
+ */
554
+ static VALUE rlua_State_top( VALUE self )
555
+ {
556
+ rlua_State* pRLState;
557
+ Data_Get_Struct( self, rlua_State, pRLState );
558
+ int top = lua_gettop( pRLState->getState() );
559
+ return INT2NUM( top );
560
+ }
561
+
562
+
563
+ /* call-seq:
564
+ * Lua::State.__globals -> Lua::Table
565
+ *
566
+ * Returns the globals table of this Lua::State.
567
+ * It is an instance of the Lua::Table class.
568
+ */
569
+ static VALUE rlua_State_globals( VALUE self )
570
+ {
571
+ rlua_State* pRLState;
572
+ Data_Get_Struct( self, rlua_State, pRLState );
573
+ lua_State* L = pRLState->getState();
574
+
575
+ lua_pushvalue( L, LUA_GLOBALSINDEX );
576
+ VALUE result = marshal_lua_to_ruby( self, L, -1 );
577
+ lua_pop( L, 1 );
578
+ return result;
579
+ }
580
+
581
+
582
+ /* call-seq:
583
+ * Lua::State.__registry -> Lua::Table
584
+ *
585
+ * Returns the registry table of this Lua::State.
586
+ * It is an instance of the Lua::Table class.
587
+ *
588
+ * As the Lua Registry is intended for C extensions
589
+ * and the Lua reference system, be careful modifying
590
+ * values stored in this table.
591
+ */
592
+ static VALUE rlua_State_registry( VALUE self )
593
+ {
594
+ rlua_State* pRLState;
595
+ Data_Get_Struct( self, rlua_State, pRLState );
596
+ lua_State* L = pRLState->getState();
597
+
598
+ lua_pushvalue( L, LUA_REGISTRYINDEX );
599
+ VALUE result = marshal_lua_to_ruby( self, L, -1 );
600
+ lua_pop( L, 1 );
601
+ return result;
602
+ }
603
+
604
+
605
+ /* call-seq:
606
+ * Lua::State.__loadlib( libs )
607
+ *
608
+ * Loads the specified Lua standard libraries into the Lua::State.
609
+ *
610
+ * If _libs_ is not specified, all libraries are loaded. Otherwise, if _libs_ is a symbol, that library
611
+ * is loaded. Special symbols are :all, which loads all libraries, and :none which loads no libraries.
612
+ * If _libs_ is an Array, all symbols in the Array are loaded (in the order specified); in this case,
613
+ * :all and :none are ignored; an empty Array will load no libraries. If none of the above fits,
614
+ * an ArgumentError is raised.
615
+ *
616
+ * Supported libraries are:
617
+ * - base
618
+ * - package
619
+ * - table
620
+ * - io
621
+ * - os
622
+ * - string
623
+ * - math
624
+ * - debug
625
+ */
626
+ static VALUE rlua_State_loadlibs( VALUE self, VALUE libs )
627
+ {
628
+ rlua_State* pRLState;
629
+ Data_Get_Struct( self, rlua_State, pRLState );
630
+ lua_State* L = pRLState->getState();
631
+
632
+ // if it is empty or :all, load all
633
+ // if it is a symbol, load that the lib it matches
634
+ // if it is :none, load none
635
+ // if it is an array, load all its symbols (:all is ignored here)
636
+ // otherwise, load none
637
+ if ( NIL_P(libs) )
638
+ {
639
+ luaL_openlibs( L );
640
+ }
641
+ else if ( TYPE(libs) == T_SYMBOL )
642
+ {
643
+ const char* libname = rb_id2name( SYM2ID(libs) );
644
+ if ( !strcmp(libname, "all") )
645
+ luaL_openlibs( L );
646
+ else if ( !strcmp(libname, "none") )
647
+ {} // load none on :none
648
+ else
649
+ load_std_library_by_name( L, libname );
650
+ }
651
+ else if ( TYPE(libs) == T_ARRAY )
652
+ {
653
+ int i;
654
+ for ( i = 0; i < RARRAY(libs)->len; i++ )
655
+ {
656
+ VALUE entry = RARRAY(libs)->ptr[i];
657
+ if ( TYPE(entry) == T_SYMBOL )
658
+ {
659
+ const char* libname = rb_id2name( SYM2ID(entry) );
660
+ load_std_library_by_name( L, libname );
661
+ }
662
+ }
663
+ }
664
+ else
665
+ rb_raise( rb_eArgError, "loadlibs must be Nil, a Symbol, or an Array of symbols" );
666
+
667
+ return self;
668
+ }
669
+
670
+
671
+ /* call-seq:
672
+ * Lua::State.eval -> result
673
+ *
674
+ * Evaluates the passed string in the Lua::State.
675
+ *
676
+ * Returns the first value returned by the evaluation.
677
+ */
678
+ static VALUE rlua_State_eval( VALUE self, VALUE str )
679
+ {
680
+ // verify and marshal Ruby args to C
681
+ rlua_State* pRLState;
682
+ Data_Get_Struct( self, rlua_State, pRLState );
683
+ SafeStringValue(str);
684
+ lua_State* L = pRLState->getState();
685
+
686
+ // process the string to a chunk
687
+ int err = luaL_loadbuffer( L, RSTRING(str)->ptr, RSTRING(str)->len, "Lua::State.eval" );
688
+ if ( err == LUA_ERRMEM )
689
+ rb_raise( rb_eNoMemError, pop_error_to_buffer(L) );
690
+ else if ( err == LUA_ERRSYNTAX )
691
+ rb_raise( rb_eSyntaxError, pop_error_to_buffer(L) );
692
+
693
+ // pcall the chunk, returning only a single argument
694
+ // TODO: error handler with stack traceback
695
+ // TODO: it would be nice to have it configurable whether to print the traceback
696
+ // TODO: hmmm... the err handler could even be in Ruby?
697
+ err = lua_pcall( L, 0, 1, 0 );
698
+ if ( err == LUA_ERRRUN )
699
+ rb_raise( rb_eRuntimeError, pop_error_to_buffer(L) );
700
+ else if ( err == LUA_ERRMEM )
701
+ rb_raise( rb_eNoMemError, pop_error_to_buffer(L) );
702
+ else if ( err == LUA_ERRERR )
703
+ rb_raise( rb_eFatal, pop_error_to_buffer(L) );
704
+
705
+ // marshal the result to Ruby
706
+ VALUE result = marshal_lua_to_ruby( self, L, -1 );
707
+ lua_pop( L, 1 );
708
+ return result;
709
+ }
710
+
711
+
712
+ /* call-seq:
713
+ * Lua::State.eval_mult -> Array
714
+ *
715
+ * Evaluates the passed string in the Lua::State.
716
+ *
717
+ * Returns the all the return values in a Ruby array (with the first result first).
718
+ * If there are no results, an empty array is returned.
719
+ */
720
+ static VALUE rlua_State_eval_mult( VALUE self, VALUE str )
721
+ {
722
+ // verify and marshal Ruby args to C
723
+ rlua_State* pRLState;
724
+ Data_Get_Struct( self, rlua_State, pRLState );
725
+ SafeStringValue(str);
726
+ lua_State* L = pRLState->getState();
727
+ int args_bottom = lua_gettop(L);
728
+
729
+ // process the string to a chunk
730
+ int err = luaL_loadbuffer( L, RSTRING(str)->ptr, RSTRING(str)->len, "Lua::State.eval" );
731
+ if ( err == LUA_ERRMEM )
732
+ rb_raise( rb_eNoMemError, pop_error_to_buffer(L) );
733
+ else if ( err == LUA_ERRSYNTAX )
734
+ rb_raise( rb_eSyntaxError, pop_error_to_buffer(L) );
735
+
736
+ // pcall the chunk, returning only a single argument
737
+ // TODO: error handler with stack traceback
738
+ // TODO: it would be nice to have it configurable whether to print the traceback
739
+ // TODO: hmmm... the err handler could even be in Ruby?
740
+ err = lua_pcall( L, 0, LUA_MULTRET, 0 );
741
+ if ( err == LUA_ERRRUN )
742
+ rb_raise( rb_eRuntimeError, pop_error_to_buffer(L) );
743
+ else if ( err == LUA_ERRMEM )
744
+ rb_raise( rb_eNoMemError, pop_error_to_buffer(L) );
745
+ else if ( err == LUA_ERRERR )
746
+ rb_raise( rb_eFatal, pop_error_to_buffer(L) );
747
+
748
+ // marshal the result to Ruby
749
+ int args_top = lua_gettop(L);
750
+ int nres = args_top - args_bottom;
751
+ int li, ri;
752
+ VALUE ary_res = rb_ary_new2( nres );
753
+ for ( li = args_bottom+1, ri = 0; li <= args_top; ++li, ++ri )
754
+ rb_ary_store( ary_res, ri, marshal_lua_to_ruby(self, L, li) );
755
+ lua_pop( L, nres );
756
+ return ary_res;
757
+ }
758
+
759
+
760
+ /* call-seq:
761
+ * Lua::State.method_missing -> result
762
+ *
763
+ * This method is called by Ruby when it sees an Object can't handle a message.
764
+ * We use it to dispatch to Lua, attempting a lookup of that value in the Lua::State's global table.
765
+ *
766
+ * If the method name has an '<tt>=</tt>' at the end, it is treated as an assignment,
767
+ * in which case it assigns the first value. It returns that value for chaining.
768
+ *
769
+ * The first argument is the symbol of the message name, the rest are its args.
770
+ */
771
+ VALUE rlua_State_method_missing( int argc, VALUE* argv, VALUE self )
772
+ {
773
+ rlua_State* pRLstate;
774
+ Data_Get_Struct( self, rlua_State, pRLstate );
775
+ lua_State* L = pRLstate->getState();
776
+
777
+ Check_Type( argv[0], T_SYMBOL );
778
+ ID methodid = SYM2ID( argv[0] );
779
+ const char* key = rb_id2name( methodid );
780
+
781
+ lua_pushvalue( L, LUA_GLOBALSINDEX );
782
+ return rlua_method_missing_dispatch( L, key, self, argc, argv );
783
+ }
784
+
785
+
786
+ /* call-seq:
787
+ * Lua::State[key] -> value
788
+ *
789
+ * Returns the value indexed at _key_ in the Lua::State's globals table.
790
+ */
791
+ VALUE rlua_State_getindex( VALUE self, VALUE key )
792
+ {
793
+ rlua_State* pRLstate;
794
+ Data_Get_Struct( self, rlua_State, pRLstate );
795
+ lua_State* L = pRLstate->getState();
796
+
797
+ marshal_ruby_to_lua_top( L, key );
798
+ lua_gettable( L, LUA_GLOBALSINDEX );
799
+
800
+ // marshal the result to Ruby
801
+ VALUE result = marshal_lua_to_ruby( self, L, -1 );
802
+ lua_pop( L, 1 );
803
+ return result;
804
+ }
805
+
806
+
807
+ /* call-seq:
808
+ * Lua::State[key] = value -> value
809
+ *
810
+ * Assigns _value_ to be indexed at _key_ in the Lua::State's globals table.
811
+ * Returns the value for chaining.
812
+ */
813
+ VALUE rlua_State_setindex( VALUE self, VALUE key, VALUE val )
814
+ {
815
+ rlua_State* pRLstate;
816
+ Data_Get_Struct( self, rlua_State, pRLstate );
817
+ lua_State* L = pRLstate->getState();
818
+
819
+ marshal_ruby_to_lua_top( L, key );
820
+ marshal_ruby_to_lua_top( L, val );
821
+ lua_settable( L, LUA_GLOBALSINDEX );
822
+
823
+ return val; // return val for chaining
824
+ }
825
+
826
+
827
+ /* call-seq:
828
+ * Lua::State.new_table_at key -> Lua::Table
829
+ *
830
+ * Creates a new table at the given key. Returns the new table.
831
+ */
832
+ VALUE rlua_State_new_table_at( VALUE self, VALUE key )
833
+ {
834
+ rlua_State* pRLstate;
835
+ Data_Get_Struct( self, rlua_State, pRLstate );
836
+ lua_State* L = pRLstate->getState();
837
+
838
+ marshal_ruby_to_lua_top( L, key );
839
+ lua_newtable( L );
840
+
841
+ VALUE result = marshal_lua_to_ruby( self, L, -1 );
842
+ lua_settable( L, LUA_GLOBALSINDEX );
843
+
844
+ return result;
845
+ }
846
+
847
+
848
+ /* call-seq:
849
+ * Lua::State.indexable? -> true
850
+ *
851
+ * Returns whether Lua:State is indexable (via __index), which it is.
852
+ * This is to provide consistency with Lua::RefObject interface.
853
+ */
854
+ VALUE rlua_State_is_indexable( VALUE self )
855
+ {
856
+ return Qtrue;
857
+ }
858
+
859
+
860
+ /* call-seq:
861
+ * Lua::State.new_indexable? -> true
862
+ *
863
+ * Returns whether Lua:State can create new indices (via __newindex), which it can.
864
+ * This is to provide consistency with Lua::RefObject interface.
865
+ */
866
+ VALUE rlua_State_is_new_indexable( VALUE self )
867
+ {
868
+ return Qtrue;
869
+ }
870
+
871
+
872
+ /* call-seq:
873
+ * Lua::State.callable? -> true
874
+ *
875
+ * Returns whether Lua:State is callable (like via __cal), which it is not..
876
+ * This is to provide consistency with Lua::RefObject interface.
877
+ */
878
+ VALUE rlua_State_is_callable( VALUE self )
879
+ {
880
+ return Qfalse;
881
+ }
882
+
883
+
884
+ /*****************************************************************************
885
+
886
+ Document-class: Lua::RefObject
887
+
888
+ The Ruby representation of non-primitive objects in Lua.
889
+
890
+ *****************************************************************************/
891
+
892
+ /* call-seq:
893
+ * Lua::RefObject.new -> result
894
+ *
895
+ * Initializes a new Lua::RefObject.
896
+ *
897
+ * THIS METHOD IS NOT INTENDED TO BE CALLED BY CLIENTS.
898
+ *
899
+ * TODO: Can we enforce the hiding of this? Only Lua module members should access it.
900
+ */
901
+ static VALUE rlua_RefObject_initialize( VALUE self, VALUE Rstate, VALUE RluaRef )
902
+ {
903
+ rlua_RefObject* pRef;
904
+ Data_Get_Struct( self, rlua_RefObject, pRef );
905
+
906
+ RLB_DEBUG_PRINT( "ref init: self:%d Rstate:%p TYPE(Rstate):%d RluaRef:%d TYPE(RluaRef):%d luaRef:%d\n",
907
+ (unsigned long)self, (unsigned long)Rstate, (unsigned long)TYPE(Rstate),
908
+ (unsigned long)RluaRef, (unsigned long)TYPE(RluaRef), NUM2INT(RluaRef) );
909
+
910
+ pRef->Rstate = Rstate;
911
+ pRef->Lref = NUM2INT(RluaRef);
912
+
913
+ rlua_State* pRState;
914
+ Data_Get_Struct( Rstate, rlua_State, pRState );
915
+ pRef->Lstate = pRState->Lstate;
916
+
917
+ return self;
918
+ }
919
+
920
+
921
+ /// free the Lua::RefObject, created with lua_RefObject_alloc
922
+ static void rlua_RefObject_free( rlua_RefObject* pRefObject )
923
+ {
924
+ RLB_DEBUG_PRINT( "ref free: ptr:%p ref:%d L:%p\n", pRefObject, pRefObject->Lref, pRefObject->getState() );
925
+ assert( pRefObject != NULL );
926
+ luaL_unref( pRefObject->getState(), LUA_REGISTRYINDEX, pRefObject->Lref );
927
+
928
+ delete pRefObject;
929
+ }
930
+
931
+
932
+ /// allocate a new Lua::RefObject
933
+ static VALUE rlua_RefObject_alloc( VALUE klass )
934
+ {
935
+ rlua_RefObject* pRef = new rlua_RefObject();
936
+ if ( !pRef )
937
+ rb_raise( rb_eNoMemError, "Out of memory when allocating rlua_RefObject" );
938
+ // pRef->Lstate = NULL;
939
+ pRef->Lref = LUA_NOREF;
940
+ pRef->Rstate = Qnil;
941
+
942
+ // wrap it inside a Ruby object
943
+ //rlua_RefObject_mark
944
+ VALUE obj = Data_Wrap_Struct( klass, NULL, rlua_RefObject_free, pRef );
945
+ return obj;
946
+ }
947
+
948
+
949
+ /* call-seq:
950
+ * Lua::RefObject.__state -> Lua::State
951
+ *
952
+ * Returns the Lua::State this Lua::RefObject belongs to.
953
+ */
954
+ static VALUE rlua_RefObject_state( VALUE self )
955
+ {
956
+ rlua_RefObject* pRefObject;
957
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
958
+
959
+ return pRefObject->Rstate;
960
+ }
961
+
962
+
963
+ /* call-seq:
964
+ * Lua::RefObject.method_missing -> result
965
+ *
966
+ * This method is called by Ruby when it sees an Object can't handle a message.
967
+ * We use it to dispatch to Lua, attempting a lookup of that value in the Lua::RefObject.
968
+ *
969
+ * The first argument is the symbol of the message name, the rest are its args.
970
+
971
+ * If the method name has an <tt>=</tt> at the end, it is treated as an assignment,
972
+ * in which case it assigns the first value. It returns that value for chaining.
973
+ *
974
+ * If the method name has a '<tt>_</tt>' at the end, it is treated as an method invocation,
975
+ * passing itself as a parameter. This is to emulate the '<tt>:</tt>' token used in Lua.
976
+ */
977
+ VALUE rlua_RefObject_method_missing( int argc, VALUE* argv, VALUE self )
978
+ {
979
+ rlua_RefObject* pRefObject;
980
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
981
+ lua_State* L = pRefObject->getState();
982
+
983
+ Check_Type( argv[0], T_SYMBOL );
984
+ ID methodid = SYM2ID( argv[0] );
985
+ const char* key = rb_id2name( methodid );
986
+
987
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
988
+ if ( !is_indexable(L, -1) )
989
+ {
990
+ lua_pop(L, 1);
991
+ rb_raise( rb_eRuntimeError, "Lua::RefObject not indexable, key='%s'", key );
992
+ }
993
+
994
+ return rlua_method_missing_dispatch( L, key, pRefObject->Rstate, argc, argv );
995
+ }
996
+
997
+
998
+ /* call-seq:
999
+ * Lua::RefObject.__length -> int
1000
+ *
1001
+ * Returns the 'length' of the RefObject.
1002
+ *
1003
+ * According to the {Lua manual}[http://www.lua.org/manual/5.1/manual.html#lua_objlen]:
1004
+ * Returns the "length" of the value at the given acceptable index:
1005
+ * for strings, this is the string length; for tables, this is the result
1006
+ * of the length operator ('#'); for userdata, this is the size of the
1007
+ * block of memory allocated for the userdata; for other values, it is 0.
1008
+ */
1009
+ VALUE rlua_RefObject_length( VALUE self )
1010
+ {
1011
+ rlua_RefObject* pRefObject;
1012
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1013
+ lua_State* L = pRefObject->getState();
1014
+
1015
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1016
+ size_t len = lua_objlen(L, -1);
1017
+ lua_pop( L, 1 );
1018
+
1019
+ VALUE result = INT2NUM(len);
1020
+ return result;
1021
+ }
1022
+
1023
+
1024
+ /* call-seq:
1025
+ * Lua::RefObject.__type -> int
1026
+ *
1027
+ * Returns the type id of the underlying Lua object.
1028
+ */
1029
+ VALUE rlua_RefObject_type( VALUE self )
1030
+ {
1031
+ rlua_RefObject* pRefObject;
1032
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1033
+ lua_State* L = pRefObject->getState();
1034
+
1035
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1036
+ size_t len = lua_type(L, -1);
1037
+ lua_pop( L, 1 );
1038
+
1039
+ VALUE result = INT2NUM(len);
1040
+ return result;
1041
+ }
1042
+
1043
+
1044
+ /* call-seq:
1045
+ * Lua::RefObject.__metatable -> Lua::Table
1046
+ *
1047
+ * Returns the metatable of the underlying Lua object.
1048
+ * Return nil if it has no metatable.
1049
+ */
1050
+ VALUE rlua_RefObject_getmetatable( VALUE self )
1051
+ {
1052
+ rlua_RefObject* pRefObject;
1053
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1054
+ lua_State* L = pRefObject->getState();
1055
+
1056
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1057
+
1058
+ if (lua_getmetatable(L, -1) == 0)
1059
+ lua_pushnil( L );
1060
+
1061
+ VALUE result = marshal_lua_to_ruby( pRefObject->Rstate, L, -1 );
1062
+ lua_pop( L, 2 );
1063
+ return result;
1064
+ }
1065
+
1066
+
1067
+ /* call-seq:
1068
+ * Lua::RefObject.__metatable= Lua::Table -> Lua::Table
1069
+ *
1070
+ * Sets the metatable for this Lua::RefObject.
1071
+ * Returns the passed metatable.
1072
+ */
1073
+ VALUE rlua_RefObject_setmetatable( VALUE self, VALUE mtable )
1074
+ {
1075
+ rlua_RefObject* pRefObject;
1076
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1077
+ lua_State* L = pRefObject->getState();
1078
+
1079
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1080
+
1081
+ marshal_ruby_to_lua_top( L, mtable );
1082
+ lua_setmetatable( L, -2 );
1083
+
1084
+ lua_pop( L, 1 );
1085
+ return mtable;
1086
+ }
1087
+
1088
+
1089
+ /* call-seq:
1090
+ * Lua::RefObject.[key] -> value
1091
+ *
1092
+ * Returns the value indexed at _key_ in the RefObject.
1093
+ *
1094
+ * Raises RuntimeError if the RefObject is not indexable.
1095
+ */
1096
+ VALUE rlua_RefObject_getindex( VALUE self, VALUE key )
1097
+ {
1098
+ rlua_RefObject* pRefObject;
1099
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1100
+ lua_State* L = pRefObject->getState();
1101
+
1102
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1103
+ if ( !is_indexable(L, -1) )
1104
+ {
1105
+ lua_pop( L, 1 );
1106
+ rb_raise( rb_eRuntimeError, "(getindex) Lua::RefObject not indexable" );
1107
+ }
1108
+
1109
+ marshal_ruby_to_lua_top( L, key );
1110
+ lua_gettable( L, -2 );
1111
+
1112
+ // marshal the result to Ruby
1113
+ VALUE result = marshal_lua_to_ruby( pRefObject->Rstate, L, -1 );
1114
+ lua_pop( L, 2 );
1115
+ return result;
1116
+ }
1117
+
1118
+
1119
+ /* call-seq:
1120
+ * Lua::RefObject.[key] = value -> value
1121
+ *
1122
+ * Assigns _value_ to be indexed at _key_ in the RefObject.
1123
+ * Returns the value for chaining.
1124
+ *
1125
+ * Raises RuntimeError if the RefObject is not indexable.
1126
+ */
1127
+ VALUE rlua_RefObject_setindex( VALUE self, VALUE key, VALUE val )
1128
+ {
1129
+ rlua_RefObject* pRefObject;
1130
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1131
+ lua_State* L = pRefObject->getState();
1132
+
1133
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1134
+ if ( !is_indexable(L, -1) )
1135
+ {
1136
+ lua_pop( L, 1 );
1137
+ rb_raise( rb_eRuntimeError, "(setindex) Lua::RefObject not indexable" );
1138
+ }
1139
+
1140
+ marshal_ruby_to_lua_top( L, key );
1141
+ marshal_ruby_to_lua_top( L, val );
1142
+ lua_settable( L, -3 );
1143
+
1144
+ lua_pop( L, 1 );
1145
+ return val; // return val for chaining
1146
+ }
1147
+
1148
+
1149
+ /* call-seq:
1150
+ * Lua::RefObject.new_table_at key -> Lua::Table
1151
+ *
1152
+ * Creates a new table at the given key. Returns the new table.
1153
+ *
1154
+ * Raises RuntimeError if the RefObject is not indexable.
1155
+ */
1156
+ VALUE rlua_RefObject_new_table_at( VALUE self, VALUE key )
1157
+ {
1158
+ rlua_RefObject* pRefObject;
1159
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1160
+ lua_State* L = pRefObject->getState();
1161
+
1162
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1163
+ if ( !is_indexable(L, -1) )
1164
+ {
1165
+ lua_pop( L, 1 );
1166
+ rb_raise( rb_eRuntimeError, "(setindex) Lua::RefObject not indexable" );
1167
+ }
1168
+
1169
+ marshal_ruby_to_lua_top( L, key );
1170
+ lua_newtable( L );
1171
+
1172
+ VALUE result = marshal_lua_to_ruby( pRefObject->Rstate, L, -1 );
1173
+ lua_settable( L, -3 );
1174
+
1175
+ lua_pop( L, 1 );
1176
+ return result;
1177
+ }
1178
+
1179
+
1180
+ /* call-seq:
1181
+ * Lua::RefObject.to_s -> string
1182
+ *
1183
+ * Invokes the Lua function {tostring}[http://www.lua.org/manual/5.1/manual.html#pdf-tostring]
1184
+ * on the object and returns the resulting string.
1185
+ */
1186
+ VALUE rlua_RefObject_to_s( VALUE self )
1187
+ {
1188
+ rlua_RefObject* pRefObject;
1189
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1190
+ lua_State* L = pRefObject->getState();
1191
+
1192
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1193
+ rluaB_tostring( L );
1194
+
1195
+ VALUE result = marshal_lua_to_ruby( pRefObject->Rstate, L, -1 );
1196
+
1197
+ lua_pop( L, 2 );
1198
+ return result;
1199
+ }
1200
+
1201
+
1202
+ /* call-seq:
1203
+ * Lua::RefObject.indexable? -> true
1204
+ *
1205
+ * Returns whether Lua:State is indexable (via __index), which it is.
1206
+ * This is to provide consistency with Lua::RefObject interface.
1207
+ */
1208
+ VALUE rlua_RefObject_is_indexable( VALUE self )
1209
+ {
1210
+ rlua_RefObject* pRefObject;
1211
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1212
+ lua_State* L = pRefObject->getState();
1213
+
1214
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1215
+ VALUE result = is_indexable(L, -1) ? Qtrue : Qfalse;
1216
+
1217
+ lua_pop( L, 1 );
1218
+ return result;
1219
+ }
1220
+
1221
+
1222
+ /* call-seq:
1223
+ * Lua::RefObject.new_indexable? -> true
1224
+ *
1225
+ * Returns whether Lua:State can create new indices (via __newindex), which it can.
1226
+ * This is to provide consistency with Lua::RefObject interface.
1227
+ */
1228
+ VALUE rlua_RefObject_is_new_indexable( VALUE self )
1229
+ {
1230
+ rlua_RefObject* pRefObject;
1231
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1232
+ lua_State* L = pRefObject->getState();
1233
+
1234
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1235
+ VALUE result = is_new_indexable(L, -1) ? Qtrue : Qfalse;
1236
+
1237
+ lua_pop( L, 1 );
1238
+ return result;
1239
+ }
1240
+
1241
+
1242
+ /* call-seq:
1243
+ * Lua::State.indexable? -> true
1244
+ *
1245
+ * Returns whether Lua:State is callable (like via __cal), which it is not..
1246
+ * This is to provide consistency with Lua::RefObject interface.
1247
+ */
1248
+ VALUE rlua_RefObject_is_callable( VALUE self )
1249
+ {
1250
+ rlua_RefObject* pRefObject;
1251
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1252
+ lua_State* L = pRefObject->getState();
1253
+
1254
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1255
+ VALUE result = is_callable(L, -1) ? Qtrue : Qfalse;
1256
+
1257
+ lua_pop( L, 1 );
1258
+ return result;
1259
+ }
1260
+
1261
+
1262
+
1263
+ /*****************************************************************************
1264
+
1265
+ Document-class: Lua::Table
1266
+
1267
+ When Rua marshals a Lua table to Ruby, it instantiates it as a Lua::Table.
1268
+
1269
+ This gives it some extra methods that aren't available to a regular Lua::RefObject.
1270
+
1271
+ *****************************************************************************/
1272
+
1273
+ /////////////////////////////////
1274
+ ///// LUA::TABLE CONVERSION
1275
+
1276
+ /* call-seq:
1277
+ * Lua::Table.to_array -> Array
1278
+ *
1279
+ * Returns a Ruby Array of the (first, dense) integer keys in the Table.
1280
+ */
1281
+ VALUE rlua_Table_to_array( VALUE self )
1282
+ {
1283
+ rlua_RefObject* pRefObject;
1284
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1285
+ lua_State* L = pRefObject->getState();
1286
+
1287
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1288
+ int tablelen = lua_objlen( L, -1 );
1289
+
1290
+ VALUE array = rb_ary_new2( tablelen );
1291
+ int i;
1292
+ for ( i = 1; i <= tablelen; ++i )
1293
+ {
1294
+ lua_rawgeti( L, -1, i );
1295
+ VALUE rvalue = marshal_lua_to_ruby( pRefObject->Rstate, L, -1 );
1296
+ rb_ary_push( array, rvalue );
1297
+ lua_pop( L, 1 );
1298
+ }
1299
+
1300
+ lua_pop( L, 1 );
1301
+ return array;
1302
+ }
1303
+
1304
+
1305
+ /* call-seq:
1306
+ * Lua::Table.to_hash -> Hash
1307
+ *
1308
+ * Returns a Ruby Hash of all pairs in the table.
1309
+ */
1310
+ VALUE rlua_Table_to_hash( VALUE self )
1311
+ {
1312
+ rlua_RefObject* pRefObject;
1313
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1314
+ lua_State* L = pRefObject->getState();
1315
+
1316
+ VALUE hash = rb_hash_new();
1317
+
1318
+ // table is in the stack at index 't'
1319
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1320
+ int table = lua_gettop( L );
1321
+ lua_pushnil( L ); // first key
1322
+ while ( lua_next(L, table) != 0 )
1323
+ {
1324
+ // uses 'key' (at index -2) and 'value' (at index -1)
1325
+ VALUE rvalue = marshal_lua_to_ruby( pRefObject->Rstate, L, -1 );
1326
+ VALUE rkey = marshal_lua_to_ruby( pRefObject->Rstate, L, -2 );
1327
+ rb_hash_aset( hash, rkey, rvalue );
1328
+ // removes 'value'; keeps 'key' for next iteration
1329
+ lua_pop( L, 1 );
1330
+ }
1331
+
1332
+ lua_pop( L, 1 );
1333
+ return hash;
1334
+ }
1335
+
1336
+
1337
+ /////////////////////////////////
1338
+ ///// LUA::TABLE HASH ITERATION
1339
+
1340
+ /* call-seq:
1341
+ * Lua::Table.each { |key,value| block } -> Lua::Table
1342
+ * Lua::Table.each_pair { |key,value| block } -> Lua::Table
1343
+ *
1344
+ * Calls _block_ once for each key in _table_, passing the key and value as parameters.
1345
+ *
1346
+ * This goes over all pairs in the table.
1347
+ */
1348
+ VALUE rlua_Table_each_pair( VALUE self )
1349
+ {
1350
+ rlua_RefObject* pRefObject;
1351
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1352
+ lua_State* L = pRefObject->getState();
1353
+
1354
+ // table is in the stack at index 't'
1355
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1356
+ int table = lua_gettop( L );
1357
+ lua_pushnil( L ); // first key
1358
+ while ( lua_next(L, table) != 0 )
1359
+ {
1360
+ // uses 'key' (at index -2) and 'value' (at index -1)
1361
+ VALUE rvalue = marshal_lua_to_ruby( pRefObject->Rstate, L, -1 );
1362
+ VALUE rkey = marshal_lua_to_ruby( pRefObject->Rstate, L, -2 );
1363
+ rb_yield_values( 2, rkey, rvalue );
1364
+ // removes 'value'; keeps 'key' for next iteration
1365
+ lua_pop( L, 1 );
1366
+ }
1367
+
1368
+ lua_pop( L, 1 );
1369
+ return self;
1370
+ }
1371
+
1372
+
1373
+ /* call-seq:
1374
+ * Lua::Table.each_key { |key| block } -> Lua::Table
1375
+ *
1376
+ * Calls _block_ once for each key in _table_, passing the key to the block as a parameter.
1377
+ *
1378
+ * This goes over all pairs in the table.
1379
+ */
1380
+ VALUE rlua_Table_each_key( VALUE self )
1381
+ {
1382
+ rlua_RefObject* pRefObject;
1383
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1384
+ lua_State* L = pRefObject->getState();
1385
+
1386
+ // table is in the stack at index 't'
1387
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1388
+ int table = lua_gettop( L );
1389
+ lua_pushnil( L ); // first key
1390
+ while ( lua_next(L, table) != 0 )
1391
+ {
1392
+ // uses 'key' (at index -2) and 'value' (at index -1)
1393
+ VALUE rkey = marshal_lua_to_ruby( pRefObject->Rstate, L, -2 );
1394
+ rb_yield( rkey );
1395
+ // removes 'value'; keeps 'key' for next iteration
1396
+ lua_pop( L, 1 );
1397
+ }
1398
+
1399
+ lua_pop( L, 1 );
1400
+ return self;
1401
+ }
1402
+
1403
+
1404
+ /* call-seq:
1405
+ * Lua::Table.each_value { |value| block } -> Lua::Table
1406
+ *
1407
+ * Calls _block_ once for each key in _table_, passing the value to the block as a parameter.
1408
+ *
1409
+ * This goes over all pairs in the table.
1410
+ */
1411
+ VALUE rlua_Table_each_value( VALUE self )
1412
+ {
1413
+ rlua_RefObject* pRefObject;
1414
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1415
+ lua_State* L = pRefObject->getState();
1416
+
1417
+ // table is in the stack at index 't'
1418
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1419
+ int table = lua_gettop( L );
1420
+ lua_pushnil( L ); // first key
1421
+ while ( lua_next(L, table) != 0 )
1422
+ {
1423
+ // uses 'key' (at index -2) and 'value' (at index -1)
1424
+ VALUE rvalue = marshal_lua_to_ruby( pRefObject->Rstate, L, -1 );
1425
+ rb_yield( rvalue );
1426
+ // removes 'value'; keeps 'key' for next iteration
1427
+ lua_pop( L, 1 );
1428
+ }
1429
+
1430
+ lua_pop( L, 1 );
1431
+ return self;
1432
+ }
1433
+
1434
+
1435
+ /////////////////////////
1436
+ ///// ARRAY ITERATION
1437
+
1438
+ /* call-seq:
1439
+ * Lua::Table.each_ipair { |key,value| block } -> Lua::Table
1440
+ *
1441
+ * Calls _block_ once for each integer key in _table_, passing the key and value as parameters.
1442
+ *
1443
+ * This goes over all integer pairs in the table. Similar to ipairs(), this
1444
+ * only touches the first #table integers, thus treating the table like a dense array.
1445
+ */
1446
+ VALUE rlua_Table_each_ipair( VALUE self )
1447
+ {
1448
+ rlua_RefObject* pRefObject;
1449
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1450
+ lua_State* L = pRefObject->getState();
1451
+
1452
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1453
+ int tablelen = lua_objlen( L, -1 );
1454
+ int i;
1455
+ for ( i = 1; i <= tablelen; ++i )
1456
+ {
1457
+ lua_rawgeti( L, -1, i );
1458
+ VALUE rvalue = marshal_lua_to_ruby( pRefObject->Rstate, L, -1 );
1459
+ rb_yield_values( 2, INT2NUM(i), rvalue );
1460
+ lua_pop( L, 1 );
1461
+ }
1462
+
1463
+ lua_pop( L, 1 );
1464
+
1465
+ return self;
1466
+ }
1467
+
1468
+
1469
+ /* call-seq:
1470
+ * Lua::Table.each_index { |key| block } -> Lua::Table
1471
+ * Lua::Table.each_ikey { |key| block } -> Lua::Table
1472
+ *
1473
+ * Calls _block_ once for each integer key in _table_, passing the key to the block as a parameter.
1474
+ *
1475
+ * This goes over all integer pairs in the table. Similar to ipairs(), this
1476
+ * only touches the first #table integers, thus treating the table like a dense array.
1477
+ */
1478
+ VALUE rlua_Table_each_ikey( VALUE self )
1479
+ {
1480
+ rlua_RefObject* pRefObject;
1481
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1482
+ lua_State* L = pRefObject->getState();
1483
+
1484
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1485
+ int tablelen = lua_objlen( L, -1 );
1486
+ int i;
1487
+ for ( i = 1; i <= tablelen; ++i )
1488
+ {
1489
+ lua_rawgeti( L, -1, i );
1490
+ rb_yield( INT2NUM(i) );
1491
+ lua_pop( L, 1 );
1492
+ }
1493
+
1494
+ lua_pop( L, 1 );
1495
+
1496
+ return self;
1497
+ }
1498
+
1499
+
1500
+ /* call-seq:
1501
+ * Lua::Table.each_ivalue { |value| block } -> Lua::Table
1502
+ *
1503
+ * Calls _block_ once for each integer key in _table_, passing the value to the block as a parameter.
1504
+ *
1505
+ * This goes over all integer pairs in the table. Similar to ipairs(), this
1506
+ * only touches the first #table integers, thus treating the table like a dense array.
1507
+ */
1508
+ VALUE rlua_Table_each_ivalue( VALUE self )
1509
+ {
1510
+ rlua_RefObject* pRefObject;
1511
+ Data_Get_Struct( self, rlua_RefObject, pRefObject );
1512
+ lua_State* L = pRefObject->getState();
1513
+
1514
+ lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
1515
+ int tablelen = lua_objlen( L, -1 );
1516
+ int i;
1517
+ for ( i = 1; i <= tablelen; ++i )
1518
+ {
1519
+ lua_rawgeti( L, -1, i );
1520
+ VALUE rvalue = marshal_lua_to_ruby( pRefObject->Rstate, L, -1 );
1521
+ rb_yield( rvalue );
1522
+ lua_pop( L, 1 );
1523
+ }
1524
+
1525
+ lua_pop( L, 1 );
1526
+
1527
+ return self;
1528
+ }
1529
+
1530
+
1531
+
1532
+ /*****************************************************************************/
1533
+ //
1534
+ // Extension Initialization
1535
+ //
1536
+ /*****************************************************************************/
1537
+
1538
+ extern "C" {
1539
+ /*
1540
+ Document-module: Lua
1541
+
1542
+ The module where all of the RubyLuaBridge components live.
1543
+ */
1544
+ void Init_rubyluabridge()
1545
+ {
1546
+ // Lua module
1547
+ mLua = rb_define_module( "Lua" );
1548
+ rb_define_const( mLua, "BRIDGE_VERSION", rb_str_new2( RUBYLUABRIDGE_VERSION ) );
1549
+ rb_define_const( mLua, "BRIDGE_VERSION_NUM", INT2FIX( RUBYLUABRIDGE_VERSION_NUM ) );
1550
+ rb_define_const( mLua, "LUA_VERSION", rb_str_new2( LUA_VERSION ) );
1551
+ rb_define_const( mLua, "LUA_RELEASE", rb_str_new2( LUA_RELEASE ) );
1552
+
1553
+ rb_define_const( mLua, "TNONE", INT2FIX( LUA_TNONE ) );
1554
+ rb_define_const( mLua, "TNIL", INT2FIX( LUA_TNIL ) );
1555
+ rb_define_const( mLua, "TBOOLEAN", INT2FIX( LUA_TBOOLEAN ) );
1556
+ rb_define_const( mLua, "TLIGHTUSERDATA", INT2FIX( LUA_TLIGHTUSERDATA ) );
1557
+ rb_define_const( mLua, "TNUMBER", INT2FIX( LUA_TNUMBER ) );
1558
+ rb_define_const( mLua, "TSTRING", INT2FIX( LUA_TSTRING ) );
1559
+ rb_define_const( mLua, "TTABLE", INT2FIX( LUA_TTABLE ) );
1560
+ rb_define_const( mLua, "TFUNCTION", INT2FIX( LUA_TFUNCTION ) );
1561
+ rb_define_const( mLua, "TUSERDATA", INT2FIX( LUA_TUSERDATA ) );
1562
+ rb_define_const( mLua, "TTHREAD", INT2FIX( LUA_TTHREAD ) );
1563
+
1564
+ // Lua::State class
1565
+ cLua_State = rb_define_class_under( mLua, "State", rb_cObject );
1566
+ rb_define_alloc_func( cLua_State, rlua_State_alloc );
1567
+ rb_define_method( cLua_State, "initialize", RUBY_METHOD_FUNC(rlua_State_initialize), -1 );
1568
+ rb_define_method( cLua_State, "method_missing", RUBY_METHOD_FUNC(rlua_State_method_missing), -1 );
1569
+ rb_define_method( cLua_State, "__state", RUBY_METHOD_FUNC(rlua_State_state), 0 );
1570
+ rb_define_method( cLua_State, "__top", RUBY_METHOD_FUNC(rlua_State_top), 0 );
1571
+ rb_define_method( cLua_State, "__globals", RUBY_METHOD_FUNC(rlua_State_globals), 0 );
1572
+ rb_define_method( cLua_State, "__registry", RUBY_METHOD_FUNC(rlua_State_registry), 0 );
1573
+ rb_define_method( cLua_State, "__loadlibs", RUBY_METHOD_FUNC(rlua_State_loadlibs), 1 );
1574
+ rb_define_method( cLua_State, "new_table_at", RUBY_METHOD_FUNC(rlua_State_new_table_at), 1 );
1575
+ rb_define_method( cLua_State, "[]", RUBY_METHOD_FUNC(rlua_State_getindex), 1 );
1576
+ rb_define_method( cLua_State, "[]=", RUBY_METHOD_FUNC(rlua_State_setindex), 2 );
1577
+ rb_define_method( cLua_State, "eval", RUBY_METHOD_FUNC(rlua_State_eval), 1 );
1578
+ rb_define_method( cLua_State, "eval_mult", RUBY_METHOD_FUNC(rlua_State_eval_mult), 1 );
1579
+ rb_define_method( cLua_State, "callable?", RUBY_METHOD_FUNC(rlua_State_is_callable), 0 );
1580
+ rb_define_method( cLua_State, "indexable?", RUBY_METHOD_FUNC(rlua_State_is_indexable), 0 );
1581
+ rb_define_method( cLua_State, "new_indexable?", RUBY_METHOD_FUNC(rlua_State_is_new_indexable), 0 );
1582
+ // TODO: more methods!
1583
+
1584
+ // rb_define_method( cLua_State, "execute", lua_State_eval, 1 );
1585
+ // rb_define_method( cLua_State, "execute_mult", lua_State_eval_mult, 1 );
1586
+
1587
+ // Lua::RefObject class
1588
+ cLua_RefObject = rb_define_class_under( mLua, "RefObject", rb_cObject );
1589
+ rb_define_alloc_func( cLua_RefObject, rlua_RefObject_alloc );
1590
+ rb_define_method( cLua_RefObject, "initialize", RUBY_METHOD_FUNC(rlua_RefObject_initialize), 2 );
1591
+ rb_define_method( cLua_RefObject, "method_missing", RUBY_METHOD_FUNC(rlua_RefObject_method_missing), -1 );
1592
+ rb_define_method( cLua_RefObject, "__state", RUBY_METHOD_FUNC(rlua_RefObject_state), 0 );
1593
+ rb_define_method( cLua_RefObject, "__length", RUBY_METHOD_FUNC(rlua_RefObject_length), 0 );
1594
+ rb_define_method( cLua_RefObject, "__type", RUBY_METHOD_FUNC(rlua_RefObject_type), 0 );
1595
+ rb_define_method( cLua_RefObject, "__metatable", RUBY_METHOD_FUNC(rlua_RefObject_getmetatable), 0 );
1596
+ rb_define_method( cLua_RefObject, "__metatable=", RUBY_METHOD_FUNC(rlua_RefObject_setmetatable), 1 );
1597
+ rb_define_method( cLua_RefObject, "[]", RUBY_METHOD_FUNC(rlua_RefObject_getindex), 1 );
1598
+ rb_define_method( cLua_RefObject, "[]=", RUBY_METHOD_FUNC(rlua_RefObject_setindex), 2 );
1599
+ rb_define_method( cLua_RefObject, "new_table_at", RUBY_METHOD_FUNC(rlua_RefObject_new_table_at), 1 );
1600
+ rb_define_method( cLua_RefObject, "to_s", RUBY_METHOD_FUNC(rlua_RefObject_to_s), 0 );
1601
+ rb_define_method( cLua_RefObject, "method_missing", RUBY_METHOD_FUNC(rlua_RefObject_method_missing), -1 );
1602
+ rb_undef_method( cLua_RefObject, "type" );
1603
+ rb_undef_method( cLua_RefObject, "id" );
1604
+ rb_define_method( cLua_RefObject, "callable?", RUBY_METHOD_FUNC(rlua_RefObject_is_callable), 0 );
1605
+ rb_define_method( cLua_RefObject, "indexable?", RUBY_METHOD_FUNC(rlua_RefObject_is_indexable), 0 );
1606
+ rb_define_method( cLua_RefObject, "new_indexable?", RUBY_METHOD_FUNC(rlua_RefObject_is_new_indexable), 0 );
1607
+
1608
+ // Lua::Table class
1609
+ cLua_Table = rb_define_class_under( mLua, "Table", cLua_RefObject );
1610
+ rb_define_method( cLua_Table, "to_array", RUBY_METHOD_FUNC(rlua_Table_to_array), 0 );
1611
+ rb_define_method( cLua_Table, "to_hash", RUBY_METHOD_FUNC(rlua_Table_to_hash), 0 );
1612
+ rb_define_method( cLua_Table, "each_ipair", RUBY_METHOD_FUNC(rlua_Table_each_ipair), 0 );
1613
+ rb_define_method( cLua_Table, "each_ikey", RUBY_METHOD_FUNC(rlua_Table_each_ikey), 0 );
1614
+ rb_define_method( cLua_Table, "each_ivalue", RUBY_METHOD_FUNC(rlua_Table_each_ivalue), 0 );
1615
+ rb_define_method( cLua_Table, "each_pair", RUBY_METHOD_FUNC(rlua_Table_each_pair), 0 );
1616
+ rb_define_method( cLua_Table, "each_key", RUBY_METHOD_FUNC(rlua_Table_each_key), 0 );
1617
+ rb_define_method( cLua_Table, "each_value", RUBY_METHOD_FUNC(rlua_Table_each_value), 0 );
1618
+ rb_define_alias( cLua_Table, "each", "each_pair" );
1619
+ rb_define_alias( cLua_Table, "each_index", "each_ikey" );
1620
+ }
1621
+
1622
+ } // extern "C"
1623
+