root/as2/E3Engine/VirtualMachine.as

リビジョン 299, 19.4 kB (コミッタ: yossy, コミット時期: 4 年 前)

Imported Lab code.

Line 
1 class VirtualMachine
2 {
3         private var byteCode:Array;
4         private var byteCodeLength:Number;
5        
6         private var programCounter:Number;
7        
8         private var global:Object;
9         private var localObject:Object;
10         private var thisObject:Object;
11        
12         private var returnValue:Object;
13        
14         private var stack:Array;
15        
16         public function VirtualMachine ()
17         {
18                 initialize();
19         }
20        
21         public function initialize () : Void
22         {
23                 programCounter = 1;
24                 byteCode = new Array();
25                
26                 stack = new Array();
27                
28                 global = new Object();
29                 global.__scope = null;
30                 localObject = global;
31                 thisObject = global;
32         }
33        
34         public function getGlobalObject () : Object
35         {
36                 return global;
37         }
38         public function setByteCode (byteCode:Array) : Void
39         {
40                 this.byteCode = byteCode;
41                 byteCodeLength = byteCode.length;
42         }
43        
44         public function execute () : Boolean
45         {
46                 var _byteCode:Array = byteCode;
47                 var _programCounter:Number = programCounter;
48                
49                 var _byteCodeLength:Number = byteCodeLength;
50                
51                 var next:Number;
52                
53                 for (; _programCounter < _byteCodeLength; ) {
54                         // trace("proccess : "+("00"+_programCounter).substr(-2,2)+" : "+_byteCode[_programCounter]);
55                         if ((next = this[_byteCode[_programCounter]](_byteCode, _programCounter)) == null) {
56                                
57                                 programCounter = _programCounter + 1;
58                                 // このタイミングでいらない値は破棄しておこう...
59                                 delete _byteCode[0];
60                                
61                                 return true;
62                         }
63                         _programCounter = next;
64                 }
65                
66                 programCounter = _programCounter;
67                
68                 // このタイミングでいらない値は破棄しておこう...
69                 delete _byteCode[0];
70                
71                 return false;
72         }
73        
74         private function executeFunction (thisObject:Object, args:Array, entryPoint:Number, scope:Object) : Object
75         {
76                 var _thisObject:Object = this.thisObject;
77                 var _localObject:Object = localObject;
78                 var _programCounter:Number = programCounter;
79                
80                 this.thisObject = thisObject;
81                 localObject = {arguments: args, __scope:scope};
82                 programCounter = entryPoint;
83                
84                 while (execute()) {}
85                
86                 programCounter = _programCounter;
87                 localObject = _localObject;
88                 this.thisObject = _thisObject;
89                
90                 return returnValue;
91         }
92        
93         private function __resolve (name:String) : Number
94         {
95                 throw new Error('VirtualMachine [UnknwonOperation] : '+name+' at pc'+arguments[1]);
96                 return 0;
97         }
98         //
99         //nop
100         //(no operation)
101         //何もしない
102         private function NOP (code:Array, pc:Number) : Number
103         {
104                 return pc+1;
105         }
106         //
107         //spd
108         //(suspend)
109         //処理を中断する
110         private function SPD (code:Array, pc:Number) : Number
111         {
112                 return null;
113         }
114         //
115         //lit v %
116         //(literal)
117         //リテラルvを%に代入
118         private function LIT (code:Array, pc:Number) : Number
119         {
120                 code[code[pc+2]] = code[pc+1];
121                
122                 return pc+3;
123         }
124         //
125         //call id n %
126         //(call function)
127         //関数idをn個の引数で呼び出して結果を%に代入
128         private function CALL (code:Array, pc:Number) : Number
129         {
130                 var id:String = code[pc+1];
131                
132                 var func:Object = null;
133                
134                 for (var o:Object = localObject; o != null; o = o.__scope) {
135                         if (o.hasOwnProperty(id)) {
136                                 func = o[id];
137                                 break;
138                         }
139                 }
140                
141                 var numOfArguments:Number = code[pc+2] + 1;
142                 var _stack:Array = stack;
143                 var args:Array = [];
144                 while (--numOfArguments) {
145                         args.push(_stack.pop());
146                 }
147                 args.reverse();
148                
149                 if (func.__entryPoint !== undefined) {
150                         _stack.push(pc+4);
151                         _stack.push(thisObject);
152                         _stack.push(localObject);
153                         _stack.push(code[pc+3]);
154                        
155                         thisObject = global;
156                         localObject = {arguments: args, __scope: func.__scope};
157                        
158                         return func.__entryPoint;
159                 }
160                
161                 code[code[pc+3]] = func.apply(global, args);
162                 return pc+4;
163         }
164         //
165         //calll id n %
166         //(call local function)
167         //関数idをn個の引数で呼び出して結果を%に代入
168         private function CALLL (code:Array, pc:Number) : Number
169         {
170                 var func:Object = localObject[code[pc+1]];
171                
172                 var numOfArguments:Number = code[pc+2] + 1;
173                 var _stack:Array = stack;
174                 var args:Array = [];
175                 while (--numOfArguments) {
176                         args.push(_stack.pop());
177                 }
178                 args.reverse();
179                
180                 if (func.__entryPoint !== undefined) {
181                         _stack.push(pc+4);
182                         _stack.push(thisObject);
183                         _stack.push(localObject);
184                         _stack.push(code[pc+3]);
185                        
186                         thisObject = global;
187                         localObject = {arguments: args, __scope: func.__scope};
188                        
189                         return func.__entryPoint;
190                 }
191                
192                 code[code[pc+3]] = func.apply(global, args);
193                 return pc+4;
194         }
195         //
196         //callm o id n %
197         //(call member function)
198         //関数v.idをn個の引数で呼び出して結果を%に代入
199         private function CALLM (code:Array, pc:Number) : Number
200         {
201                 var o:Object = code[pc+1];
202                
203                 var func:Object = o[code[pc+2]];
204                
205                 var numOfArguments:Number = code[pc+3] + 1;
206                 var _stack:Array = stack;
207                 var args:Array = [];
208                 while (--numOfArguments) {
209                         args.push(_stack.pop());
210                 }
211                 args.reverse();
212                
213                 if (func.__entryPoint !== undefined) {
214                         _stack.push(pc+5);
215                         _stack.push(thisObject);
216                         _stack.push(localObject);
217                         _stack.push(code[pc+4]);
218                        
219                         thisObject = o;
220                         localObject = {arguments: args, __scope: func.__scope};
221                        
222                         return func.__entryPoint;
223                 }
224                
225                 code[code[pc+4]] = func.apply(o, args);
226                 return pc+5;
227         }
228         //
229         //callf o n %
230         //(call functor)
231         //関数オブジェクトoをn個の引数で呼び出して結果を%に代入
232         private function CALLF (code:Array, pc:Number) : Number
233         {
234                 var func:Object = code[pc+1];
235                
236                 var numOfArguments:Number = code[pc+2] + 1;
237                 var _stack:Array = stack;
238                 var args:Array = [];
239                 while (--numOfArguments) {
240                         args.push(_stack.pop());
241                 }
242                 args.reverse();
243                
244                 if (func.__entryPoint !== undefined) {
245                         _stack.push(pc+4);
246                         _stack.push(thisObject);
247                         _stack.push(localObject);
248                         _stack.push(code[pc+3]);
249                        
250                         thisObject = global;
251                         localObject = {arguments: args, __scope: func.__scope};
252                        
253                         return func.__entryPoint;
254                 }
255                
256                 code[code[pc+3]] = func.apply(global, args);
257                 return pc+4;
258         }
259         //
260         //ret v
261         //(return function)
262         //戻り値vで関数の呼び出し元に戻る
263         private function RET (code:Array, pc:Number) : Number
264         {
265                 returnValue = code[pc+1];
266                
267                 return byteCodeLength;
268         }
269         //
270         //cret v
271         //(return coroutine)
272         //戻り値vでコルーチンの呼び出し元に戻る
273         private function CRET (code:Array, pc:Number) : Number
274         {
275                 var _stack:Array = stack;
276                
277                 code[_stack.pop()] = code[pc+1];
278                
279                 localObject = _stack.pop();
280                 thisObject = _stack.pop();
281                
282                 return Number(_stack.pop());
283         }
284         //
285         //func :% %
286         //(function declare)
287         //:%までを本体とする関数オブジェクトを生成して%に代入
288         private function FUNC (code:Array, pc:Number) : Number
289         {
290                 var vm:VirtualMachine = this;
291                 var entryPoint:Number = pc + 3;
292                 var scope:Object = localObject;
293                 code[code[pc+2]] = function ()
294                 {
295                         return vm.executeFunction(this, arguments, entryPoint, scope);
296                 };
297                 return code[pc+1];
298         }
299         //
300         //cor :% %
301         //(coroutine declare)
302         //:%までを本体とするコルーチンを生成して%に代入
303         private function COR (code:Array, pc:Number) : Number
304         {
305                 code[code[pc+2]] = {__entryPoint:pc+3, __scope:localObject};
306                 return code[pc+1];
307         }
308         //
309         //arg n id
310         //(get argument)
311         //n番目の引数を変数idに代入
312         private function ARG (code:Array, pc:Number) : Number
313         {
314                 localObject[code[pc+2]] = localObject.arguments[code[pc+1]];
315                
316                 return pc+3;
317         }
318         //
319         //jmp :%
320         //(jump)
321         //:%に飛ぶ
322         private function JMP (code:Array, pc:Number) : Number
323         {
324                 return code[pc+1];
325         }
326         //
327         //if v :%
328         //(jump if)
329         //vが真で「なければ」:%に飛ぶ(真であれば次のコードが実行される)
330         private function IF (code:Array, pc:Number) : Number
331         {
332                 if (code[pc+1]) {
333                         return pc+3;
334                 }
335                 return code[pc+2];
336         }
337         //
338         //nif v :%
339         //(jump if not)
340         //vが偽で「なければ」:%に飛ぶ(偽であれば次のコードが実行される)
341         private function NIF (code:Array, pc:Number) : Number
342         {
343                 if (code[pc+1]) {
344                         return code[pc+2];
345                 }
346                 return pc+3;
347         }
348         //
349         //add v1 v2 %
350         //(add)
351         //v1+v2を%に代入
352         private function ADD (code:Array, pc:Number) : Number
353         {
354                 code[code[pc+3]] = code[pc+1] + code[pc+2];
355                 return pc+4;
356         }
357         //
358         //sub v1 v2 %
359         //(subtract)
360         //v1-v2を%に代入
361         private function SUB (code:Array, pc:Number) : Number
362         {
363                 code[code[pc+3]] = code[pc+1] - code[pc+2];
364                 return pc+4;
365         }
366         //
367         //mul v1 v2 %
368         //(multiply)
369         //v1*v2を%に代入
370         private function MUL (code:Array, pc:Number) : Number
371         {
372                 code[code[pc+3]] = code[pc+1] * code[pc+2];
373                 return pc+4;
374         }
375         //
376         //div v1 v2 %
377         //(divide)
378         //v1/v2を%に代入
379         private function DIV (code:Array, pc:Number) : Number
380         {
381                 code[code[pc+3]] = code[pc+1] / code[pc+2];
382                 return pc+4;
383         }
384         //
385         //mod v1 v2 %
386         //(modulo)
387         //v1%v2を%に代入
388         private function MOD (code:Array, pc:Number) : Number
389         {
390                 code[code[pc+3]] = code[pc+1] % code[pc+2];
391                 return pc+4;
392         }
393         //
394         //and v1 v2 %
395         //(bitwise and)
396         //v1&v2を%に代入
397         private function AND (code:Array, pc:Number) : Number
398         {
399                 code[code[pc+3]] = code[pc+1] & code[pc+2];
400                 return pc+4;
401         }
402         //
403         //or v1 v2 %
404         //(bitwise or)
405         //v1|v2を%に代入
406         private function OR (code:Array, pc:Number) : Number
407         {
408                 code[code[pc+3]] = code[pc+1] | code[pc+2];
409                 return pc+4;
410         }
411         //
412         //xor v1 v2 %
413         //(bitwise xor)
414         //v1^v2を%に代入
415         private function XOR (code:Array, pc:Number) : Number
416         {
417                 code[code[pc+3]] = code[pc+1] ^ code[pc+2];
418                 return pc+4;
419         }
420         //
421         //not v %
422         //(bitwise not)
423         //~vを%に代入
424         private function NOT (code:Array, pc:Number) : Number
425         {
426                 code[code[pc+2]] = ~code[pc+1];
427                 return pc+3;
428         }
429         //
430         //lnot v %
431         //(logical not)
432         //!vを%に代入
433         private function LNOT (code:Array, pc:Number) : Number
434         {
435                 code[code[pc+2]] = !code[pc+1];
436                 return pc+3;
437         }
438         //
439         //lsh v1 v2 %
440         //(left shift)
441         //v1<<v2を%に代入
442         private function LSH (code:Array, pc:Number) : Number
443         {
444                 code[code[pc+3]] = code[pc+1] << code[pc+2];
445                 return pc+4;
446         }
447         //
448         //rsh v1 v2 %
449         //(signed right shift)
450         //v1>>v2を%に代入
451         private function RSH (code:Array, pc:Number) : Number
452         {
453                 code[code[pc+3]] = code[pc+1] >> code[pc+2];
454                 return pc+4;
455         }
456         //
457         //ursh v1 v2 %
458         //(unsigned right shift)
459         //v1>>>v2を%に代入
460         private function URSH (code:Array, pc:Number) : Number
461         {
462                 code[code[pc+3]] = code[pc+1] >>> code[pc+2];
463                 return pc+4;
464         }
465         //
466         //inc v %
467         //(increment)
468         //vを加算して%に代入
469         private function INC (code:Array, pc:Number) : Number
470         {
471                 code[code[pc+2]] = code[pc+1] + 1;
472                 return pc+3;
473         }
474         //
475         //dec v %
476         //(decrement)
477         //vを減算して%に代入
478         private function DEC (code:Array, pc:Number) : Number
479         {
480                 code[code[pc+2]] = code[pc+1] - 1;
481                 return pc+3;
482         }
483         //
484         //ceq v1 v2 %
485         //(compare equal)
486         //v1==v2の結果を%に代入
487         private function CEQ (code:Array, pc:Number) : Number
488         {
489                 code[code[pc+3]] = code[pc+1] == code[pc+2];
490                 return pc+4;
491         }
492         //
493         //cseq v1 v2 %
494         //(compare strict equal)
495         //v1===v2の結果を%に代入
496         private function CSEQ (code:Array, pc:Number) : Number
497         {
498                 code[code[pc+3]] = code[pc+1] === code[pc+2];
499                 return pc+4;
500         }
501         //
502         //cne v1 v2 %
503         //(compare not equal)
504         //v1!=v2の結果を%に代入
505         private function CNE (code:Array, pc:Number) : Number
506         {
507                 code[code[pc+3]] = code[pc+1] != code[pc+2];
508                 return pc+4;
509         }
510         //
511         //csne v1 v2 %
512         //(compare not strict equal)
513         //v1!==v2の結果を%に代入
514         private function CSNE (code:Array, pc:Number) : Number
515         {
516                 code[code[pc+3]] = code[pc+1] !== code[pc+2];
517                 return pc+4;
518         }
519         //
520         //clt v1 v2 %
521         //(compare less than)
522         //v1<v2の結果を%に代入
523         private function CLT (code:Array, pc:Number) : Number
524         {
525                 code[code[pc+3]] = code[pc+1] < code[pc+2];
526                 return pc+4;
527         }
528         //
529         //cgt v1 v2 %
530         //(compare greater than)
531         //v1>v2の結果を%に代入
532         private function CGT (code:Array, pc:Number) : Number
533         {
534                 code[code[pc+3]] = code[pc+1] > code[pc+2];
535                 return pc+4;
536         }
537         //
538         //cle v1 v2 %
539         //(compare less than or equal)
540         //v1<=v2の結果を%に代入
541         private function CLE (code:Array, pc:Number) : Number
542         {
543                 code[code[pc+3]] = code[pc+1] <= code[pc+2];
544                 return pc+4;
545         }
546         //
547         //cge v1 v2 %
548         //(compare greater than or equal)
549         //v1>=v2の結果を%に代入
550         private function CGE (code:Array, pc:Number) : Number
551         {
552                 code[code[pc+3]] = code[pc+1] >= code[pc+2];
553                 return pc+4;
554         }
555         //
556         //dup v %1 %2
557         //(duplicate)
558         //%1と%2にvを代入
559         private function DUP (code:Array, pc:Number) : Number
560         {
561                 var value:Object = code[pc+1];
562                 code[code[pc+2]] = value;
563                 code[code[pc+3]] = value;
564                 return pc+4;
565         }
566         //
567         //this %
568         //(this)
569         //thisを%に代入
570         private function THIS (code:Array, pc:Number) : Number
571         {
572                 code[code[pc+1]] = thisObject;
573                 return pc+2;
574         }
575         //
576         //array n %
577         //(initialize array)
578         //n個の要素を持つ配列を生成して%に代入
579         private function ARRAY (code:Array, pc:Number) : Number
580         {
581                 var elements:Number = code[pc+1];
582                 var instance:Array = new Array(elements);
583                 var _stack:Array = stack;
584                 for (var i:Number=0; i<elements; ++i) {
585                         instance[i] = _stack.pop();
586                 }
587                 instance.reverse();
588                 code[code[pc+2]] = instance;
589                 return pc+3;
590         }
591         //
592         //obj n %
593         //(initialize object)
594         //n個のキーと値のペアを持つオブジェクトを生成して%に代入
595         private function OBJ (code:Array, pc:Number) : Number
596         {
597                 var properties:Number = code[pc+1];
598                 var instance:Object = new Object();
599                 var _stack:Array = stack;
600                 for (var i:Number=0; i<properties; ++i) {
601                         var value:Object = _stack.pop();
602                         instance[_stack.pop()] = value;
603                 }
604                 code[code[pc+2]] = instance;
605                 return pc+3;
606         }
607         //
608         //setl id v %
609         //(set local variable)
610         //現在の実行コンテキスト上の変数idにvを代入(変数idが存在しなければ生成; スコープチェーンは見ない)
611         private function SETL (code:Array, pc:Number) : Number
612         {
613                 localObject[code[pc+1]] = code[code[pc+3]] = code[pc+2];
614                 return pc+4;
615         }
616         //
617         //getl id %
618         //(get local variable)
619         //現在の実行コンテキスト上の変数idを探して%に代入(スコープチェーンは見ない)
620         private function GETL (code:Array, pc:Number) : Number
621         {
622                 code[code[pc+2]] = localObject[code[pc+1]];
623                 return pc+3;
624         }
625         //
626         //set id v %
627         //(set variable)
628         //現在の実行コンテキストを基点とするスコープチェーンから変数idを探してvを代入
629         private function SET (code:Array, pc:Number) : Number
630         {
631                 var id:String = code[pc+1];
632                 for (var o:Object = localObject; o != null; o = o.__scope) {
633                         if (o.hasOwnProperty(id)) {
634                                 o[id] = code[code[pc+3]] = code[pc+2];
635                                 return pc+4;
636                         }
637                 }
638                 global[id] = code[code[pc+3]] = code[pc+2];
639                 return pc+4;
640         }
641         //
642         //get id %
643         //(get variable)
644         //現在の実行コンテキストを基点とするスコープチェーンから変数idを探して%に代入
645         private function GET (code:Array, pc:Number) : Number
646         {
647                 var id:String = code[pc+1];
648                 for (var o:Object = localObject; o != null; o = o.__scope) {
649                         if (o.hasOwnProperty(id)) {
650                                 code[code[pc+2]] = o[id];
651                                 return pc+3;
652                         }
653                 }
654                 code[code[pc+2]] = undefined;
655                 return pc+3;
656         }
657         //
658         //setm o id v %
659         //(set member)
660         //o.idにvを代入
661         private function SETM (code:Array, pc:Number) : Number
662         {
663                 code[pc+1][code[pc+2]] = code[code[pc+4]] = code[pc+3];
664                 return pc+5;
665         }
666         //
667         //getm o id %
668         //(get member)
669         //o.idを%に代入
670         private function GETM (code:Array, pc:Number) : Number
671         {
672                 code[code[pc+3]] = code[pc+1][code[pc+2]];
673                 return pc+4;
674         }
675         //
676         //new v n %
677         //(new instance)
678         //クラスvをn個の引数で生成して%に代入
679         private function NEW (code:Array, pc:Number) : Number
680         {
681                 var constructor:Function = code[pc+1];
682                 _constructor.prototype = constructor.prototype;
683                 var instance:Object = new _constructor();
684                 var argLen:Number = code[pc+2]+1;
685                 var _stack:Array = stack;
686                 var args:Array = [];
687                 while (--argLen) {
688                         args.push(_stack.pop());
689                 }
690                 code[code[pc+3]] = constructor.apply(instance, args) || instance;
691                 return pc+4;
692         }
693         private function _constructor () : Void
694         {
695         }
696         //
697         //del id %
698         //(delete)
699         //変数idを削除し、その成否を%に代入
700         private function DEL (code:Array, pc:Number) : Number
701         {
702                 var id:String = code[pc+1];
703                 for (var o:Object = localObject; o != null; o = o.__scope) {
704                         if (o.hasOwnProperty(id)) {
705                                 code[code[pc+2]] = delete o[id];
706                                 return pc+3;
707                         }
708                 }
709                 code[code[pc+2]] = false;
710                 return pc+3;
711         }
712         //
713         //dell id %
714         //(delete local)
715         //変数idを削除し、その成否を%に代入
716         private function DELL (code:Array, pc:Number) : Number
717         {
718                 code[code[pc+2]] = delete localObject[code[pc+1]];
719                 return pc+3;
720         }
721         //
722         //delm o id %
723         //(delete member)
724         //o.idを削除し、その成否を%に代入
725         private function DELM (code:Array, pc:Number) : Number
726         {
727                 code[code[pc+3]] = delete code[pc+1][code[pc+2]];
728                 return pc+4;
729         }
730         //
731         //typeof v %
732         //(typeof)
733         //typeof vの結果を%に代入
734         private function TYPEOF (code:Array, pc:Number) : Number
735         {
736                 code[code[pc+2]] = typeof code[pc+1];
737                 return pc+3;
738         }
739         //
740         //insof v1 v2 %
741         //(instanceof)
742         //v1 instanceof v2の結果を%に代入
743         private function INSOF (code:Array, pc:Number) : Number
744         {
745                 code[code[pc+3]] = code[pc+1] instanceof code[pc+2];
746                 return pc+4;
747         }
748         //
749         //num v %
750         //(to number)
751         //Number(v)の結果を%に代入
752         private function NUM (code:Array, pc:Number) : Number
753         {
754                 code[code[pc+2]] = Number(code[pc+1]);
755                 return pc+3;
756         }
757         //
758         //str v %
759         //(to string)
760         //String(v)の結果を%に代入
761         private function STR (code:Array, pc:Number) : Number
762         {
763                 code[code[pc+2]] = String(code[pc+1]);
764                 return pc+3;
765         }
766         //
767         //with v
768         //(start with)
769         //スコープチェーンの先頭にvを追加
770         private function WITH (code:Array, pc:Number) : Number
771         {
772                 var o:Object = code[pc+1];
773                
774                 o.__scope = localObject;
775                 localObject = o;
776                
777                 return pc+2;
778         }
779         //
780         //ewith
781         //(end with)
782         //スコープチェーンから先頭のオブジェクトを取り除く
783         private function EWITH (code:Array, pc:Number) : Number
784         {
785                 localObject = localObject.__scope;
786                 return pc+1;
787         }
788         //
789         //push v
790         //(push)
791         //vをスタックに積む
792         private function PUSH (code:Array, pc:Number) : Number
793         {
794                 stack.push(code[pc+1]);
795                 return pc+2;
796         }
797         //
798         //pop %
799         //(pop)
800         //スタックから値を取り出し%に代入
801         private function POP (code:Array, pc:Number) : Number
802         {
803                 code[code[pc+1]] = stack.pop();
804                 return pc+2;
805         }
806        
807         /* FECMAScriptɂN[W̊TO
808        
809         eFunctiońA`ꂽꏊɂXR[v`F[A
810         vpeBƂρB
811        
812         j
813         globalɒ`ꂽ֐f́AglobalXR[v`F[ɎB
814         f().__proto__ == global
815         fɒ`ꂽ֐ǵAfActivationObjectXR[v`F[ɎB
816         g().__proto__ == ActivationObject(f)
817         ActivationObject(f).__proto__ = f().__proto__
818        
819         eFunctionJnƂAActivationObjecti[Jϐ
820         i[̈̂悤Ȃ́jÃXR[v`F[͊֐̂
821         ƒXR[v`F[ɐݒ肳B
822        
823         ɂA
824        
825         ///////////////////////////////////////
826         var a:Number = 1;
827        
828         function f (g:Function) : Void
829         {
830                 var b:Number = 1;
831                 a = g(b);
832         }
833        
834         f(function(n:Number) : Number
835         {
836                 return a + n;
837         });
838         ///////////////////////////////////////
839        
840         ƂR[h́A֐fA֐igjɃO[o̕ϐa
841         ANZXł̂łB
842        
843         ֐fϐQƂƂA
844         ActivationObject(f) (-> ActivationObject(f).__proto__ -> f().__proto__) -> global
845         ƂŎQƂA֐ϐaQƂƂl̎菇ōsB
846        
847         ֐ϐQƂƂA
848         ActivationObject() (-> ActivationObject().__proto__ -> ().__proto__) -> global
849         ƂŎQƂ邽߁A֐f̕ϐbɂ̓ANZXłȂB
850        
851         ϐbActivationObject(f)ɍ쐬B
852        
853         */
854 }
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。