Develop and Download Open Source Software

Browse CVS Repository

Contents of /netruby/netruby/node.cs

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1.1.1 - (show annotations) (download) (vendor branch)
Mon Apr 8 13:28:17 2002 UTC (22 years ago) by arton
Branch: MAIN, vendor
CVS Tags: start, HEAD
Changes since 1.1: +0 -0 lines
initial version 0.8

1 /*
2 Copyright(C) 2001-2002 arton
3
4 Permission is granted for use, copying, modification, distribution,
5 and distribution of modified versions of this work as long as the
6 above copyright notice is included.
7 */
8
9 using System;
10 using System.IO;
11 using System.Text;
12 using System.Reflection;
13 using System.Reflection.Emit;
14 using System.Collections;
15 using System.Security;
16
17 namespace arton.NETRuby
18 {
19 public enum NOEX
20 {
21 PUBLIC = 0,
22 UNDEF = 1,
23 CFUNC = 1,
24 PRIVATE = 2,
25 PROTECTED = 4,
26 }
27
28 public class ILParam : IDisposable
29 {
30 internal ILParam(TypeBuilder tb, MethodBuilder mb)
31 {
32 methodList = null;
33 init(tb, mb);
34 }
35 internal ILParam(ILParam pm)
36 {
37 tb = pm.tb;
38 mb = pm.mb;
39 il = pm.il;
40 th = pm.th;
41 result = pm.result;
42 idx = pm.idx;
43 curr = pm.curr;
44 argcnt = pm.argcnt;
45 argopt = pm.argopt;
46 args = pm.args;
47 iters = pm.iters;
48 canreturn = pm.canreturn;
49 methodList = pm.methodList;
50 }
51 void init(TypeBuilder tb, MethodBuilder mb)
52 {
53 this.tb = tb;
54 this.mb = mb;
55 this.il = mb.GetILGenerator();
56 il.BeginScope();
57 th = null;
58 result = null;
59 idx = null;
60 curr = -1;
61 argcnt = argopt = 0;
62 args = new ArrayList();
63 iters = new Stack();
64 canreturn = false;
65 }
66 public void Dispose()
67 {
68 Dispose(true);
69 GC.SuppressFinalize(this);
70 }
71 protected bool disposed;
72 ~ILParam()
73 {
74 Dispose(false);
75 }
76 protected virtual void Dispose(bool disposing)
77 {
78 if (!disposed)
79 {
80 il.EndScope();
81 il.Emit(OpCodes.Ret);
82 disposed = true;
83 }
84 }
85 internal LocalBuilder Args { get { return ((ArgBlock)args[curr]).Args; } }
86 internal void SaveReceiver()
87 {
88 ((ArgBlock)args[curr]).SaveReceiver(il);
89 }
90 internal LocalBuilder Receiver
91 {
92 get { return ((ArgBlock)args[curr]).receiver; }
93 }
94 internal void OpenIterBlock(Type tp)
95 {
96 iters.Push(new IterBlock(this, tp, iters.Count));
97 }
98 internal void CloseIterBlock()
99 {
100 IterBlock ib = (IterBlock)iters.Pop();
101 ib.Close(this);
102 }
103 internal void SetupArgs(int n)
104 {
105 curr++;
106 if (args.Count == curr)
107 {
108 args.Add(new ArgBlock(il, curr));
109 }
110 ((ArgBlock)args[curr]).CreateArray(il, n);
111 if (n > 0)
112 {
113 AdjustBlock();
114 }
115 }
116 internal void CleanupArgs(int n)
117 {
118 if (n > 0)
119 {
120 RestoreBlock();
121 }
122 curr--;
123 }
124 internal void SetArg(NetRuby ruby, RThread th, int n, RNode nd)
125 {
126 bool b;
127 il.Emit(OpCodes.Ldloc, ((ArgBlock)args[curr]).Args);
128 LoadInt(il, n);
129 #if INVOKE_DEBUG
130 System.Console.WriteLine("SetArg node=" + nd.ToString());
131 #endif
132 nd.Compile(ruby, th, this, out b);
133 if (b)
134 {
135 il.Emit(OpCodes.Stelem_Ref);
136 }
137 else
138 {
139 il.Emit(OpCodes.Ldnull);
140 il.Emit(OpCodes.Stelem_Ref);
141 }
142 }
143 internal void SaveResult()
144 {
145 if (result == null)
146 {
147 result = il.DeclareLocal(typeof(object));
148 result.SetLocalSymInfo("result");
149 }
150 il.Emit(OpCodes.Stloc, result);
151 }
152 internal void LoadResult()
153 {
154 il.Emit(OpCodes.Ldloc, result);
155 }
156 internal void Cond(NetRuby ruby, RThread th, RNode body, RNode els)
157 {
158 Label el = il.DefineLabel();
159 Label exit = il.DefineLabel();
160 il.Emit(OpCodes.Call, typeof(RBasic).GetMethod("RTest"));
161 il.Emit(OpCodes.Brfalse, el);
162 ruby.CompileNode(this, body, false, th);
163 if (els != null)
164 {
165 il.Emit(OpCodes.Br, exit);
166 }
167 il.MarkLabel(el);
168 if (els != null)
169 {
170 ruby.CompileNode(this, els, false, th);
171 il.MarkLabel(exit);
172 }
173 }
174 static readonly FieldInfo rubyfield = typeof(RBasic).GetField("ruby", BindingFlags.Public | BindingFlags.Instance);
175 internal void LoadRuby()
176 {
177 il.Emit(OpCodes.Ldarg_0);
178 il.Emit(OpCodes.Ldfld, rubyfield);
179 }
180 void InitLocal()
181 {
182 if (th == null)
183 {
184 th = il.DeclareLocal(typeof(RThread));
185 th.SetLocalSymInfo("th");
186 }
187 Label lab = il.DefineLabel();
188 il.Emit(OpCodes.Ldloc, th);
189 il.Emit(OpCodes.Dup);
190 il.Emit(OpCodes.Brtrue, lab);
191 il.Emit(OpCodes.Pop);
192 LoadRuby();
193 il.Emit(OpCodes.Call, typeof(NetRuby).GetMethod("GetCurrentContext",
194 BindingFlags.Public | BindingFlags.Instance,
195 null, new Type[0], null));
196 il.Emit(OpCodes.Dup);
197 il.Emit(OpCodes.Stloc, th);
198 il.MarkLabel(lab);
199 }
200 void AdjustBlock()
201 {
202 InitLocal();
203 LocalBuilder block = ((ArgBlock)args[curr]).InitBlock(il);
204 il.Emit(OpCodes.Call, typeof(RThread).GetMethod("AdjustBlock"));
205 il.Emit(OpCodes.Stloc, block);
206 }
207 void RestoreBlock()
208 {
209 il.Emit(OpCodes.Ldloc, th);
210 il.Emit(OpCodes.Ldloc, ((ArgBlock)args[curr]).Block);
211 il.Emit(OpCodes.Call, typeof(RThread).GetMethod("RestoreBlock"));
212 }
213 public virtual void Break()
214 {
215 if (iters.Count > 0)
216 {
217 ((IterBlock)iters.Peek()).Break(il);
218 }
219 else
220 {
221 throw new eLocalJumpError("unexpected break");
222 }
223 }
224 public virtual void Next()
225 {
226 if (iters.Count > 0)
227 {
228 ((IterBlock)iters.Peek()).Next(il);
229 }
230 else
231 {
232 throw new eLocalJumpError("unexpected next");
233 }
234 }
235 public virtual void Redo()
236 {
237 throw new eLocalJumpError("unexpected redo");
238 }
239 public virtual void Return()
240 {
241 if (canreturn)
242 {
243 PreReturn();
244 il.Emit(OpCodes.Ret);
245 }
246 else
247 {
248 throw new eLocalJumpError("unexpected return");
249 }
250 }
251 public virtual void Retry()
252 {
253 throw new eLocalJumpError("unexpected return");
254 }
255 internal void LoadTh()
256 {
257 if (th == null)
258 InitLocal();
259 else
260 il.Emit(OpCodes.Ldloc, th);
261 }
262 internal void LoadInt(int rank)
263 {
264 LoadInt(il, rank);
265 }
266 public virtual void InitLocalTable(NetRuby ruby, uint[] tbl)
267 {
268 if (tbl == null || tbl.Length == 0) return;
269 LoadTh();
270 LoadInt(tbl.Length);
271 il.Emit(OpCodes.Newarr, typeof(uint));
272 for (int i = 0; i < tbl.Length; i++)
273 {
274 il.Emit(OpCodes.Dup);
275 LoadInt(i);
276 LoadInt((int)tbl[i]);
277 il.Emit(OpCodes.Stelem_I4);
278 }
279 LoadInt(tbl.Length);
280 il.Emit(OpCodes.Newarr, typeof(object));
281 il.Emit(OpCodes.Call, typeof(RThread).GetMethod("InitLVar"));
282
283 }
284 public virtual void SetLocalTable(int i)
285 {
286 SaveResult();
287 LoadTh();
288 LoadInt(i);
289 LoadResult();
290 il.Emit(OpCodes.Call, typeof(RThread).GetMethod("SetLVar"));
291 }
292 public virtual void LoadLocalTable(int i)
293 {
294 LoadTh();
295 LoadInt(i);
296 il.Emit(OpCodes.Call, typeof(RThread).GetMethod("LoadLVar"));
297 }
298 public virtual void PreReturn()
299 {
300 }
301 static internal void LoadInt(ILGenerator il, int rank)
302 {
303 switch (rank)
304 {
305 case 0:
306 il.Emit(OpCodes.Ldc_I4_0);
307 break;
308 case 1:
309 il.Emit(OpCodes.Ldc_I4_1);
310 break;
311 case 2:
312 il.Emit(OpCodes.Ldc_I4_2);
313 break;
314 case 3:
315 il.Emit(OpCodes.Ldc_I4_3);
316 break;
317 case 4:
318 il.Emit(OpCodes.Ldc_I4_4);
319 break;
320 case 5:
321 il.Emit(OpCodes.Ldc_I4_5);
322 break;
323 case 6:
324 il.Emit(OpCodes.Ldc_I4_6);
325 break;
326 case 7:
327 il.Emit(OpCodes.Ldc_I4_7);
328 break;
329 case 8:
330 il.Emit(OpCodes.Ldc_I4_8);
331 break;
332 default:
333 il.Emit(OpCodes.Ldc_I4, rank);
334 break;
335 }
336 }
337
338 class ArgBlock
339 {
340 internal ArgBlock(ILGenerator il, int nst)
341 {
342 this.nst = nst;
343 args = il.DeclareLocal(typeof(object[]));
344 args.SetLocalSymInfo("args" + nst.ToString());
345 receiver = null;
346 block = null;
347 #if CLEAR_ARGARRAY
348 idx = null;
349 #endif
350 }
351 internal LocalBuilder Args { get { return args; } }
352 internal LocalBuilder Block { get { return block; } }
353 internal LocalBuilder InitBlock(ILGenerator il)
354 {
355 if (block == null)
356 {
357 block = il.DeclareLocal(typeof(Block));
358 block.SetLocalSymInfo("block_save" + nst.ToString());
359 }
360 return block;
361 }
362 internal void SaveReceiver(ILGenerator il)
363 {
364 if (receiver == null)
365 {
366 receiver = il.DeclareLocal(typeof(object));
367 receiver.SetLocalSymInfo("receiver" + nst.ToString());
368 }
369 il.Emit(OpCodes.Stloc, receiver);
370 }
371 internal void CreateArray(ILGenerator il, int rank)
372 {
373 Label force = il.DefineLabel();
374 Label end = il.DefineLabel();
375 il.Emit(OpCodes.Ldloc, args);
376 il.Emit(OpCodes.Brfalse, force);
377 il.Emit(OpCodes.Ldloc, args);
378 il.Emit(OpCodes.Ldlen);
379 ILParam.LoadInt(il, rank);
380 il.Emit(OpCodes.Beq, end);
381 il.MarkLabel(force);
382 ILParam.LoadInt(il, rank);
383 il.Emit(OpCodes.Newarr, typeof(object));
384 il.Emit(OpCodes.Stloc, args);
385 il.MarkLabel(end);
386 #if CLEAR_ARGARRAY
387 {
388 if (idx == null)
389 idx = il.DeclareLocal(typeof(int));
390 il.Emit(OpCodes.Ldc_I4_0);
391 Label label = il.DefineLabel();
392 il.MarkLabel(label);
393 il.Emit(OpCodes.Stloc, idx);
394 il.Emit(OpCodes.Ldloc, args);
395 il.Emit(OpCodes.Ldloc, idx);
396 il.Emit(OpCodes.Ldnull);
397 il.Emit(OpCodes.Stelem_Ref);
398 il.Emit(OpCodes.Ldloc, idx);
399 il.Emit(OpCodes.Ldc_I4_1);
400 il.Emit(OpCodes.Add);
401 il.Emit(OpCodes.Dup);
402 il.Emit(OpCodes.Ldloc, args);
403 il.Emit(OpCodes.Ldlen);
404 il.Emit(OpCodes.Blt_S, label);
405 il.Emit(OpCodes.Pop);
406 }
407 #endif
408 }
409 #if CLEAR_ARGARRAY
410 LocalBuilder idx;
411 #endif
412 LocalBuilder args;
413 LocalBuilder block;
414 internal LocalBuilder receiver;
415 int nst;
416 }
417 ArrayList args;
418
419 class IterBlock
420 {
421 internal IterBlock(ILParam pm, Type tp, int nst)
422 {
423 ILGenerator il = pm.il;
424 this.nst = nst;
425 il.BeginScope();
426 retry = il.DeclareLocal(typeof(bool));
427 retryLabel = il.DefineLabel();
428 exitLabel = il.DefineLabel();
429 nextLabel = il.DefineLabel();
430 il.MarkLabel(retryLabel);
431 il.Emit(OpCodes.Ldc_I4_0);
432 il.Emit(OpCodes.Stloc, retry);
433 pm.LoadTh();
434 il.Emit(OpCodes.Ldnull);
435 il.Emit(OpCodes.Ldtoken, tp);
436 il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
437 il.Emit(OpCodes.Ldstr, "Iterator");
438 pm.LoadInt((int)(BindingFlags.Static | BindingFlags.Public));
439 il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetMethod",
440 new Type[] { typeof(string), typeof(BindingFlags) }));
441 pm.LoadRuby();
442 il.Emit(OpCodes.Newobj, typeof(RNCFunc).GetConstructor(
443 new Type[] {typeof(MethodInfo), typeof(NetRuby)}));
444 il.Emit(OpCodes.Ldarg_0);
445 il.Emit(OpCodes.Call, typeof(RThread).GetMethod("IterBlock"));
446 block = il.DeclareLocal(typeof(Block));
447 block.SetLocalSymInfo("_block");
448 il.Emit(OpCodes.Stloc, block);
449 tryLabel = il.BeginExceptionBlock();
450 pm.LoadTh();
451 pm.LoadInt((int)ITER.PRE);
452 il.Emit(OpCodes.Call, typeof(RThread).GetMethod("PushIter"));
453 il.MarkLabel(nextLabel);
454 }
455 internal void Break(ILGenerator il)
456 {
457 il.Emit(OpCodes.Br, exitLabel);
458 }
459 internal void Next(ILGenerator il)
460 {
461 il.Emit(OpCodes.Br, nextLabel);
462 }
463 internal void Close(ILParam pm)
464 {
465 ILGenerator il = pm.il;
466 pm.LoadTh();
467 il.Emit(OpCodes.Call, typeof(RThread).GetMethod("PopIter"));
468 exp = il.DeclareLocal(typeof(Exception));
469 exp.SetLocalSymInfo("ex");
470 il.BeginCatchBlock(typeof(Exception));
471 il.Emit(OpCodes.Stloc, exp);
472 pm.LoadTh();
473 il.Emit(OpCodes.Ldarg_0);
474 pm.LoadRuby();
475 il.Emit(OpCodes.Ldloc, exp);
476 il.Emit(OpCodes.Newobj, typeof(RException).GetConstructor(new Type[] { typeof(NetRuby), typeof(Exception) }));
477 il.Emit(OpCodes.Stfld, typeof(RThread).GetField("errInfo"));
478 il.EndExceptionBlock();
479 il.MarkLabel(exitLabel);
480 pm.LoadTh();
481 il.Emit(OpCodes.Ldloc, block);
482 il.Emit(OpCodes.Call, typeof(RThread).GetMethod("ResetIterBlock"));
483 il.Emit(OpCodes.Ldloc, retry);
484 il.Emit(OpCodes.Brtrue, retryLabel);
485 il.EndScope();
486 }
487 Label retryLabel;
488 Label exitLabel;
489 Label nextLabel;
490 Label tryLabel;
491 internal LocalBuilder block;
492 LocalBuilder retry;
493 LocalBuilder exp;
494 int nst;
495 }
496 Stack iters;
497 int curr;
498 int argcnt;
499 int argopt;
500 protected bool canreturn;
501 internal TypeBuilder tb;
502 internal MethodBuilder mb;
503 internal LocalBuilder _Block {
504 get { return ((IterBlock)iters.Peek()).block; }
505 }
506 internal ILGenerator il;
507 internal LocalBuilder th;
508 internal LocalBuilder result;
509 internal LocalBuilder idx;
510 ArrayList methodList;
511 internal void AddMethod(Type tp)
512 {
513 if (methodList == null)
514 methodList = new ArrayList();
515 methodList.Add(tp);
516 }
517 internal ArrayList MethodList {
518 get { return methodList; }
519 }
520 internal void SetupIndex()
521 {
522 if (idx == null)
523 {
524 idx = il.DeclareLocal(typeof(int));
525 idx.SetLocalSymInfo("idx");
526 }
527 }
528 }
529 public class TopLevelILParam : ILParam
530 {
531 internal TopLevelILParam(TypeBuilder tb, MethodBuilder mb) :
532 base(tb, mb)
533 {
534 }
535 }
536
537 sealed public class IterILParam : ILParam, IDisposable
538 {
539 internal IterILParam(TypeBuilder tb, MethodBuilder mb) :
540 base(tb, mb)
541 {
542 }
543 public override void Break()
544 {
545 LoadInt((int)Tag.TAG.BREAK);
546 il.Emit(OpCodes.Newobj, typeof(eTagJump).GetConstructor(
547 new Type[] { typeof(Tag.TAG) }));
548 il.Emit(OpCodes.Throw);
549 }
550 public override void Next()
551 {
552 LoadInt((int)Tag.TAG.NEXT);
553 il.Emit(OpCodes.Newobj, typeof(eTagJump).GetConstructor(
554 new Type[] { typeof(Tag.TAG) }));
555 il.Emit(OpCodes.Throw);
556 }
557 public override void Redo()
558 {
559 LoadInt((int)Tag.TAG.REDO);
560 il.Emit(OpCodes.Newobj, typeof(eTagJump).GetConstructor(
561 new Type[] { typeof(Tag.TAG) }));
562 il.Emit(OpCodes.Throw);
563 }
564 public override void Retry()
565 {
566 LoadInt((int)Tag.TAG.RETRY);
567 il.Emit(OpCodes.Newobj, typeof(eTagJump).GetConstructor(
568 new Type[] { typeof(Tag.TAG) }));
569 il.Emit(OpCodes.Throw);
570 }
571 public override void Return()
572 {
573 SaveResult();
574 LoadRuby();
575 il.Emit(OpCodes.Dup);
576 LoadResult();
577 il.Emit(OpCodes.Call, typeof(NetRuby).GetMethod("SetReturnValue"));
578 il.Emit(OpCodes.Call, typeof(NetRuby).GetMethod("ReturnCheck"));
579 LoadInt((int)Tag.TAG.RETURN);
580 il.Emit(OpCodes.Newobj, typeof(eTagJump).GetConstructor(
581 new Type[] { typeof(Tag.TAG) }));
582 il.Emit(OpCodes.Throw);
583 }
584 }
585 public class ScopedILParam : ILParam, IDisposable
586 {
587 internal ScopedILParam(TypeBuilder tb, MethodBuilder mb) :
588 base(tb, mb)
589 {
590 canreturn = true;
591 vm = il.DeclareLocal(typeof(Scope.ScopeMode));
592 }
593 protected override void Dispose(bool disposing)
594 {
595 if (!disposed)
596 {
597 RestoreLocalTable();
598 base.Dispose(disposing);
599 }
600 }
601 public override void InitLocalTable(NetRuby ruby, uint[] tbl)
602 {
603 #if INVOKE_DEBUG
604 il.EmitWriteLine("InitLocalTable");
605 #endif
606 LoadTh();
607 il.Emit(OpCodes.Call, typeof(RThread).GetMethod("PushScope"));
608 il.Emit(OpCodes.Stloc, vm);
609 base.InitLocalTable(ruby, tbl);
610 }
611 public void RestoreLocalTable()
612 {
613 #if INVOKE_DEBUG
614 il.EmitWriteLine("PopTable");
615 #endif
616 LoadTh();
617 il.Emit(OpCodes.Ldloc, vm);
618 il.Emit(OpCodes.Call, typeof(RThread).GetMethod("PopScope"));
619 }
620 public override void PreReturn()
621 {
622 RestoreLocalTable();
623 }
624 LocalBuilder vm;
625 }
626 public class CondILParam : ILParam, IDisposable
627 {
628 internal CondILParam(ILParam ip) :
629 base(ip)
630 {
631 outer = ip;
632 il.BeginScope();
633 breakLabel = il.DefineLabel();
634 redoLabel = il.DefineLabel();
635 nextLabel = il.DefineLabel();
636 topLabel = il.BeginExceptionBlock();
637 }
638 ~CondILParam()
639 {
640 Dispose(false);
641 }
642 protected override void Dispose(bool disposing)
643 {
644 if (!disposed)
645 {
646 LocalBuilder exp = il.DeclareLocal(typeof(Exception));
647 exp.SetLocalSymInfo("ex");
648 il.BeginCatchBlock(typeof(Exception));
649 il.Emit(OpCodes.Stloc, exp);
650 LoadTh();
651 il.Emit(OpCodes.Ldarg_0);
652 LoadRuby();
653 il.Emit(OpCodes.Ldloc, exp);
654 il.Emit(OpCodes.Newobj, typeof(RException).GetConstructor(new Type[] { typeof(NetRuby), typeof(Exception) }));
655 il.Emit(OpCodes.Stfld, typeof(RThread).GetField("errInfo"));
656 il.EndExceptionBlock();
657 il.MarkLabel(breakLabel);
658 il.EndScope();
659 disposed = true;
660 // never call to base. (no Ret)
661 }
662 }
663 ILParam outer;
664 public override void PreReturn()
665 {
666 outer.PreReturn();
667 }
668 internal void CondBreak(OpCode op)
669 {
670 il.Emit(OpCodes.Call, typeof(RBasic).GetMethod("RTest"));
671 il.Emit(op, breakLabel);
672 }
673 internal void CondCont(OpCode op)
674 {
675 il.Emit(OpCodes.Call, typeof(RBasic).GetMethod("RTest"));
676 il.Emit(op, redoLabel);
677 }
678 internal void CondLoop(NetRuby ruby, RThread th, RNode body)
679 {
680 il.MarkLabel(redoLabel);
681 ruby.CompileNode(this, body, false, th);
682 il.MarkLabel(nextLabel);
683 }
684 public override void Break()
685 {
686 il.Emit(OpCodes.Br, breakLabel);
687 }
688 public override void Next()
689 {
690 il.Emit(OpCodes.Br, nextLabel);
691 }
692 public override void Redo()
693 {
694 il.Emit(OpCodes.Br, redoLabel);
695 }
696 Label breakLabel;
697 Label nextLabel;
698 Label topLabel;
699 Label redoLabel;
700 }
701 public class RNode
702 {
703 internal RNode()
704 {
705 #if _SCANNER_DEBUG
706 System.Console.WriteLine("Create Node:" + ToString());
707 #endif
708 }
709 internal RNode(RNode nd)
710 {
711 File = nd.File;
712 Line = nd.Line;
713 }
714 internal RNode(RThread th)
715 {
716 #if _SCANNER_DEBUG
717 System.Console.WriteLine("Create Node:" + ToString());
718 #endif
719 if (th != null)
720 {
721 File = th.file;
722 Line = th.line;
723 }
724 else
725 {
726 File = "internal";
727 Line = 0;
728 }
729 }
730 public virtual RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
731 {
732 b = false;
733 System.Console.WriteLine("Unkonw Compile Node : " + ToString());
734 return null;
735 }
736 public virtual RNode Eval(NetRuby ruby, object self, out object result)
737 {
738 ruby.bug("Eval: unknown node type " + ToString());
739
740 #if EVAL_TRACE
741 System.Console.WriteLine("Eval:" + ToString());
742 #endif
743 result = null;
744 return null;
745 }
746
747 protected void CallArgs(NetRuby ruby, RThread th, ILParam pm)
748 {
749 if (args == null)
750 {
751 pm.SetupArgs(0);
752 }
753 else if (args is RNArray)
754 {
755 RNode n = args;
756 int argc = n.alen;
757 if (argc > 0)
758 {
759 pm.SetupArgs(argc);
760
761 string file = th.file;
762 int line = th.line;
763 for (int i = 0; i < argc; i++)
764 {
765 pm.SetArg(ruby, th, i, n.head);
766 n = n.next;
767 }
768 th.file = file;
769 th.line = line;
770 }
771 else
772 {
773 pm.SetupArgs(0);
774 }
775 }
776 else
777 {
778 System.Console.WriteLine("!!!!!!!!!!!!!!!!!!!!!!CallArgs:" + args.ToString());
779 #if NEXT_STEP
780 object nargs = ruby.Eval(self, n);
781 string file = th.file;
782 int line = th.line;
783 ArrayList ar;
784 if (nargs is RArray)
785 {
786 ar = ((RArray)nargs).ArrayList;
787 }
788 else if (nargs is ArrayList == false)
789 {
790 object o = nargs;
791 ar = new ArrayList();
792 ar.Add(nargs);
793 }
794 else
795 {
796 ar = (ArrayList)nargs;
797 }
798 argv = new object[ar.Count];
799 for (int i = 0; i < ar.Count; i++)
800 {
801 argv[i] = ar[i];
802 }
803 th.file = file;
804 th.line = line;
805 #endif
806 }
807 }
808 protected void CleanupArgs(NetRuby ruby, RThread th, ILParam pm)
809 {
810 if (args == null)
811 {
812 pm.CleanupArgs(0);
813 }
814 else if (args is RNArray)
815 {
816 pm.CleanupArgs((args.alen < 0) ? 0 : args.alen);
817 }
818 }
819 public virtual object[] SetupArgs(NetRuby ruby, object self, RNode n)
820 {
821 #if EVAL_TRACE
822 System.Console.WriteLine(String.Format("SetupArgs self={0} node={1}",
823 (self == null) ? "null" : self.ToString(),
824 (n == null) ? "null" : n.ToString()));
825 #endif
826 if (n == null) return new object[0];
827
828 RThread th = ruby.GetCurrentContext();
829
830 int argc = 0;
831 object[] argv = null;
832 if (n is RNArray)
833 {
834 argc = n.alen;
835 if (argc > 0)
836 {
837 string file = th.file;
838 int line = th.line;
839 argv = new object[argc];
840 for (int i = 0; i < argc; i++)
841 {
842 argv[i] = ruby.Eval(self, n.head);
843 #if EVAL_TRACE
844 if (argv[i] == null)
845 System.Console.WriteLine("arg" + i.ToString() + "=null");
846 else
847 System.Console.WriteLine("arg" + i.ToString() + "=" + argv[i].ToString());
848 #endif
849 n = n.next;
850 }
851 th.file = file;
852 th.line = line;
853 }
854 else
855 {
856 argv = new object[0];
857 }
858 }
859 else
860 {
861 object nargs = ruby.Eval(self, n);
862 string file = th.file;
863 int line = th.line;
864 ArrayList ar;
865 if (nargs is RArray)
866 {
867 ar = ((RArray)nargs).ArrayList;
868 }
869 else if (nargs is ArrayList == false)
870 {
871 object o = nargs;
872 ar = new ArrayList();
873 ar.Add(nargs);
874 }
875 else
876 {
877 ar = (ArrayList)nargs;
878 }
879 argv = new object[ar.Count];
880 for (int i = 0; i < ar.Count; i++)
881 {
882 argv[i] = ar[i];
883 }
884 th.file = file;
885 th.line = line;
886 }
887 return argv;
888 }
889
890 public virtual object Funcall(RMetaObject klass, object recver, uint id, object[] args)
891 {
892 klass.ruby.bug("Funcall: unknown node type " + ToString());
893 return null;
894 }
895
896 public virtual void Assign(NetRuby ruby, RThread th, ILParam pm)
897 {
898 ruby.bug("Assign(compiler): unknown node type " + ToString());
899 }
900
901 public virtual object Assign(NetRuby ruby, object self, object val, bool check)
902 {
903 ruby.bug("bug in variable assignment");
904 return null;
905 }
906
907 static public ArrayList MakeArray(NetRuby ruby, object self, object val)
908 {
909 ArrayList ary = null;
910 if (val is QUndef)
911 ary = new ArrayList();
912 else if (val is ArrayList)
913 ary = (ArrayList)val;
914 else if (val is RArray)
915 ary = ((RArray)val).ArrayList;
916 else if (val is object[])
917 {
918 ary = new ArrayList((object[])val);
919 }
920 else
921 {
922 uint toary = ruby.intern("to_ary");
923 if (ruby.RespondTo(self, toary))
924 {
925 object o = ruby.Funcall(val, toary, null);
926 if (o is RArray == false)
927 {
928 throw new eTypeError(ruby.ClassOf(o).ClassName
929 + "#to_ary should retrun Array");
930 }
931 val = ((RArray)o).ArrayList;
932 }
933 else
934 {
935 ary = new ArrayList();
936 ary.Add(val);
937 }
938 }
939 return ary;
940 }
941
942 protected string ArgDefined(NetRuby ruby, object self, RNode node, string type)
943 {
944 if (node == null) return type;
945 if (node is RNArray)
946 {
947 int argc = node.alen;
948 if (argc > 0)
949 {
950 for (int i = 0; i < argc; i++)
951 {
952 if (IsDefined(ruby, self, node.head) == null)
953 return null;
954 node = node.next;
955 }
956 }
957 }
958 else if (IsDefined(ruby, self, node) == null)
959 {
960 return null;
961 }
962 return type;
963 }
964 static internal string IsDefined(NetRuby ruby, object self, RNode node)
965 {
966 if (node == null) return "expression";
967 return node.IsDefined(ruby, self);
968 }
969
970 protected virtual string IsDefined(NetRuby ruby, object self)
971 {
972 RThread th = ruby.GetCurrentContext();
973 string s = null;
974 th.PushTag(Tag.TAG.PROT_NONE);
975 try
976 {
977 ruby.Eval(self, this);
978 s = "expression";
979 }
980 catch
981 {
982 th.errInfo = null;
983 }
984 th.PopTag(false);
985 return s;
986 }
987
988 public virtual RNode head
989 {
990 get { throw new NotSupportedException("bug(head get):" + GetType().ToString()); }
991 set { throw new NotSupportedException("bug(head set):" + GetType().ToString()); }
992 }
993 public virtual int alen
994 {
995 get { throw new NotSupportedException("bug(alen get):" + GetType().ToString()); }
996 set { throw new NotSupportedException("bug(alen set):" + GetType().ToString()); }
997 }
998 public virtual RNode next
999 {
1000 get { throw new NotSupportedException("bug(next get):" + GetType().ToString()); }
1001 set { throw new NotSupportedException("bug(next set):" + GetType().ToString()); }
1002 }
1003
1004 public virtual RNode cond
1005 {
1006 get { throw new NotSupportedException("bug(cond get):" + GetType().ToString()); }
1007 }
1008 public virtual RNode body
1009 {
1010 get { throw new NotSupportedException("bug(body get):" + GetType().ToString()); }
1011 set { throw new NotSupportedException("bug(body set):" + GetType().ToString()); }
1012 }
1013 public virtual RNode nd_else
1014 {
1015 get { throw new NotSupportedException("bug(nd_else get):" + GetType().ToString()); }
1016 }
1017
1018 public virtual RMetaObject orig
1019 {
1020 get { throw new NotSupportedException("bug(orig get):" + GetType().ToString()); }
1021 }
1022
1023 public virtual RNode resq
1024 {
1025 get { throw new NotSupportedException("bug(resq get):" + GetType().ToString()); }
1026 }
1027 public virtual RNode ensr
1028 {
1029 get { throw new NotSupportedException("bug(ensr get):" + GetType().ToString()); }
1030 }
1031
1032 public virtual RNode nd_1st
1033 {
1034 get { throw new NotSupportedException("bug(nd_1st get):" + GetType().ToString()); }
1035 }
1036 public virtual RNode nd_2nd
1037 {
1038 get { throw new NotSupportedException("bug(nd_2nd get):" + GetType().ToString()); }
1039 }
1040
1041 public virtual RNode stts
1042 {
1043 get { throw new NotSupportedException("bug(stts get):" + GetType().ToString()); }
1044 }
1045
1046 public virtual GlobalEntry entry
1047 {
1048 get { throw new NotSupportedException("bug(entry get):" + GetType().ToString()); }
1049 }
1050
1051 public virtual uint vid
1052 {
1053 get { throw new NotSupportedException("bug(vid get):" + GetType().ToString()); }
1054 }
1055 public virtual uint cflag
1056 {
1057 get { throw new NotSupportedException("bug(cflag get):" + GetType().ToString()); }
1058 set { throw new NotSupportedException("bug(cflag set):" + GetType().ToString()); }
1059 }
1060 public virtual int cnt
1061 {
1062 get { throw new NotSupportedException("bug(cnt get):" + GetType().ToString()); }
1063 set { throw new NotSupportedException("bug(cnt set):" + GetType().ToString()); }
1064 }
1065 public virtual uint[] tbl
1066 {
1067 get { throw new NotSupportedException("bug(tbl get):" + GetType().ToString()); }
1068 set { throw new NotSupportedException("bug(tbl set):" + GetType().ToString()); }
1069 }
1070
1071 public virtual RNode var
1072 {
1073 get { throw new NotSupportedException("bug(var get):" + GetType().ToString()); }
1074 }
1075 public virtual RNode ibody
1076 {
1077 get { throw new NotSupportedException("bug(ibody get):" + GetType().ToString()); }
1078 }
1079 public virtual RNode iter
1080 {
1081 get { throw new NotSupportedException("bug(iter get):" + GetType().ToString()); }
1082 set { throw new NotSupportedException("bug(iter set):" + GetType().ToString()); }
1083 }
1084
1085 public virtual RNode val
1086 {
1087 get { throw new NotSupportedException("bug(val get):" + GetType().ToString()); }
1088 set { throw new NotSupportedException("bug(val set):" + GetType().ToString()); }
1089 }
1090 public virtual uint aid
1091 {
1092 get { throw new NotSupportedException("bug(aid get):" + GetType().ToString()); }
1093 set { throw new NotSupportedException("bug(aid set):" + GetType().ToString()); }
1094 }
1095
1096 public virtual object lit
1097 {
1098 get { throw new NotSupportedException("bug(lit get):" + GetType().ToString()); }
1099 set { throw new NotSupportedException("bug(lit set):" + GetType().ToString()); }
1100 }
1101
1102 public virtual RNode frml
1103 {
1104 get { throw new NotSupportedException("bug(frml get):" + GetType().ToString()); }
1105 }
1106 public virtual int rest
1107 {
1108 get { throw new NotSupportedException("bug(rest get):" + GetType().ToString()); }
1109 }
1110 public virtual RNode opt
1111 {
1112 get { throw new NotSupportedException("bug(opt get):" + GetType().ToString()); }
1113 }
1114
1115 public virtual RNode recv
1116 {
1117 get { throw new NotSupportedException("bug(recv get):" + GetType().ToString()); }
1118 }
1119 public virtual uint mid
1120 {
1121 get { throw new NotSupportedException("bug(mid get):" + GetType().ToString()); }
1122 }
1123 public virtual RNode args
1124 {
1125 get { throw new NotSupportedException("bug(args get):" + GetType().ToString()); }
1126 set { throw new NotSupportedException("bug(args set):" + GetType().ToString()); }
1127 }
1128
1129 public virtual NOEX noex
1130 {
1131 get { throw new NotSupportedException("bug(nodex get):" + GetType().ToString()); }
1132 set { throw new NotSupportedException("bug(noex set):" + GetType().ToString()); }
1133 }
1134 public virtual RNode defn
1135 {
1136 get { throw new NotSupportedException("bug(defn get):" + GetType().ToString()); }
1137 }
1138
1139 public virtual uint old
1140 {
1141 get { throw new NotSupportedException("bug(old get):" + GetType().ToString()); }
1142 }
1143 public virtual uint nd_new
1144 {
1145 get { throw new NotSupportedException("bug(nd_new get):" + GetType().ToString()); }
1146 }
1147
1148 public virtual MethodInfo cfunc
1149 {
1150 get { throw new NotSupportedException("bug(cfunc get):" + GetType().ToString()); }
1151 }
1152
1153 public virtual int argc
1154 {
1155 get { throw new NotSupportedException("bug(argc get):" + GetType().ToString()); }
1156 }
1157
1158 public virtual uint cname
1159 {
1160 get { throw new NotSupportedException("bug(cname get):" + GetType().ToString()); }
1161 }
1162 public virtual RNode super
1163 {
1164 get { throw new NotSupportedException("bug(super get):" + GetType().ToString()); }
1165 }
1166
1167 public virtual uint modl
1168 {
1169 get { throw new NotSupportedException("bug(modl get):" + GetType().ToString()); }
1170 }
1171
1172 public virtual RMetaObject clss
1173 {
1174 get { throw new NotSupportedException("bug(clss get):" + GetType().ToString()); }
1175 }
1176
1177 public virtual RNode beg
1178 {
1179 get { throw new NotSupportedException("bug(beg get):" + GetType().ToString()); }
1180 set { throw new NotSupportedException("bug(beg set):" + GetType().ToString()); }
1181 }
1182 public virtual RNode end
1183 {
1184 get { throw new NotSupportedException("bug(end get):" + GetType().ToString()); }
1185 set { throw new NotSupportedException("bug(end set):" + GetType().ToString()); }
1186 }
1187 public virtual bool state
1188 {
1189 get { throw new NotSupportedException("bug(state get):" + GetType().ToString()); }
1190 set { throw new NotSupportedException("bug(state set):" + GetType().ToString()); }
1191 }
1192 public virtual RNode rval
1193 {
1194 get { throw new NotSupportedException("bug(rval get):" + GetType().ToString()); }
1195 set { throw new NotSupportedException("bug(rval set):" + GetType().ToString()); }
1196 }
1197
1198 public virtual int nth
1199 {
1200 get { throw new NotSupportedException("bug(nth get):" + GetType().ToString()); }
1201 set { throw new NotSupportedException("bug(nth set):" + GetType().ToString()); }
1202 }
1203
1204 public virtual uint tag
1205 {
1206 get { throw new NotSupportedException("bug(tag get):" + GetType().ToString()); }
1207 }
1208 public virtual object tval
1209 {
1210 get { throw new NotSupportedException("bug(tval get):" + GetType().ToString()); }
1211 }
1212 public virtual string file
1213 {
1214 get { return File; }
1215 set { File = value; }
1216 }
1217
1218 // list
1219 internal static RNode list_append(RThread th, RNode head, RNode tail)
1220 {
1221 if (head == null) return new RNArray(th, tail);
1222
1223 RNode last = head;
1224 while (last.next != null) {
1225 last = last.next;
1226 }
1227
1228 last.next = new RNArray(th, tail);
1229 head.alen += 1;
1230 return head;
1231 }
1232
1233 internal static RNode list_concat(RNode head, RNode tail)
1234 {
1235 RNode last = head;
1236 while (last.next != null) {
1237 last = last.next;
1238 }
1239
1240 last.next = tail;
1241 head.alen += tail.alen;
1242
1243 return head;
1244 }
1245
1246 internal static RNode block_append(RThread p, RNode head, RNode tail)
1247 {
1248 RNode end = null;
1249
1250 if (tail == null) return head;
1251 if (head == null) return tail;
1252
1253 if (head is RNBlock)
1254 {
1255 end = head.end;
1256 }
1257 else
1258 {
1259 end = new RNBlock(p, head);
1260 head = end;
1261 }
1262
1263 if (p.ruby.verbose)
1264 {
1265 for (RNode nd = end.head;;)
1266 {
1267 if (nd is RNNewLine)
1268 {
1269 nd = nd.next;
1270 }
1271 else if (nd is RNReturn
1272 || nd is RNBreak
1273 || nd is RNNext
1274 || nd is RNRedo
1275 || nd is RNRetry)
1276 {
1277 p.ruby.warn("statement not reached");
1278 break;
1279 }
1280 else
1281 {
1282 break;
1283 }
1284 }
1285 }
1286
1287 if (tail is RNBlock == false) {
1288 tail = new RNBlock(p, tail);
1289 }
1290 end.next = tail;
1291 head.end = tail.end;
1292 return head;
1293 }
1294
1295 internal void FixPos(RNode n)
1296 {
1297 if (n != null)
1298 {
1299 Line = n.Line;
1300 File = n.File;
1301 }
1302 }
1303
1304 internal void SetLine(int l)
1305 {
1306 Line = l;
1307 /*
1308 RNODE(n)->flags=((RNODE(n)->flags&~(-1<<NODE_LSHIFT))|(((l)&NODE_LMASK)<<NODE_LSHIFT))
1309 */
1310 }
1311
1312 protected bool RTest(object o)
1313 {
1314 return (o == null || (o is bool && ((bool)o) == false)) ? false : true;
1315 }
1316
1317 internal int Line;
1318 internal string File;
1319 }
1320
1321 internal class RNEOF : RNode
1322 {
1323 internal RNEOF()
1324 {
1325 }
1326 }
1327
1328 internal class RNMethod : RNode
1329 {
1330 internal RNMethod(RNode n, NOEX e) :
1331 base((RThread)null)
1332 {
1333 nx = e;
1334 bdy = n;
1335 ct = 0;
1336 }
1337 internal RNMethod(RNMethod m) :
1338 base(m)
1339 {
1340 nx = m.nx;
1341 ct = 0;
1342 }
1343 public override NOEX noex
1344 {
1345 get { return nx; }
1346 set { nx = value; }
1347 }
1348 public override RNode body
1349 {
1350 get { return bdy; }
1351 set { bdy = value; }
1352 }
1353 public override int cnt
1354 {
1355 get { return ct; }
1356 set { ct = value; }
1357 }
1358 NOEX nx;
1359 RNode bdy;
1360 int ct;
1361 }
1362
1363 internal class RNFBody : RNode
1364 {
1365 internal RNFBody(RNode n, uint i, RMetaObject origin) :
1366 base((RThread)null)
1367 {
1368 rv = n;
1369 id = i;
1370 or = origin;
1371 }
1372 public override RNode head
1373 {
1374 get { return rv; }
1375 }
1376 public override RNode recv
1377 {
1378 get { return rv; }
1379 }
1380 public override uint mid
1381 {
1382 get { return id; }
1383 }
1384 public override RMetaObject orig
1385 {
1386 get { return or; }
1387 }
1388 RMetaObject or;
1389 RNode rv;
1390 uint id;
1391 }
1392
1393 public class RNCFunc : RNode
1394 {
1395 public RNCFunc(MethodInfo mi, NetRuby rb)
1396 : base(rb.GetCurrentContext())
1397 {
1398 ruby = rb;
1399 minf = mi;
1400 ct = 0;
1401 }
1402 public override int cnt
1403 {
1404 get { return ct; }
1405 set { ct = value; }
1406 }
1407 public override MethodInfo cfunc
1408 {
1409 get { return minf; }
1410 }
1411 int ct;
1412 MethodInfo minf;
1413 NetRuby ruby;
1414
1415 public override object Funcall(RMetaObject klass, object recver, uint id, object[] args)
1416 {
1417 MethodInfo mi = cfunc;
1418 object ret = null;
1419 if (ruby.TraceFunc != null)
1420 {
1421 ret = Call(mi, recver, args);
1422 }
1423 else
1424 {
1425 ret = Call(mi, recver, args);
1426 }
1427 return ret;
1428 }
1429
1430 private object Call(MethodInfo mi, object recver, object[] args)
1431 {
1432 #if INVOKE_DEBUG
1433 if (mi == null)
1434 System.Console.WriteLine("no methodinfo");
1435 if (recver == null)
1436 System.Console.WriteLine("no recver");
1437 if (args == null)
1438 System.Console.WriteLine("no args");
1439 #endif
1440 object[] argv = args;
1441 ParameterInfo[] ps = mi.GetParameters();
1442 if (ps.Length == 0)
1443 {
1444 argv = null;
1445 }
1446 else if (ps.Length > 0)
1447 {
1448 int last = ps.Length - 1;
1449 Type tp = ps[last].ParameterType;
1450 if (tp.IsArray)
1451 {
1452 argv = new object[ps.Length];
1453 int i = 0;
1454 int id = 0;
1455 if (ps[0].ParameterType == typeof(NetRuby))
1456 {
1457 argv[0] = ruby;
1458 id++;
1459 }
1460 else if (ps[0].ParameterType == typeof(RBasic) && recver is RBasic)
1461 {
1462 argv[0] = (RBasic)recver;
1463 id++;
1464 }
1465 for (; id < last; id++)
1466 {
1467 if (i < args.Length)
1468 argv[id] = args[i++];
1469 else
1470 argv[id] = null;
1471 }
1472 int cnt = (args.Length <= i) ? 0 : args.Length - i;
1473 object[] rest = new object[cnt];
1474 argv[last] = rest;
1475 for (id = 0; i < cnt; i++)
1476 {
1477 #if INVOKE_DEBUG
1478 System.Console.WriteLine("rest" + id.ToString() + "=" + ((args[i] == null) ? "null" : args[i].ToString()));
1479 #endif
1480 rest[id++] = args[i];
1481 }
1482 }
1483 else if (ps[0].ParameterType == typeof(NetRuby))
1484 {
1485 argv = new object[args.Length + 1];
1486 argv[0] = ruby;
1487 if (args.Length > 0)
1488 {
1489 Array.Copy(args, 0, argv, 1, args.Length);
1490 }
1491 }
1492 }
1493 object ret = null;
1494 try
1495 {
1496 if (mi.IsStatic)
1497 {
1498 #if INVOKE_DEBUG
1499 System.Console.WriteLine("Invoke(static:"+mi.Name+") by " + recver.ToString());
1500 if (argv != null)
1501 {
1502 for (int i = 0; i < argv.Length; i++)
1503 {
1504 System.Console.WriteLine("param(" + i.ToString() + ")=" + ((argv[i] == null) ? "null" : argv[i].ToString()));
1505 }
1506 }
1507 #endif
1508 ret = mi.Invoke(null, argv);
1509 #if INVOKE_DEBUG
1510 System.Console.WriteLine("invoked(static:"+mi.Name+")=" + ((ret==null)?"null":ret.ToString()));
1511 #endif
1512 }
1513 else
1514 {
1515 recver = ruby.InstanceOf(recver);
1516 #if INVOKE_DEBUG
1517 System.Console.WriteLine("Invoke("+mi.Name+") by " + recver.ToString());
1518 if (argv != null)
1519 {
1520 for (int i = 0; i < argv.Length; i++)
1521 {
1522 System.Console.WriteLine("param(" + i.ToString() + ")=" + ((argv[i] == null) ? "null" : argv[i].ToString()));
1523 }
1524 }
1525 #endif
1526 ret = mi.Invoke(recver, argv);
1527 #if INVOKE_DEBUG
1528 System.Console.WriteLine("invoked("+mi.Name+")=" + ((ret==null)?"null":ret.ToString()));
1529 #endif
1530 }
1531 }
1532 catch (TargetInvocationException e)
1533 {
1534 if (e.InnerException is eTagJump == false)
1535 {
1536 ruby.warn(e.InnerException.Message);
1537 #if _DEBUG
1538 ruby.warn(e.InnerException.StackTrace);
1539 #endif
1540 }
1541 throw e.InnerException;
1542 }
1543 catch (Exception e)
1544 {
1545 #if _DEBUG
1546 ruby.warn(e.StackTrace);
1547 #endif
1548 string msg = String.Format("Exception for {0} --- {1}", mi.Name, e.Message);
1549 ruby.ruby_raise(ruby.InstanceOf(recver), ruby.eRuntimeError, msg);
1550 }
1551 return ret;
1552 }
1553 }
1554
1555 public class RNIFunc : RNode
1556 {
1557 internal RNIFunc(RThread p, NetRuby.BlockProc blk, object dat)
1558 : base(p)
1559 {
1560 blockProc = blk;
1561 data = dat;
1562 }
1563 NetRuby.BlockProc blockProc;
1564 object data;
1565 internal object Call(object val, object self)
1566 {
1567 return blockProc(val, data, self);
1568 }
1569 }
1570
1571 internal class RNRFunc : RNode
1572 {
1573 internal RNRFunc(NetRuby rb, RBasic.RMethod mtd, int ac)
1574 : base(rb.GetCurrentContext())
1575 {
1576 ruby = rb;
1577 method = mtd;
1578 argcnt = ac;
1579 }
1580
1581 event RBasic.RMethod method;
1582 NetRuby ruby;
1583 int argcnt;
1584
1585 public override int argc
1586 {
1587 get { return argcnt; }
1588 }
1589 public override object Funcall(RMetaObject klass, object recver, uint id, object[] args)
1590 {
1591 int ln = (args == null) ? 0 : args.Length;
1592 if (argcnt >= 0 && argcnt != ln)
1593 {
1594 throw new ArgumentException(
1595 String.Format("wrong # of arguments({0} for {1})", ln, argcnt));
1596 }
1597 object ret = method(ruby.InstanceOf(recver), args);
1598 return ret;
1599 }
1600 }
1601
1602 internal class RNBlock : RNode
1603 {
1604 internal RNBlock(RThread th, RNode n)
1605 : base(th)
1606 {
1607 FixPos(n);
1608 bg = n;
1609 ed = this;
1610 nxt = null;
1611 }
1612
1613 RNode bg;
1614 RNode ed;
1615 RNode nxt;
1616
1617 public override RNode head
1618 {
1619 get { return bg; }
1620 set { bg = value; }
1621 }
1622 public override RNode beg
1623 {
1624 get { return bg; }
1625 set { bg = value; }
1626 }
1627 public override RNode end
1628 {
1629 get { return ed; }
1630 set { ed = value; }
1631 }
1632 public override RNode next
1633 {
1634 get { return nxt; }
1635 set { nxt = value; }
1636 }
1637
1638 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
1639 {
1640 b = false;
1641 RNode node = this;
1642 while (node.next != null)
1643 {
1644 if (node.head != null)
1645 {
1646 for (RNode nh = node.head; nh != null; )
1647 {
1648 nh = nh.Compile(ruby, th, pm, out b);
1649 if (b && nh != null)
1650 pm.il.Emit(OpCodes.Pop);
1651 }
1652 }
1653 node = node.next;
1654 if (b && node.next != null)
1655 pm.il.Emit(OpCodes.Pop);
1656 }
1657 return node.head;
1658 }
1659
1660 public override RNode Eval(NetRuby ruby, object self, out object result)
1661 {
1662 #if EVAL_TRACE
1663 System.Console.WriteLine("Eval:" + ToString());
1664 #endif
1665 RNode node = this;
1666 while (node.next != null)
1667 {
1668 ruby.Eval(self, node.head);
1669 node = node.next;
1670 }
1671 result = null;
1672 return node.head;
1673 }
1674
1675 }
1676
1677 internal class RNNewLine : RNode
1678 {
1679 internal RNNewLine(RThread p, RNode n) :
1680 base(p)
1681 {
1682 FixPos(n);
1683 nt = n.Line;
1684 nd = n;
1685 }
1686 int nt;
1687 RNode nd;
1688 public override int nth
1689 {
1690 get { return nt; }
1691 set { nt = value; }
1692 }
1693 public override RNode next
1694 {
1695 get { return nd; }
1696 set { nd = value; }
1697 }
1698
1699 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
1700 {
1701 b = false;
1702 th.file = File;
1703 th.line = nt;
1704 return next;
1705 }
1706 public override RNode Eval(NetRuby ruby, object self, out object result)
1707 {
1708 #if EVAL_TRACE
1709 System.Console.WriteLine("Eval:" + ToString());
1710 #endif
1711 RThread th = ruby.GetCurrentContext();
1712 th.file = File;
1713 th.line = nt;
1714 if (ruby.TraceFunc != null)
1715 {
1716 System.Console.WriteLine("Trace");
1717 }
1718 result = null;
1719 return next;
1720 }
1721 }
1722
1723 internal class RNYield : RNode
1724 {
1725 internal RNYield(RThread p, RNode a) :
1726 base(p)
1727 {
1728 st = a;
1729 }
1730
1731 internal RNYield(RThread p) :
1732 base(p)
1733 {
1734 st = null;
1735 }
1736 public override RNode stts
1737 {
1738 get { return st; }
1739 }
1740 protected RNode st;
1741
1742 public override RNode Eval(NetRuby ruby, object self, out object result)
1743 {
1744 #if EVAL_TRACE
1745 System.Console.WriteLine("Eval:" + ToString());
1746 #endif
1747 object val = null;
1748 if (st != null)
1749 {
1750 val = ruby.Eval(self, st);
1751 if (st is RNRestArgs && ((RArray)val).Count == 1)
1752 {
1753 val = ((RArray)val)[0];
1754 }
1755 }
1756 result = ruby.Yield(val, null, null, false);
1757 return null;
1758 }
1759 }
1760
1761 internal class RNReturn : RNYield
1762 {
1763 internal RNReturn(RThread p, RNode n) :
1764 base(p, n)
1765 {
1766 }
1767 internal RNReturn(RThread p) :
1768 base(p)
1769 {
1770 }
1771
1772 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
1773 {
1774 b = false;
1775 if (st != null)
1776 {
1777 ruby.CompileNode(pm, st, true, th);
1778 }
1779 else
1780 {
1781 pm.il.Emit(OpCodes.Ldnull);
1782 }
1783 pm.Return();
1784 return null;
1785 }
1786 public override RNode Eval(NetRuby ruby, object self, out object result)
1787 {
1788 #if EVAL_TRACE
1789 System.Console.WriteLine("Eval:" + ToString());
1790 #endif
1791 if (st != null)
1792 {
1793 result = ruby.Eval(self, st);
1794 ruby.SetReturnValue(result);
1795 }
1796 else
1797 {
1798 result = null;
1799 ruby.SetReturnValue(null);
1800 }
1801 ruby.ReturnCheck();
1802 throw new eTagJump(Tag.TAG.RETURN);
1803 }
1804 protected override string IsDefined(NetRuby ruby, object self)
1805 {
1806 if (ruby.IsBlockGiven)
1807 return "yield";
1808 return null;
1809 }
1810 }
1811
1812 internal class RNBreak : RNode
1813 {
1814 internal RNBreak(RThread p) :
1815 base(p)
1816 {
1817 }
1818 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
1819 {
1820 b = false;
1821 pm.Break();
1822 return null;
1823 }
1824 public override RNode Eval(NetRuby ruby, object self, out object result)
1825 {
1826 #if EVAL_TRACE
1827 System.Console.WriteLine("Eval:" + ToString());
1828 #endif
1829 throw new eTagJump(Tag.TAG.BREAK);
1830 }
1831 }
1832
1833 internal class RNNext : RNode
1834 {
1835 internal RNNext(RThread p) :
1836 base(p)
1837 {
1838 }
1839 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
1840 {
1841 b = false;
1842 pm.Next();
1843 return null;
1844 }
1845 public override RNode Eval(NetRuby ruby, object self, out object result)
1846 {
1847 #if EVAL_TRACE
1848 System.Console.WriteLine("Eval:" + ToString());
1849 #endif
1850 throw new eTagJump(Tag.TAG.NEXT);
1851 }
1852 }
1853
1854 internal class RNRedo : RNode
1855 {
1856 internal RNRedo(RThread p) :
1857 base(p)
1858 {
1859 }
1860 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
1861 {
1862 b = false;
1863 pm.Redo();
1864 return null;
1865 }
1866 public override RNode Eval(NetRuby ruby, object self, out object result)
1867 {
1868 #if EVAL_TRACE
1869 System.Console.WriteLine("Eval:" + ToString());
1870 #endif
1871 throw new eTagJump(Tag.TAG.REDO);
1872 }
1873 }
1874
1875 internal class RNRetry : RNode
1876 {
1877 internal RNRetry(RThread p) :
1878 base(p)
1879 {
1880 }
1881 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
1882 {
1883 b = false;
1884 pm.Retry();
1885 return null;
1886 }
1887 public override RNode Eval(NetRuby ruby, object self, out object result)
1888 {
1889 #if EVAL_TRACE
1890 System.Console.WriteLine("Eval:" + ToString());
1891 #endif
1892 throw new eTagJump(Tag.TAG.RETRY);
1893 }
1894 }
1895
1896 internal class RNBegin : RNode
1897 {
1898 internal RNBegin(RThread p, RNode b)
1899 : base(p)
1900 {
1901 bdy = b;
1902 }
1903 protected RNode bdy;
1904
1905 public override RNode body
1906 {
1907 get { return bdy; }
1908 set { bdy = value; }
1909 }
1910
1911 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
1912 {
1913 b = true;
1914 ruby.CompileNode(pm, bdy, true, th);
1915 return null;
1916 }
1917
1918 public override RNode Eval(NetRuby ruby, object self, out object result)
1919 {
1920 #if EVAL_TRACE
1921 System.Console.WriteLine("Eval:" + ToString());
1922 #endif
1923 result = null;
1924 return body;
1925 }
1926 }
1927
1928 internal class RNEnsure : RNode
1929 {
1930 internal RNEnsure(RThread p, RNode b, RNode en)
1931 : base(p)
1932 {
1933 ens = en;
1934 bdy = b;
1935 }
1936 public override RNode ensr
1937 {
1938 get { return ens; }
1939 }
1940 RNode ens;
1941 RNode bdy;
1942 }
1943
1944
1945 internal class RNRescue : RNEnsure
1946 {
1947 internal RNRescue(RThread p, RNode b, RNode r, RNode e)
1948 : base(p, b, e)
1949 {
1950 res = r;
1951 }
1952 public override RNode resq
1953 {
1954 get { return res; }
1955 }
1956 RNode res;
1957 }
1958
1959 internal class RNRestArgs : RNode
1960 {
1961 internal RNRestArgs(RThread p, RNode a) :
1962 base(p)
1963 {
1964 hd = a;
1965 }
1966 public override RNode head
1967 {
1968 get { return hd; }
1969 set { hd = value; }
1970 }
1971 RNode hd;
1972 public override RNode Eval(NetRuby ruby, object self, out object result)
1973 {
1974 #if EVAL_TRACE
1975 System.Console.WriteLine("Eval:" + ToString());
1976 #endif
1977 result = ruby.Eval(self, hd);
1978 if (result is RArray == false)
1979 {
1980 RArray a = new RArray(ruby, true);
1981 a.Add(result);
1982 result = a;
1983 }
1984 return null;
1985 }
1986
1987 }
1988
1989 internal class RNBlockArg : RNode
1990 {
1991 internal RNBlockArg(RThread p, uint v, int c) :
1992 base(p)
1993 {
1994 vi = v;
1995 ct = c;
1996 }
1997 public override int cnt
1998 {
1999 get { return ct; }
2000 set { ct = value; }
2001 }
2002 public override uint vid
2003 {
2004 get { return vi; }
2005 }
2006 int ct;
2007 uint vi;
2008 }
2009
2010 internal class RNBlockPass : RNode
2011 {
2012 internal RNBlockPass(RThread p, RNode b) :
2013 base(p)
2014 {
2015 bdy = b;
2016 }
2017 public override RNode head
2018 {
2019 get { return null; }
2020 }
2021 public override RNode body
2022 {
2023 get { return bdy; }
2024 }
2025 RNode bdy;
2026 }
2027
2028 internal class RNIf : RNode
2029 {
2030 internal RNIf(RThread p, RNode c, RNode t, RNode e)
2031 : base(p)
2032 {
2033 FixPos(c);
2034 cd = c;
2035 bdy = t;
2036 el = e;
2037 }
2038 internal RNIf(RThread p, RNode c, RNode t)
2039 : base(p)
2040 {
2041 FixPos(c);
2042 cd = c;
2043 bdy = t;
2044 el = null;
2045 }
2046 protected RNode cd;
2047 protected RNode bdy;
2048 protected RNode el;
2049 public override RNode cond
2050 {
2051 get { return cd; }
2052 }
2053 public override RNode body
2054 {
2055 get { return bdy; }
2056 }
2057 public override RNode nd_else
2058 {
2059 get { return el; }
2060 }
2061 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
2062 {
2063 b = false;
2064 ruby.CompileNode(pm, cond, true, th);
2065 pm.Cond(ruby, th, bdy, el);
2066 return null;
2067 }
2068 public override RNode Eval(NetRuby ruby, object self, out object result)
2069 {
2070 #if EVAL_TRACE
2071 System.Console.WriteLine("Eval:" + ToString());
2072 #endif
2073 ruby.SourceLine = Line;
2074 result = null;
2075 object o = ruby.Eval(self, cond);
2076 if (RTest(o))
2077 {
2078 return bdy;
2079 }
2080 else
2081 {
2082 return el;
2083 }
2084 }
2085 }
2086
2087 internal class RNPreExe : RNScope
2088 {
2089 internal RNPreExe(RThread p, RNode b) :
2090 base(p, b)
2091 {
2092 }
2093 }
2094
2095 internal class RNPostExe : RNode
2096 {
2097 internal RNPostExe(RThread p) :
2098 base(p)
2099 {
2100 onece = false;
2101 }
2102 bool onece;
2103
2104 public override RNode Eval(NetRuby ruby, object self, out object result)
2105 {
2106 #if EVAL_TRACE
2107 System.Console.WriteLine("Eval:" + ToString());
2108 #endif
2109 result = null;
2110 if (onece) return null;
2111 onece = true;
2112 ruby.End();
2113 return null;
2114 }
2115 }
2116
2117 internal class RNDot2 : RNode
2118 {
2119 internal RNDot2(RThread p, RNode b, RNode e) :
2120 base(p)
2121 {
2122 bg = b;
2123 ed = e;
2124 }
2125 protected RNode bg;
2126 protected RNode ed;
2127
2128 public override RNode beg
2129 {
2130 get { return bg; }
2131 set { bg = value; }
2132 }
2133 public override RNode end
2134 {
2135 get { return ed; }
2136 set { ed = value; }
2137 }
2138 }
2139
2140 internal class RNDot3 : RNDot2
2141 {
2142 internal RNDot3(RThread p, RNode b, RNode e) :
2143 base(p, b, e)
2144 {
2145 }
2146 }
2147
2148 internal class RNUnless : RNIf
2149 {
2150 internal RNUnless(RThread p, RNode c, RNode t, RNode e)
2151 : base(p, c, e, t)
2152 {
2153 }
2154 internal RNUnless(RThread p, RNode c, RNode t)
2155 : base(p, c, null, t)
2156 {
2157 }
2158
2159 }
2160
2161 internal class RNAlias : RNode
2162 {
2163 internal RNAlias(RThread p, uint n, uint o)
2164 : base(p)
2165 {
2166 od = o;
2167 nw = n;
2168 }
2169 public override uint old
2170 {
2171 get { return od; }
2172 }
2173 public override uint nd_new
2174 {
2175 get { return nw; }
2176 }
2177 public override uint mid
2178 {
2179 get { return nw; }
2180 }
2181 protected uint nw;
2182 protected uint od;
2183
2184 public override RNode Eval(NetRuby ruby, object self, out object result)
2185 {
2186 #if EVAL_TRACE
2187 System.Console.WriteLine("Eval:" + ToString());
2188 #endif
2189 result = null;
2190 RThread th = ruby.GetCurrentContext();
2191 RMetaObject rc = th.rClass;
2192 if (rc == null)
2193 {
2194 throw new eTypeError("no class to make alias");
2195 }
2196 rc.DefineAlias(nw, od);
2197 ruby.Funcall(rc, "method_added", nw);
2198 return null;
2199 }
2200 }
2201
2202 internal class RNVAlias : RNAlias
2203 {
2204 internal RNVAlias(RThread p, uint n, uint o)
2205 : base(p, o, n)
2206 {
2207 }
2208 }
2209
2210 internal class RNUndef : RNode
2211 {
2212 internal RNUndef(RThread p, uint id) :
2213 base(p)
2214 {
2215 mi = id;
2216 }
2217 uint mi;
2218 public override uint mid
2219 {
2220 get { return mi; }
2221 }
2222 }
2223
2224 internal class RNClassBase : RNode
2225 {
2226 protected RNClassBase(RThread p, uint n, RNode b, RNode s) :
2227 base(p)
2228 {
2229 cn = n;
2230 sprcls = s;
2231 bdy = new RNScope(p, b);
2232 }
2233 protected RNode sprcls;
2234 protected uint cn;
2235 protected RNode bdy;
2236 public override uint cname
2237 {
2238 get { return cn; }
2239 }
2240 public override RNode body
2241 {
2242 get { return bdy; }
2243 }
2244 public override RNode super
2245 {
2246 get { return sprcls; }
2247 }
2248 }
2249
2250 internal class RNClass : RNClassBase
2251 {
2252 internal RNClass(RThread p, uint n, RNode b, RNode s) :
2253 base(p, n, b, s)
2254 {
2255 }
2256
2257 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
2258 {
2259 b = true;
2260 ILGenerator il = pm.il;
2261 il.BeginScope();
2262 LocalBuilder spr = il.DeclareLocal(typeof(RMetaObject));
2263 spr.SetLocalSymInfo("super");
2264 LocalBuilder klass = il.DeclareLocal(typeof(RClass));
2265 klass.SetLocalSymInfo("klass");
2266 Label skipType = il.DefineLabel();
2267 if (sprcls != null)
2268 {
2269 Superclass(ruby, th, pm);
2270 }
2271 else
2272 {
2273 pm.LoadRuby();
2274 il.Emit(OpCodes.Ldfld, typeof(NetRuby).GetField("cObject"));
2275 }
2276 il.Emit(OpCodes.Stloc, spr);
2277 string name = ruby.id2name(cn);
2278 pm.LoadRuby();
2279 pm.LoadTh();
2280 pm.LoadInt((int)cn);
2281 il.Emit(OpCodes.Ldloc, spr);
2282 il.Emit(OpCodes.Call, typeof(RClass).GetMethod("CheckClass"));
2283 il.Emit(OpCodes.Dup);
2284 il.Emit(OpCodes.Brtrue, skipType);
2285 il.Emit(OpCodes.Pop);
2286 TypeBuilder tb = ruby.dynModule.DefineType(name, TypeAttributes.Public, typeof(RClass));
2287 ConstructorBuilder cb = tb.DefineConstructor(
2288 MethodAttributes.Public,
2289 CallingConventions.Standard,
2290 new Type[] {typeof(NetRuby), typeof(RMetaObject)});
2291 ILGenerator cilg = cb.GetILGenerator();
2292 cilg.Emit(OpCodes.Ldarg_0);
2293 cilg.Emit(OpCodes.Ldarg_1);
2294 cilg.Emit(OpCodes.Ldstr, name);
2295 cilg.Emit(OpCodes.Ldarg_2);
2296 ConstructorInfo supctr = typeof(RClass).GetConstructor(
2297 BindingFlags.Instance | BindingFlags.Public, null,
2298 new Type[] {typeof(NetRuby), typeof(string), typeof(RMetaObject)}, null);
2299 cilg.Emit(OpCodes.Call, supctr);
2300 cilg.Emit(OpCodes.Ret);
2301
2302 pm.LoadRuby();
2303 il.Emit(OpCodes.Ldloc, spr);
2304 il.Emit(OpCodes.Newobj, cb);
2305 pm.LoadInt((int)cn);
2306 il.Emit(OpCodes.Ldstr, name);
2307 il.Emit(OpCodes.Ldloc, spr);
2308 pm.LoadTh();
2309 il.Emit(OpCodes.Call, typeof(RThread).GetMethod("get_OuterClass"));
2310 il.Emit(OpCodes.Call, typeof(RClass).GetMethod("DefineNewClass"));
2311 il.MarkLabel(skipType);
2312 il.Emit(OpCodes.Stloc, klass);
2313 pm.LoadTh();
2314 il.Emit(OpCodes.Ldloc, klass);
2315 il.Emit(OpCodes.Call, typeof(RThread).GetMethod("SetWrapper"));
2316 MethodBuilder mb = tb.DefineMethod("Init",
2317 MethodAttributes.Public |
2318 MethodAttributes.Static,
2319 typeof(object), new Type[] { typeof(RClass) });
2320 using (ScopedILParam npm = new ScopedILParam(tb, mb))
2321 {
2322 npm.InitLocalTable(ruby, bdy.tbl);
2323 ILGenerator ilnew = npm.il;
2324 LocalBuilder cls = ilnew.DeclareLocal(typeof(RMetaObject));
2325 npm.LoadTh();
2326 ilnew.Emit(OpCodes.Ldarg_0);
2327 ilnew.Emit(OpCodes.Call, typeof(RThread).GetMethod("PushClass"));
2328 ilnew.Emit(OpCodes.Stloc, cls);
2329 ruby.CompileNode(npm, bdy.next, true, th);
2330
2331 if (npm.MethodList != null)
2332 {
2333 foreach (Type typ in npm.MethodList)
2334 {
2335 ilnew.Emit(OpCodes.Ldarg_0);
2336 ilnew.Emit(OpCodes.Call, typ.GetMethod("Init", BindingFlags.Static | BindingFlags.Public));
2337 }
2338 }
2339 npm.LoadTh();
2340 ilnew.Emit(OpCodes.Ldloc, cls);
2341 ilnew.Emit(OpCodes.Call, typeof(RThread).GetMethod("PopClass"));
2342 }
2343 il.Emit(OpCodes.Ldloc, klass);
2344 il.Emit(OpCodes.Call, mb);
2345 Type tp = tb.CreateType();
2346 il.EndScope();
2347 return null;
2348 }
2349
2350 public override RNode Eval(NetRuby ruby, object self, out object result)
2351 {
2352 #if EVAL_TRACE
2353 System.Console.WriteLine("Eval:" + ToString());
2354 #endif
2355 RThread th = ruby.GetCurrentContext();
2356 RMetaObject rc = th.OuterClass;
2357 RClass spr;
2358 if (sprcls != null)
2359 {
2360 spr = Superclass(ruby, self);
2361 }
2362 else
2363 {
2364 spr = null;
2365 }
2366 RClass klass = RClass.CheckClass(ruby, th, cn, spr);
2367 if (klass == null)
2368 {
2369 string name = ruby.id2name(cn);
2370 klass = RClass.ClassNew(ruby, spr, null);
2371 klass.SetClassPath(rc, name);
2372 rc.ConstSet(cn, klass);
2373 }
2374 th.SetWrapper(klass);
2375 result = ruby.ModuleSetup(klass, bdy);
2376 return null;
2377 }
2378
2379 private RClass Superclass(NetRuby ruby, object self)
2380 {
2381 object o = null;
2382 try
2383 {
2384 o = ruby.Eval(self, sprcls);
2385 }
2386 catch (Exception)
2387 {
2388 o = null;
2389 }
2390 if (o == null || (o is RClass == false))
2391 {
2392 if (sprcls is RNColon2)
2393 throw new eTypeError("undefined superclass `" + ruby.id2name(sprcls.mid) + "'");
2394 if (sprcls is RNConst)
2395 throw new eTypeError("undefined superclass `" + ruby.id2name(sprcls.vid) + "'");
2396 throw new eTypeError("superclass undefined");
2397 }
2398 RClass spr = (RClass)o;
2399 if (spr.IsSingleton)
2400 {
2401 throw new eTypeError("can't make subclass of virtual class");
2402 }
2403 return spr;
2404 }
2405 private void Superclass(NetRuby ruby, RThread th, ILParam pm)
2406 {
2407 ruby.CompileNode(pm, sprcls, true, th);
2408 }
2409 }
2410
2411 internal class RNSClass : RNClassBase
2412 {
2413 internal RNSClass(RThread p, RNode r, RNode b) :
2414 base(p, 0, b, null)
2415 {
2416 FixPos(r);
2417 rv = r;
2418 }
2419 RNode rv;
2420 public override RNode recv
2421 {
2422 get { return rv; }
2423 }
2424 public override RNode Eval(NetRuby ruby, object self, out object result)
2425 {
2426 #if EVAL_TRACE
2427 System.Console.WriteLine("Eval:" + ToString());
2428 #endif
2429 RMetaObject klass;
2430 result = ruby.Eval(self, rv);
2431 RThread th = ruby.GetCurrentContext();
2432 if (result is bool)
2433 {
2434 if ((bool)result)
2435 klass = ruby.cTrueClass;
2436 else
2437 klass = ruby.cFalseClass;
2438 }
2439 else if (result == null)
2440 {
2441 klass = ruby.cNilClass;
2442 }
2443 else
2444 {
2445 if (RBasic.IsSpecialConstType(result))
2446 throw new eTypeError("no virtual class for " + ruby.ClassOf(result).Name);
2447 RBasic bas = ruby.InstanceOf(result);
2448 if (th.safeLevel >= 4 && bas.IsTainted == false)
2449 throw new SecurityException("Insecure: can't extend object");
2450 if (ruby.ClassOf(bas) is RSingletonClass)
2451 {
2452 ; // why clear cache ?
2453 }
2454 klass = RBasic.SingletonClass(bas, ruby);
2455 }
2456 th.SetWrapper(klass);
2457 result = ruby.ModuleSetup(klass, bdy);
2458 return null;
2459 }
2460 }
2461
2462 internal class RNModule : RNClassBase
2463 {
2464 internal RNModule(RThread p, uint n, RNode b) :
2465 base(p, n, b, null)
2466 {
2467 }
2468 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
2469 {
2470 b = true;
2471 string name = ruby.id2name(cn);
2472 ILGenerator il = pm.il;
2473 il.BeginScope();
2474 LocalBuilder module = il.DeclareLocal(typeof(RModule));
2475 module.SetLocalSymInfo("module");
2476 Label skipType = il.DefineLabel();
2477 pm.LoadRuby();
2478 pm.LoadTh();
2479 pm.LoadInt((int)cn);
2480 il.Emit(OpCodes.Call, typeof(RModule).GetMethod("CheckModule"));
2481 il.Emit(OpCodes.Dup);
2482 il.Emit(OpCodes.Brtrue, skipType);
2483 il.Emit(OpCodes.Pop);
2484 TypeBuilder tb = ruby.dynModule.DefineType(name, TypeAttributes.Public, typeof(RModule));
2485 ConstructorBuilder cb = tb.DefineConstructor(
2486 MethodAttributes.Public,
2487 CallingConventions.Standard,
2488 new Type[] {typeof(NetRuby) });
2489 ILGenerator cilg = cb.GetILGenerator();
2490 cilg.Emit(OpCodes.Ldarg_0);
2491 cilg.Emit(OpCodes.Ldarg_1);
2492 cilg.Emit(OpCodes.Ldstr, name);
2493 ConstructorInfo supctr = typeof(RModule).GetConstructor(
2494 BindingFlags.Instance | BindingFlags.Public, null,
2495 new Type[] {typeof(NetRuby), typeof(string) }, null);
2496 cilg.Emit(OpCodes.Call, supctr);
2497 cilg.Emit(OpCodes.Ret);
2498 pm.LoadRuby();
2499 il.Emit(OpCodes.Newobj, cb);
2500 il.Emit(OpCodes.Dup);
2501 pm.LoadTh();
2502 il.Emit(OpCodes.Call, typeof(RThread).GetMethod("get_OuterClass"));
2503 il.Emit(OpCodes.Ldstr, name);
2504 il.Emit(OpCodes.Call, typeof(RModule).GetMethod("SetClassPath"));
2505 il.MarkLabel(skipType);
2506 il.Emit(OpCodes.Stloc, module);
2507 pm.LoadTh();
2508 il.Emit(OpCodes.Ldloc, module);
2509 il.Emit(OpCodes.Call, typeof(RThread).GetMethod("SetWrapper"));
2510 MethodBuilder mb = tb.DefineMethod("Init",
2511 MethodAttributes.Public |
2512 MethodAttributes.Static,
2513 typeof(object), new Type[] { typeof(RModule) });
2514 using (ScopedILParam npm = new ScopedILParam(tb, mb))
2515 {
2516 npm.InitLocalTable(ruby, bdy.tbl);
2517 ILGenerator ilnew = npm.il;
2518 LocalBuilder cls = ilnew.DeclareLocal(typeof(RMetaObject));
2519 npm.LoadTh();
2520 ilnew.Emit(OpCodes.Ldarg_0);
2521 ilnew.Emit(OpCodes.Call, typeof(RThread).GetMethod("PushClass"));
2522 ilnew.Emit(OpCodes.Stloc, cls);
2523 ruby.CompileNode(npm, bdy.next, true, th);
2524
2525 if (npm.MethodList != null)
2526 {
2527 foreach (Type typ in npm.MethodList)
2528 {
2529 ilnew.Emit(OpCodes.Ldarg_0);
2530 ilnew.Emit(OpCodes.Call, typ.GetMethod("Init", BindingFlags.Static | BindingFlags.Public));
2531 }
2532 }
2533 npm.LoadTh();
2534 ilnew.Emit(OpCodes.Ldloc, cls);
2535 ilnew.Emit(OpCodes.Call, typeof(RThread).GetMethod("PopClass"));
2536 }
2537 il.Emit(OpCodes.Ldloc, module);
2538 il.Emit(OpCodes.Call, mb);
2539 Type tp = tb.CreateType();
2540 il.EndScope();
2541
2542 return null;
2543 }
2544 public override RNode Eval(NetRuby ruby, object self, out object result)
2545 {
2546 #if EVAL_TRACE
2547 System.Console.WriteLine("Eval:" + ToString());
2548 #endif
2549 RThread th = ruby.GetCurrentContext();
2550 RMetaObject rClass = th.OuterClass;
2551 if ((rClass == ruby.cObject) && ruby.IsAutoloadDefined(cn))
2552 {
2553 ruby.AutoLoad(cn);
2554 }
2555 RMetaObject module = RModule.CheckModule(ruby, th, cn);
2556 if (module == null)
2557 {
2558 string name = ruby.id2name(cn);
2559 module = new RModule(ruby, name);
2560 module.SetClassPath(rClass, name);
2561 }
2562 th.SetWrapper(module);
2563 result = ruby.ModuleSetup(module, bdy);
2564 return null;
2565 }
2566 }
2567
2568 internal class RNColon3 : RNode
2569 {
2570 internal RNColon3(RThread p, uint i) :
2571 base(p)
2572 {
2573 mi = i;
2574 }
2575 protected uint mi;
2576 public override uint mid
2577 {
2578 get { return mi; }
2579 }
2580 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
2581 {
2582 ruby.id2name(mi);
2583 b = true;
2584 ILGenerator il = pm.il;
2585 pm.LoadRuby();
2586 il.Emit(OpCodes.Ldfld, typeof(NetRuby).GetField("cObject"));
2587 pm.LoadInt((int)mi);
2588 il.Emit(OpCodes.Call, typeof(RClass).GetMethod("ConstGetAt"));
2589 return null;
2590 }
2591 public override RNode Eval(NetRuby ruby, object self, out object result)
2592 {
2593 #if EVAL_TRACE
2594 System.Console.WriteLine("Eval:" + ToString());
2595 #endif
2596 result = ruby.cObject.ConstGetAt(mi);
2597 return null;
2598 }
2599 }
2600
2601 internal class RNColon2 : RNColon3
2602 {
2603 internal RNColon2(RThread p, RNode c, uint i) :
2604 base(p, i)
2605 {
2606 hd = c;
2607 }
2608 RNode hd;
2609 public override RNode head
2610 {
2611 get { return hd; }
2612 }
2613 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
2614 {
2615 ruby.id2name(mi);
2616 b = true;
2617 ILGenerator il = pm.il;
2618 Label callLabel = il.DefineLabel();
2619 Label exitLabel = il.DefineLabel();
2620 ruby.CompileNode(pm, hd, true, th);
2621 il.Emit(OpCodes.Dup);
2622 il.Emit(OpCodes.Isinst, typeof(RMetaObject));
2623 il.Emit(OpCodes.Brfalse, callLabel);
2624 pm.LoadInt((int)mi);
2625 il.Emit(OpCodes.Call, typeof(RMetaObject).GetMethod("ConstGet"));
2626 il.Emit(OpCodes.Br, exitLabel);
2627 il.MarkLabel(callLabel);
2628 pm.SaveResult();
2629 pm.LoadRuby();
2630 pm.LoadResult();
2631 pm.LoadInt((int)mi);
2632 il.Emit(OpCodes.Ldnull);
2633 il.Emit(OpCodes.Call, typeof(NetRuby).GetMethod("Funcall", BindingFlags.Instance | BindingFlags.Public, null, new Type[]{typeof(object), typeof(uint), typeof(object[])}, null));
2634 il.MarkLabel(exitLabel);
2635 return null;
2636 }
2637 public override RNode Eval(NetRuby ruby, object self, out object result)
2638 {
2639 #if EVAL_TRACE
2640 System.Console.WriteLine("Eval:" + ToString());
2641 #endif
2642 object o = ruby.Eval(self, hd);
2643 if (o is RMetaObject == false)
2644 result = ruby.Funcall(o, mi);
2645 else
2646 result = ((RMetaObject)o).ConstGet(mi);
2647 return null;
2648 }
2649 protected override string IsDefined(NetRuby ruby, object self)
2650 {
2651 ruby.bug("not defined yet");
2652 return null;
2653 }
2654 }
2655
2656 internal class RNCRef : RNode
2657 {
2658 internal RNCRef(RMetaObject c1, RNode c2) :
2659 base((RThread)null)
2660 {
2661 cls = c1;
2662 nxt = c2;
2663 }
2664 internal RNCRef(RMetaObject c1) :
2665 base((RThread)null)
2666 {
2667 cls = c1;
2668 nxt = null;
2669 }
2670 RMetaObject cls;
2671 RNode nxt;
2672 public override RMetaObject clss
2673 {
2674 get { return cls; }
2675 }
2676 public override RNode next
2677 {
2678 get { return nxt; }
2679 set { nxt = value; }
2680 }
2681
2682 internal bool ConstDefined(NetRuby ruby, uint id, object self)
2683 {
2684 RNode cbase = this;
2685 while (cbase != null && cbase.next != null)
2686 {
2687 RMetaObject klass = cbase.clss;
2688 if (klass == null) return ruby.ClassOf(self).IsConstDefined(id);
2689 string s;
2690 if (klass.iv_tbl != null && klass.iv_tbl.lookup(id, out s))
2691 return true;
2692 cbase = cbase.next;
2693 }
2694 return cls.IsConstDefined(id);
2695 }
2696 }
2697
2698 internal class RNWhile : RNode
2699 {
2700 internal RNWhile(RThread p, RNode c, RNode b, bool n)
2701 : base(p)
2702 {
2703 cd = c;
2704 bd = b;
2705 st = n;
2706 }
2707 bool st;
2708 RNode cd;
2709 RNode bd;
2710 public override bool state
2711 {
2712 get { return st; }
2713 set { st = value; }
2714 }
2715 public override RNode cond
2716 {
2717 get { return cd; }
2718 }
2719 public override RNode body
2720 {
2721 get { return bd; }
2722 }
2723 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
2724 {
2725 b = true;
2726 using (CondILParam npm = new CondILParam(pm))
2727 {
2728 th.line = Line;
2729 if (st)
2730 {
2731 ruby.CompileNode(npm, cd, true, th);
2732 npm.CondBreak(CondBreak);
2733 }
2734 npm.CondLoop(ruby, th, body);
2735 ruby.CompileNode(npm, cd, true, th);
2736 npm.CondCont(CondCont);
2737 }
2738 pm.il.Emit(OpCodes.Ldnull);
2739 return null;
2740 }
2741 protected virtual OpCode CondBreak
2742 {
2743 get { return OpCodes.Brfalse; }
2744 }
2745 protected virtual OpCode CondCont
2746 {
2747 get { return OpCodes.Brtrue; }
2748 }
2749 public override RNode Eval(NetRuby ruby, object self, out object result)
2750 {
2751 #if EVAL_TRACE
2752 System.Console.WriteLine("Eval:" + ToString());
2753 #endif
2754 result = ruby.ConditionalLoop(this, self, true);
2755 return null;
2756 }
2757 }
2758
2759 internal class RNUntil : RNWhile
2760 {
2761 internal RNUntil(RThread p, RNode c, RNode b, bool n)
2762 : base(p, c, b, n)
2763 {
2764 }
2765 protected override OpCode CondBreak
2766 {
2767 get { return OpCodes.Brtrue; }
2768 }
2769 protected override OpCode CondCont
2770 {
2771 get { return OpCodes.Brfalse; }
2772 }
2773 public override RNode Eval(NetRuby ruby, object self, out object result)
2774 {
2775 #if EVAL_TRACE
2776 System.Console.WriteLine("Eval:" + ToString());
2777 #endif
2778 result = ruby.ConditionalLoop(this, self, false);
2779 return null;
2780 }
2781 }
2782
2783 internal class RNCase : RNode
2784 {
2785 internal RNCase(RThread p, RNode h, RNode b)
2786 : base(p)
2787 {
2788 hd = h;
2789 bd = b;
2790 }
2791 RNode hd;
2792 RNode bd;
2793 public override RNode head
2794 {
2795 get { return hd; }
2796 }
2797 public override RNode body
2798 {
2799 get { return bd; }
2800 }
2801 }
2802
2803 internal class RNList : RNode
2804 {
2805 protected RNList(RThread p, RNode n1, RNode n2, RNode n3) :
2806 base(p)
2807 {
2808 hd = n1;
2809 bd = n2;
2810 nxt = n3;
2811 }
2812 protected RNode hd;
2813 protected RNode bd;
2814 protected RNode nxt;
2815 public override RNode head
2816 {
2817 get { return hd; }
2818 set { hd = value; }
2819 }
2820 public override RNode body
2821 {
2822 get { return bd; }
2823 set { bd = value; }
2824 }
2825 public override RNode next
2826 {
2827 get { return nxt; }
2828 set { nxt = value; }
2829 }
2830 }
2831 internal class RNWhen : RNList
2832 {
2833 internal RNWhen(RThread p, RNode c, RNode t, RNode e) :
2834 base(p, c, t, e)
2835 {
2836 }
2837
2838 internal RNWhen(RThread p, RNode c) :
2839 base(p, c, null, null)
2840 {
2841 }
2842 }
2843
2844 internal class RNFor : RNList
2845 {
2846 internal RNFor(RThread p, RNode v, RNode i, RNode b)
2847 : base(p, v, b, i)
2848 {
2849 if (v != null) FixPos(v);
2850 }
2851 public override RNode var
2852 {
2853 get { return hd; }
2854 }
2855 public override RNode iter
2856 {
2857 get { return nxt; }
2858 set { nxt = value; }
2859 }
2860 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
2861 {
2862 b = true;
2863 TypeBuilder tb = null;
2864 using (ILParam npm = IterBase.NewIter(ruby))
2865 {
2866 ILGenerator il = npm.il;
2867 if (var != null && var is RNBlockNoArg == false)
2868 {
2869 il.Emit(OpCodes.Ldarg_1);
2870 var.Assign(ruby, th, npm);
2871 }
2872 ruby.CompileNode(npm, body, true, th);
2873 tb = npm.tb;
2874 }
2875 Type tp = tb.CreateType();
2876 pm.OpenIterBlock(tp);
2877 // try
2878 CompileIteration(ruby, th, pm);
2879 // catch
2880 pm.CloseIterBlock();
2881 pm.LoadResult();
2882 return null;
2883 }
2884 protected virtual void CompileIteration(NetRuby ruby, RThread th, ILParam pm)
2885 {
2886 ILGenerator il = pm.il;
2887
2888 string file = th.file;
2889 int line = th.line;
2890 il.Emit(OpCodes.Ldloc, pm._Block);
2891 il.Emit(OpCodes.Ldc_I4_0);
2892 il.Emit(OpCodes.Call, typeof(Block).GetMethod("set_DScope"));
2893
2894 LocalBuilder tempblock = il.DeclareLocal(typeof(Block));
2895 tempblock.SetLocalSymInfo("tempBlock");
2896 pm.LoadTh();
2897 il.Emit(OpCodes.Call, typeof(RThread).GetMethod("AdjustBlock"));
2898 il.Emit(OpCodes.Stloc, tempblock);
2899
2900 ruby.CompileNode(pm, iter, true, th);
2901 pm.SaveResult(); // recv
2902
2903 pm.LoadTh();
2904 il.Emit(OpCodes.Ldloc, tempblock);
2905 il.Emit(OpCodes.Call, typeof(RThread).GetMethod("RestoreBlock"));
2906
2907 th.file = file;
2908 th.line = line;
2909 pm.LoadRuby();
2910 pm.LoadResult();
2911 pm.LoadInt((int)ruby.intern("each"));
2912 il.Emit(OpCodes.Ldnull);
2913 il.Emit(OpCodes.Call, typeof(NetRuby).GetMethod("IFuncall"));
2914 pm.SaveResult();
2915 }
2916
2917 public override RNode Eval(NetRuby ruby, object self, out object result)
2918 {
2919 #if EVAL_TRACE
2920 System.Console.WriteLine("Eval:" + ToString());
2921 #endif
2922 result = ruby.Iteration(this, self);
2923 return null;
2924 }
2925 }
2926
2927 internal class RNCall : RNode
2928 {
2929 internal RNCall(RThread p, RNode r, uint m, RNode a) :
2930 base(p)
2931 {
2932 rv = r;
2933 ag = a;
2934 mi = m;
2935 }
2936 protected uint mi;
2937 protected RNode rv;
2938 protected RNode ag;
2939 public override RNode recv
2940 {
2941 get { return rv; }
2942 }
2943 public override uint mid
2944 {
2945 get { return mi; }
2946 }
2947 public override RNode args
2948 {
2949 get { return ag; }
2950 set { ag = value; }
2951 }
2952 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
2953 {
2954 // force intern if attrset or const
2955 ruby.id2name(mi);
2956 #if INVOKE_DEBUG
2957 System.Console.WriteLine("Call:Compile:Method=" + ruby.id2name(mi));
2958 pm.il.EmitWriteLine("RNCall:Compile");
2959 #endif
2960 b = true;
2961 ruby.CompileNode(pm, recv, true, th);
2962 CallArgs(ruby, th, pm);
2963 pm.SaveReceiver();
2964 pm.LoadRuby();
2965 pm.il.Emit(OpCodes.Ldloc, pm.Receiver);
2966 pm.il.Emit(OpCodes.Ldc_I4, mi);
2967 pm.il.Emit(OpCodes.Ldloc, pm.Args);
2968 pm.il.Emit(OpCodes.Call, typeof(NetRuby).GetMethod("Funcall", BindingFlags.Instance | BindingFlags.Public, null, new Type[]{typeof(object), typeof(uint), typeof(object[])}, null));
2969 #if INVOKE_DEBUG
2970 pm.il.EmitWriteLine("RNCall:Compile-exit");
2971 #endif
2972 CleanupArgs(ruby, th, pm);
2973 return null;
2974 }
2975 public override RNode Eval(NetRuby ruby, object self, out object result)
2976 {
2977 #if EVAL_TRACE
2978 System.Console.WriteLine("Eval:" + ToString());
2979 #endif
2980 object receiver;
2981 object[] argv = ruby.CallArgs(this, self, out receiver);
2982 #if INVOKE_DEBUG
2983 System.Console.WriteLine("mid=" + ruby.id2name(mi) + ",receiver=" + ((receiver==null)?"null":(receiver is RBasic)?((RBasic)receiver).Inspect().ToString():receiver.ToString()) + ", klass=" + (ruby.ClassOf(receiver).Name));
2984 #endif
2985 result = ruby.Call(ruby.ClassOf(receiver), receiver, mi, argv, 0);
2986 return null;
2987 }
2988
2989 internal object[] SetupArgs(NetRuby ruby, object self, out object receiver)
2990 {
2991 receiver = ruby.Eval(self, recv);
2992 return SetupArgs(ruby, self, args);
2993 }
2994
2995 public override object Assign(NetRuby ruby, object self, object val, bool check)
2996 {
2997 System.Console.WriteLine(String.Format("Assign for {0} into {1} by {2}",
2998 (val == null) ? "null" : val.ToString(),
2999 (self == null) ? "null" : self.ToString(),
3000 ToString()));
3001 System.Console.WriteLine("NOT YET IMPLEMENTED!!");
3002 return null;
3003 }
3004
3005 protected string CheckBound(NetRuby ruby, RMetaObject o, object self)
3006 {
3007 if (GetType().IsSubclassOf(typeof(RNCall)))
3008 {
3009 if (ruby.IsMethodBound(o, mi, false) == false)
3010 return null;
3011 }
3012 else
3013 {
3014 NOEX noex;
3015 uint id = mi;
3016 if (o.GetMethodBody(ref id, out o, out noex) == null)
3017 return null;
3018 if ((noex & NOEX.PRIVATE) != 0)
3019 return null;
3020 if ((noex & NOEX.PROTECTED) != 0)
3021 {
3022 if (ruby.InstanceOf(self).IsKindOf(o.ClassReal) == false)
3023 return null;
3024 }
3025 }
3026 return ArgDefined(ruby, self, ag, "method");
3027 }
3028 protected override string IsDefined(NetRuby ruby, object self)
3029 {
3030 if (IsDefined(ruby, self, rv) == null) return null;
3031 RThread th = ruby.GetCurrentContext();
3032 object o = null;
3033 th.PushTag(Tag.TAG.PROT_NONE);
3034 try
3035 {
3036 o = ruby.Eval(self, rv);
3037 return CheckBound(ruby, ruby.ClassOf(o), self);
3038 }
3039 catch
3040 {
3041 th.errInfo = null;
3042 return null;
3043 }
3044 finally
3045 {
3046 th.PopTag(false);
3047 }
3048 }
3049 }
3050
3051 internal class RNFCall : RNCall
3052 {
3053 internal RNFCall(RThread p, uint m, RNode a) :
3054 base(p, null, m, a)
3055 {
3056 }
3057
3058 internal RNFCall(RThread p, uint m) :
3059 base(p, null, m, null)
3060 {
3061 }
3062
3063 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
3064 {
3065 ruby.id2name(mi);
3066 #if INVOKE_DEBUG
3067 System.Console.WriteLine("FCall:Compile:Method=" + ruby.id2name(mi));
3068 pm.il.EmitWriteLine("RNFCall:Compile");
3069 #endif
3070 b = true;
3071 CallArgs(ruby, th, pm);
3072 pm.LoadRuby();
3073 pm.il.Emit(OpCodes.Ldarg_0);
3074 pm.il.Emit(OpCodes.Ldc_I4, mi);
3075 pm.il.Emit(OpCodes.Ldloc, pm.Args);
3076 pm.il.Emit(OpCodes.Call, typeof(NetRuby).GetMethod("Funcall", BindingFlags.Instance | BindingFlags.Public, null, new Type[]{typeof(object), typeof(uint), typeof(object[])}, null));
3077 #if INVOKE_DEBUG
3078 pm.il.EmitWriteLine("RNFCall:Compile-exit");
3079 #endif
3080 CleanupArgs(ruby, th, pm);
3081 return null;
3082 }
3083 public override RNode Eval(NetRuby ruby, object self, out object result)
3084 {
3085 #if EVAL_TRACE
3086 System.Console.WriteLine("Eval:" + ToString());
3087 #endif
3088 object[] args = ruby.CallArgs(this, self);
3089 result = ruby.Call(ruby.ClassOf(self), self, mi, args, 1);
3090 return null;
3091 }
3092 protected override string IsDefined(NetRuby ruby, object self)
3093 {
3094 RMetaObject o = ruby.ClassOf(self);
3095 return CheckBound(ruby, o, self);
3096 }
3097 }
3098
3099 internal class RNVCall : RNCall
3100 {
3101 internal RNVCall(RThread p, uint m) :
3102 base(p, null, m, null)
3103 {
3104 }
3105
3106 internal RNVCall(RThread p) :
3107 base(p, null, 0, null)
3108 {
3109 }
3110 public override RNode Compile(NetRuby ruby, RThread th, ILParam pm, out bool b)
3111 {
3112 ruby.id2name(mi);
3113 #if INVOKE_DEBUG
3114 System.Console.WriteLine("VCall:Compile:Method=" + ruby.id2name(mi));
3115 pm.il.EmitWriteLine("RNVCall:Compile");
3116 #endif
3117 b = true;
3118 pm.LoadRuby();
3119 pm.il.Emit(OpCodes.Ldarg_0);
3120 pm.il.Emit(OpCodes.Ldc_I4, mi);
3121 pm.il.Emit(OpCodes.Ldnull);
3122 pm.il.Emit(OpCodes.Call, typeof(NetRuby).GetMethod("VFuncall", BindingFlags.Instance | BindingFlags.Public, null, new Type[]{typeof(object), typeof(uint), typeof(object[])}, null));
3123 #if INVOKE_DEBUG
3124 pm.il.EmitWriteLine("RNVCall:Compile-exit");
3125 #endif
3126 return null;
3127 }
3128 public override RNode Eval(NetRuby ruby, object self, out object result)
3129 {
3130 #if EVAL_TRACE
3131 System.Console.WriteLine("Eval:" + ToString());
3132 #endif
3133 result = ruby.Call(ruby.ClassOf(self), self, mid, new object[0], 2);
3134 return null;
3135 }
3136