File Coverage

blib/lib/WAP/wmls/gen.pm
Criterion Covered Total %
statement 291 1170 24.8
branch 0 460 0.0
condition 0 57 0.0
subroutine 97 194 50.0
pod 0 3 0.0
total 388 1884 20.5


line stmt bran cond sub pod time code
1 1     1   7 use strict;
  1         1  
  1         47  
2 1     1   6 use warnings;
  1         2  
  1         102  
3            
4             package WAP::wmls::multibyte;
5            
6             sub size {
7 0     0     my ($value) = @_;
8 0           my $size;
9 0           for ($size = 1; $value >= 0x80; $value >>= 7) {
10 0           $size ++;
11             }
12 0           return $size;
13             }
14            
15             ###############################################################################
16            
17             package WAP::wmls::asm;
18            
19 1     1   5860 use Encode;
  1         22566  
  1         124  
20            
21 1     1   12 use constant INTEGER_8 => 0;
  1         2  
  1         75  
22 1     1   5 use constant INTEGER_16 => 1;
  1         2  
  1         348  
23 1     1   8 use constant INTEGER_32 => 2;
  1         2  
  1         145  
24 1     1   7 use constant FLOAT_32 => 3;
  1         2  
  1         47  
25 1     1   6 use constant UTF8_STRING => 4;
  1         3  
  1         44  
26 1     1   5 use constant EMPTY_STRING => 5;
  1         4  
  1         46  
27 1     1   5 use constant STRING => 6;
  1         4  
  1         6039  
28            
29             our ($OUT, $VERBOSE);
30            
31             sub _put_mb {
32 0     0     my ($value) = @_;
33 0           my $tmp = chr($value & 0x7f);
34 0           for ($value >>= 7; $value != 0; $value >>= 7) {
35 0           $tmp = chr(0x80 | ($value & 0x7f)) . $tmp;
36             }
37 0           print $OUT $tmp;
38 0           return;
39             }
40            
41             sub _put_uint8 {
42 0     0     my ($value) = @_;
43 0           print $OUT chr $value;
44 0           return;
45             }
46            
47             sub _put_int8 {
48 0     0     my ($value) = @_;
49 0           print $OUT pack 'c', $value;
50 0           return;
51             }
52            
53             sub _put_uint16 {
54 0     0     my ($value) = @_;
55 0           print $OUT pack 'n', $value;
56 0           return;
57             }
58            
59             sub _put_int16 {
60 0     0     my ($value) = @_;
61 0           print $OUT pack 'n', unpack 'v', pack 's', $value;
62 0           return;
63             }
64            
65             sub _put_int32 {
66 0     0     my ($value) = @_;
67 0           print $OUT pack 'N', unpack 'V', pack 'l', $value;
68 0           return;
69             }
70            
71             sub _put_float32 {
72 0     0     my ($value) = @_;
73 0           print $OUT pack 'f', $value;
74 0           return;
75             }
76            
77             sub _put_string {
78 0     0     my ($value) = @_;
79 0           print $OUT $value;
80 0           return;
81             }
82            
83             my @mnemo = (
84             '?',
85             'JUMP_FW',
86             'JUMP_FW_W',
87             'JUMP_BW',
88             'JUMP_BW_W',
89             'TJUMP_FW',
90             'TJUMP_FW_W',
91             'TJUMP_BW',
92             'TJUMP_BW_W',
93             'CALL',
94             'CALL_LIB',
95             'CALL_LIB_W',
96             'CALL_URL',
97             'CALL_URL_W',
98             'LOAD_VAR',
99             'STORE_VAR',
100             'INCR_VAR',
101             'DECR_VAR',
102             'LOAD_CONST',
103             'LOAD_CONST_W',
104             'CONST_0',
105             'CONST_1',
106             'CONST_M1',
107             'CONST_ES',
108             'CONST_INVALID',
109             'CONST_TRUE',
110             'CONST_FALSE',
111             'INCR',
112             'DECR',
113             'ADD_ASG',
114             'SUB_ASG',
115             'UMINUS',
116             'ADD',
117             'SUB',
118             'MUL',
119             'DIV',
120             'IDIV',
121             'REM',
122             'B_AND',
123             'B_OR',
124             'B_XOR',
125             'B_NOT',
126             'B_LSHIFT',
127             'B_RSSHIFT',
128             'B_RSZSHIFT',
129             'EQ',
130             'LE',
131             'LT',
132             'GE',
133             'GT',
134             'NE',
135             'NOT',
136             'SCAND',
137             'SCOR',
138             'TOBOOL',
139             'POP',
140             'TYPEOF',
141             'ISVALID',
142             'RETURN',
143             'RETURN_ES',
144             'DEBUG',
145             '?',
146             '?',
147             '?',
148             'STORE_VAR_S',
149             '?',
150             '?',
151             '?',
152             '?',
153             '?',
154             '?',
155             '?',
156             '?',
157             '?',
158             '?',
159             '?',
160             '?',
161             '?',
162             '?',
163             '?',
164             'LOAD_CONST_S',
165             '?',
166             '?',
167             '?',
168             '?',
169             '?',
170             '?',
171             '?',
172             '?',
173             '?',
174             '?',
175             '?',
176             '?',
177             '?',
178             '?',
179             '?',
180             'CALL_S',
181             '?',
182             '?',
183             '?',
184             '?',
185             '?',
186             '?',
187             '?',
188             'CALL_LIB_S',
189             '?',
190             '?',
191             '?',
192             '?',
193             '?',
194             '?',
195             '?',
196             'INCR_VAR_S',
197             '?',
198             '?',
199             '?',
200             '?',
201             '?',
202             '?',
203             '?',
204             '?',
205             '?',
206             '?',
207             '?',
208             '?',
209             '?',
210             '?',
211             '?',
212             'JUMP_FW_S',
213             '?',
214             '?',
215             '?',
216             '?',
217             '?',
218             '?',
219             '?',
220             '?',
221             '?',
222             '?',
223             '?',
224             '?',
225             '?',
226             '?',
227             '?',
228             '?',
229             '?',
230             '?',
231             '?',
232             '?',
233             '?',
234             '?',
235             '?',
236             '?',
237             '?',
238             '?',
239             '?',
240             '?',
241             '?',
242             '?',
243             '?',
244             'JUMP_BW_S',
245             '?',
246             '?',
247             '?',
248             '?',
249             '?',
250             '?',
251             '?',
252             '?',
253             '?',
254             '?',
255             '?',
256             '?',
257             '?',
258             '?',
259             '?',
260             '?',
261             '?',
262             '?',
263             '?',
264             '?',
265             '?',
266             '?',
267             '?',
268             '?',
269             '?',
270             '?',
271             '?',
272             '?',
273             '?',
274             '?',
275             '?',
276             'TJUMP_FW_S',
277             '?',
278             '?',
279             '?',
280             '?',
281             '?',
282             '?',
283             '?',
284             '?',
285             '?',
286             '?',
287             '?',
288             '?',
289             '?',
290             '?',
291             '?',
292             '?',
293             '?',
294             '?',
295             '?',
296             '?',
297             '?',
298             '?',
299             '?',
300             '?',
301             '?',
302             '?',
303             '?',
304             '?',
305             '?',
306             '?',
307             '?',
308             'LOAD_VAR_S',
309             '?',
310             '?',
311             '?',
312             '?',
313             '?',
314             '?',
315             '?',
316             '?',
317             '?',
318             '?',
319             '?',
320             '?',
321             '?',
322             '?',
323             '?',
324             '?',
325             '?',
326             '?',
327             '?',
328             '?',
329             '?',
330             '?',
331             '?',
332             '?',
333             '?',
334             '?',
335             '?',
336             '?',
337             '?',
338             '?',
339             '?',
340             );
341            
342             sub asmOpcode1 {
343 0     0     my ($bytecode) = @_;
344 0 0         print $VERBOSE sprintf("%-14s\t", $mnemo[$bytecode])
345             if (defined $VERBOSE);
346 0           _put_uint8($bytecode);
347 0           return;
348             }
349            
350             sub asmOpcode1s {
351 0     0     my ($bytecode, $offset) = @_;
352 0 0         print $VERBOSE sprintf("%-14s%7u\t", $mnemo[$bytecode], $offset)
353             if (defined $VERBOSE);
354 0           _put_uint8(($bytecode | $offset));
355 0           return;
356             }
357            
358             sub asmOpcode2 {
359 0     0     my ($bytecode, $offset) = @_;
360             # LOAD_CONST
361 0 0         print $VERBOSE sprintf("%-14s%7u\t", $mnemo[$bytecode], $offset)
362             if (defined $VERBOSE);
363 0           _put_uint8($bytecode);
364 0           _put_uint8($offset);
365 0           return;
366             }
367            
368             sub asmOpcode2s {
369 0     0     my ($bytecode, $idx1, $idx2) = @_;
370             # CALL_LIB_S
371 0 0         print $VERBOSE sprintf("%-14s%7u%7u\t", $mnemo[$bytecode], $idx1, $idx2)
372             if (defined $VERBOSE);
373 0           _put_uint8($bytecode | $idx1);
374 0           _put_uint8($idx2);
375 0           return;
376             }
377            
378             sub asmOpcode3 {
379 0     0     my ($bytecode, $idx1, $idx2) = @_;
380             # CALL_LIB
381 0 0         print $VERBOSE sprintf("%-14s%7u%7u\t", $mnemo[$bytecode], $idx1, $idx2)
382             if (defined $VERBOSE);
383 0           _put_uint8($bytecode);
384 0           _put_uint8($idx1);
385 0           _put_uint8($idx2);
386 0           return;
387             }
388            
389             sub asmOpcode3w {
390 0     0     my ($bytecode, $offset) = @_;
391             # LOAD_CONST_W, JUMP_xW_W
392 0 0         print $VERBOSE sprintf("%-14s%7u\t", $mnemo[$bytecode], $offset)
393             if (defined $VERBOSE);
394 0           _put_uint8($bytecode);
395 0           _put_uint16($offset);
396 0           return;
397             }
398            
399             sub asmOpcode4 {
400 0     0     my ($bytecode, $idx1, $idx2, $idx3) = @_;
401             # CALL_URL
402 0 0         print $VERBOSE sprintf("%-14s%7u%7u%7u\t", $mnemo[$bytecode], $idx1, $idx2, $idx3)
403             if (defined $VERBOSE);
404 0           _put_uint8($bytecode);
405 0           _put_uint8($idx1);
406 0           _put_uint8($idx2);
407 0           _put_uint8($idx3);
408 0           return;
409             }
410            
411             sub asmOpcode4w {
412 0     0     my ($bytecode, $idx1, $idx2) = @_;
413             # CALL_LIB_W
414 0 0         print $VERBOSE sprintf("%-14s%7u%7u\t", $mnemo[$bytecode], $idx1, $idx2)
415             if (defined $VERBOSE);
416 0           _put_uint8($bytecode);
417 0           _put_uint8($idx1);
418 0           _put_uint16($idx2);
419 0           return;
420             }
421            
422             sub asmOpcode6 {
423 0     0     my ($bytecode, $idx1, $idx2, $idx3) = @_;
424             # CALL_URL_W
425 0 0         print $VERBOSE sprintf("%-14s%7u%7u%7u\t", $mnemo[$bytecode], $idx1, $idx2, $idx3)
426             if (defined $VERBOSE);
427 0           _put_uint8($bytecode);
428 0           _put_uint16($idx1);
429 0           _put_uint16($idx2);
430 0           _put_uint8($idx3);
431 0           return;
432             }
433            
434             sub asmByte {
435 0     0     my ($str, $value) = @_;
436 0 0         print $VERBOSE "$str $value\n"
437             if (defined $VERBOSE);
438 0           _put_uint8($value);
439 0           return;
440             }
441            
442             sub asmMultiByte {
443 0     0     my ($str, $value) = @_;
444 0 0         print $VERBOSE "$str $value\n"
445             if (defined $VERBOSE);
446 0           _put_mb($value);
447 0           return;
448             }
449            
450             sub asmFunctionName {
451 0     0     my ($idx, $name) = @_;
452 0           my $len = length $name;
453 0 0         print $VERBOSE "$idx\t[$len]\t$name\n"
454             if (defined $VERBOSE);
455 0           _put_uint8($idx);
456 0           _put_uint8($len);
457 0           _put_string($name);
458 0           return;
459             }
460            
461             sub asmPragma1 {
462 0     0     my ($type, $value1) = @_;
463 0 0         print $VERBOSE sprintf("prag%7u%7u\n", $type, $value1)
464             if (defined $VERBOSE);
465 0           _put_uint8($type);
466 0           _put_mb($value1);
467 0           return;
468             }
469            
470             sub asmPragma2 {
471 0     0     my ($type, $value1, $value2) = @_;
472 0 0         print $VERBOSE sprintf("prag%7u%7u%7u\n", $type, $value1, $value2)
473             if (defined $VERBOSE);
474 0           _put_uint8($type);
475 0           _put_mb($value1);
476 0           _put_mb($value2);
477 0           return;
478             }
479            
480             sub asmPragma3 {
481 0     0     my ($type, $value1, $value2, $value3) = @_;
482 0 0         print $VERBOSE sprintf("prag%7u%7u%7u%7u\n", $type, $value1, $value2, $value3)
483             if (defined $VERBOSE);
484 0           _put_uint8($type);
485 0           _put_mb($value1);
486 0           _put_mb($value2);
487 0           _put_mb($value3);
488 0           return;
489             }
490            
491             sub asmConstantInteger8 {
492 0     0     my ($idx, $value) = @_;
493 0 0         print $VERBOSE sprintf("cst%-7u%7u%7d\n", $idx, INTEGER_8, $value)
494             if (defined $VERBOSE);
495 0           _put_uint8(INTEGER_8);
496 0           _put_int8($value);
497 0           return;
498             }
499            
500             sub asmConstantInteger16 {
501 0     0     my ($idx, $value) = @_;
502 0 0         print $VERBOSE sprintf("cst%-7u%7u%7d\n", $idx, INTEGER_16, $value)
503             if (defined $VERBOSE);
504 0           _put_uint8(INTEGER_16);
505 0           _put_int16($value);
506 0           return;
507             }
508            
509             sub asmConstantInteger32 {
510 0     0     my ($idx, $value) = @_;
511 0 0         print $VERBOSE sprintf("cst%-7u%7u%7d\n", $idx, INTEGER_32, $value)
512             if (defined $VERBOSE);
513 0           _put_uint8(INTEGER_32);
514 0           _put_int32($value);
515 0           return;
516             }
517            
518             sub asmConstantFloat32 {
519 0     0     my ($idx, $value) = @_;
520 0 0         print $VERBOSE sprintf("cst%-7u%7u %f\n", $idx, FLOAT_32, $value)
521             if (defined $VERBOSE);
522 0           _put_uint8(FLOAT_32);
523 0           _put_float32($value);
524 0           return;
525             }
526            
527             sub asmConstantStringUTF8 {
528 0     0     my ($idx, $value) = @_;
529 0           my $octets = encode('utf8', $value);
530 0           my $len = length $octets;
531 0 0         print $VERBOSE sprintf("cst%-7u%7u\t[%u]\t%s\n", $idx, UTF8_STRING, $len, $value)
532             if (defined $VERBOSE);
533 0           _put_uint8(UTF8_STRING);
534 0           _put_mb($len);
535 0           _put_string($octets);
536 0           return;
537             }
538            
539             sub asmConstantString {
540 0     0     my ($idx, $value) = @_;
541 0           my $len = length $value;
542 0 0         print $VERBOSE sprintf("cst%-7u%7u\t[%u]\t%s\n", $idx, STRING, $len, $value)
543             if (defined $VERBOSE);
544 0           _put_uint8(STRING);
545 0           _put_mb($len);
546 0           _put_string($value);
547 0           return;
548             }
549            
550             sub asmComment {
551 0     0     my ($comment) = @_;
552 0 0         if (defined $comment) {
553 0 0         print $VERBOSE "; $comment\n"
554             if (defined $VERBOSE);
555             }
556             else {
557 0 0         print $VERBOSE "\n"
558             if (defined $VERBOSE);
559             }
560 0           return;
561             }
562            
563             ###############################################################################
564            
565             package WAP::wmls::verbose;
566            
567             my $_Lineno = 0;
568             my $IN;
569            
570             sub Init {
571 0     0     my ($filename) = @_;
572 0 0         open $IN, '<', $filename
573             or die "can't open $filename ($!).\n";
574 0           return;
575             }
576            
577             sub Source {
578 0     0     my ($opcode) = @_;
579 0 0         if (defined $WAP::wmls::asm::VERBOSE) {
580 0           my $lineno = $opcode->{Lineno};
581 0           while ($lineno > $_Lineno) {
582 0           my $line = <$IN>;
583 0           print $WAP::wmls::asm::VERBOSE sprintf(";line:%5d;\t", $_Lineno + 1);
584 0 0         print $WAP::wmls::asm::VERBOSE $line if ($line);
585 0           $_Lineno ++;
586             }
587             }
588 0           return;
589             }
590            
591             sub End {
592 0     0     close $IN;
593 0           return;
594             }
595            
596             ###############################################################################
597            
598             package WAP::wmls::constantVisitor;
599            
600 1     1   15 use Carp;
  1         2  
  1         90  
601            
602 1     1   7 use Encode;
  1         2  
  1         346  
603            
604 1     1   8 use constant INT8_MIN => -128;
  1         2  
  1         1870  
605 1     1   15 use constant INT8_MAX => 127;
  1         2  
  1         51  
606 1     1   5 use constant INT16_MIN => -32768;
  1         2  
  1         226  
607 1     1   6 use constant INT16_MAX => 32767;
  1         2  
  1         1923  
608            
609             sub new {
610 0     0     my $proto = shift;
611 0   0       my $class = ref($proto) || $proto;
612 0           my $self = {};
613 0           bless($self, $class);
614 0           my ($parser) = @_;
615 0           $self->{parser} = $parser;
616 0           $self->{nb} = 0;
617 0           $self->{size} = 0;
618 0           $self->{action} = 0;
619 0           $self->{cst} = {
620             TYPE_INTEGER => {},
621             TYPE_FLOAT => {},
622             TYPE_STRING => {},
623             TYPE_UTF8_STRING => {},
624             };
625 0           return $self;
626             }
627            
628             sub visitUrl {
629 0     0     my $self = shift;
630 0           my ($opcode) = @_;
631 0           my $def = $opcode->{Definition};
632 0 0         if ($def->{NbUse} == 0) {
633 0 0         unless ($self->{action}) {
634 0           $self->{parser}->genWarning($opcode, "Unreferenced url - $def->{Symbol}.\n");
635             }
636             }
637             else {
638 0 0         unless ($self->{action}) {
639 0           $def->{Index} = $self->{nb};
640             }
641 0           $opcode->{Value}->visit($self); # LOAD_CONST
642             }
643 0           return;
644             }
645            
646             sub visitAccessDomain {
647 0     0     my $self = shift;
648 0           my ($opcode) = @_;
649 0           $opcode->{Value}->visit($self); # LOAD_CONST
650 0           return;
651             }
652            
653             sub visitAccessPath {
654 0     0     my $self = shift;
655 0           my ($opcode) = @_;
656 0           $opcode->{Value}->visit($self); # LOAD_CONST
657 0           return;
658             }
659            
660 0     0     sub visitMetaName {}
661            
662 0     0     sub visitMetaHttpEquiv {}
663            
664             sub visitMetaUserAgent {
665 0     0     my $self = shift;
666 0           my ($opcode) = @_;
667 0           $opcode->{Value}->visit($self); # LOAD_CONST
668 0           return;
669             }
670            
671             sub visitFunction {
672 0     0     my $self = shift;
673 0           my ($opcode) = @_;
674 0 0         $opcode->{Value}->visitActive($self)
675             if (defined $opcode->{Value});
676 0           return;
677             }
678            
679 0     0     sub visitLoadVar {}
680            
681 0     0     sub visitStoreVar {}
682            
683 0     0     sub visitIncrVar {}
684            
685 0     0     sub visitDecrVar {}
686            
687 0     0     sub visitAddAsg {}
688            
689 0     0     sub visitSubAsg {}
690            
691 0     0     sub visitLabel {}
692            
693 0     0     sub visitPop {}
694            
695 0     0     sub visitToBool {}
696            
697 0     0     sub visitScOr {}
698            
699 0     0     sub visitScAnd {}
700            
701 0     0     sub visitReturn {}
702            
703 0     0     sub visitReturnES {}
704            
705 0     0     sub visitCall {}
706            
707 0     0     sub visitCallLib {}
708            
709             sub visitCallUrl {
710 0     0     my $self = shift;
711 0           my ($opcode) = @_;
712 0           my $def = $opcode->{Definition};
713 0           my $value = $def->{FunctionName};
714 0 0         unless ($self->{action}) {
715 0 0         if (exists $self->{cst}->{TYPE_UTF8_STRING}{$value}) {
716 0           $opcode->{Index} = $self->{cst}->{TYPE_UTF8_STRING}{$value};
717 0           $opcode->{Doublon} = 1;
718 0           return;
719             }
720             }
721 0 0         if ($self->{action}) {
722 0 0         WAP::wmls::asm::asmConstantString($opcode->{Index}, $value)
723             unless (exists $opcode->{Doublon});
724             }
725             else {
726 0           $opcode->{Index} = $self->{nb};
727 0           $self->{cst}->{TYPE_UTF8_STRING}{$value} = $self->{nb};
728 0           $self->{size} += 1;
729 0           $self->{size} += WAP::wmls::multibyte::size(length $value);
730 0           $self->{size} += length $value;
731 0           $self->{nb} += 1;
732             }
733 0           return;
734             }
735            
736 0     0     sub visitJump {}
737            
738 0     0     sub visitFalseJump {}
739            
740 0     0     sub visitUnaryOp {}
741            
742 0     0     sub visitBinaryOp {}
743            
744             sub visitLoadConst {
745 0     0     my $self = shift;
746 0           my ($opcode) = @_;
747 0           my $type = $opcode->{TypeDef};
748 0 0         if ($type eq 'TYPE_INTEGER') {
    0          
749 0           $self->{parser}->checkRangeInteger($opcode);
750             }
751             elsif ($type eq 'TYPE_FLOAT') {
752 0           $self->{parser}->checkRangeFloat($opcode);
753             }
754 0           $type = $opcode->{TypeDef};
755 0 0 0       if ( $type eq 'TYPE_BOOLEAN'
756             or $type eq 'TYPE_INVALID' ) {
757 0           return;
758             }
759 0           my $value = $opcode->{Value};
760 0 0         unless ($self->{action}) {
761 0 0         if (exists $self->{cst}->{$type}{$value}) {
762 0           $opcode->{Index} = $self->{cst}->{$type}{$value};
763 0           $opcode->{Doublon} = 1;
764 0           return;
765             }
766             }
767 0 0         if ($type eq 'TYPE_INTEGER') {
    0          
    0          
    0          
768 0 0 0       return if ($value >= -1 and $value <= 1);
769 0 0 0       if ($value >= INT8_MIN and $value <= INT8_MAX) {
    0 0        
770 0 0         if ($self->{action}) {
771 0 0         WAP::wmls::asm::asmConstantInteger8($opcode->{Index}, $value)
772             unless (exists $opcode->{Doublon});
773             }
774             else {
775 0           $opcode->{Index} = $self->{nb};
776 0           $self->{cst}->{TYPE_INTEGER}{$value} = $self->{nb};
777 0           $self->{size} += 2;
778 0           $self->{nb} += 1;
779             }
780             }
781             elsif ($value >= INT16_MIN and $value <= INT16_MAX) {
782 0 0         if ($self->{action}) {
783 0 0         WAP::wmls::asm::asmConstantInteger16($opcode->{Index}, $value)
784             unless (exists $opcode->{Doublon});
785             }
786             else {
787 0           $opcode->{Index} = $self->{nb};
788 0           $self->{cst}->{TYPE_INTEGER}{$value} = $self->{nb};
789 0           $self->{size} += 3;
790 0           $self->{nb} += 1;
791             }
792             }
793             else {
794 0 0         if ($self->{action}) {
795 0 0         WAP::wmls::asm::asmConstantInteger32($opcode->{Index}, $value)
796             unless (exists $opcode->{Doublon});
797             }
798             else {
799 0           $opcode->{Index} = $self->{nb};
800 0           $self->{cst}->{TYPE_INTEGER}{$value} = $self->{nb};
801 0           $self->{size} += 5;
802 0           $self->{nb} += 1;
803             }
804             }
805             }
806             elsif ($type eq 'TYPE_FLOAT') {
807 0 0         if ($self->{action}) {
808 0 0         WAP::wmls::asm::asmConstantFloat32($opcode->{Index}, $value)
809             unless (exists $opcode->{Doublon});
810             }
811             else {
812 0           $opcode->{Index} = $self->{nb};
813 0           $self->{cst}->{TYPE_FLOAT}{$value} = $self->{nb};
814 0           $self->{size} += 5;
815 0           $self->{nb} += 1;
816             }
817             }
818             elsif ($type eq 'TYPE_UTF8_STRING') {
819 0 0         return unless (length $value);
820 0 0         if ($self->{action}) {
821 0 0         WAP::wmls::asm::asmConstantStringUTF8($opcode->{Index}, $value)
822             unless (exists $opcode->{Doublon});
823             }
824             else {
825 0           my $octets = encode('utf8', $value);
826 0           $opcode->{Index} = $self->{nb};
827 0           $self->{cst}->{TYPE_UTF8_STRING}{$value} = $self->{nb};
828 0           $self->{size} += 1;
829 0           $self->{size} += WAP::wmls::multibyte::size(length $octets);
830 0           $self->{size} += length $octets;
831 0           $self->{nb} += 1;
832             }
833             }
834             elsif ($type eq 'TYPE_STRING') {
835 0 0         return unless (length $value);
836 0 0         if ($self->{action}) {
837 0 0         WAP::wmls::asm::asmConstantString($opcode->{Index}, $value)
838             unless (exists $opcode->{Doublon});
839             }
840             else {
841 0           $opcode->{Index} = $self->{nb};
842 0           $self->{cst}->{TYPE_STRING}{$value} = $self->{nb};
843 0           $self->{size} += 1;
844 0           $self->{size} += WAP::wmls::multibyte::size(length $value);
845 0           $self->{size} += length $value;
846 0           $self->{nb} += 1;
847             }
848             }
849             else {
850 0           croak "INTERNAL ERROR in constantVisitor::visitLoadConst $type $value\n";
851             }
852 0           return;
853             }
854            
855             ###############################################################################
856            
857             package WAP::wmls::pragmaVisitor;
858            
859 1     1   6 use constant ACCESS_DOMAIN => 0;
  1         3  
  1         45  
860 1     1   5 use constant ACCESS_PATH => 1;
  1         2  
  1         44  
861 1     1   53 use constant USER_AGENT_PROPERTY => 2;
  1         3  
  1         37  
862 1     1   5 use constant USER_AGENT_PROPERTY_AND_SCHEME => 3;
  1         2  
  1         769  
863            
864             sub new {
865 0     0     my $proto = shift;
866 0   0       my $class = ref($proto) || $proto;
867 0           my $self = {};
868 0           bless($self, $class);
869 0           my ($parser) = @_;
870 0           $self->{parser} = $parser;
871 0           $self->{nb} = 0;
872 0           $self->{size} = 0;
873 0           $self->{action} = 0;
874 0           return $self;
875             }
876            
877 0     0     sub visitUrl {}
878            
879             sub visitAccessDomain {
880 0     0     my $self = shift;
881 0           my ($opcode) = @_;
882 0           my $pragma = $opcode->{Value};
883 0           my $value = $pragma->{OpCode}->{Index};
884 0 0         if ($self->{action}) {
885 0           WAP::wmls::verbose::Source($opcode);
886 0           WAP::wmls::asm::asmPragma1(ACCESS_DOMAIN, $value);
887             }
888             else {
889 0           $self->{size} += 1;
890 0           $self->{size} += WAP::wmls::multibyte::size($value);
891 0           $self->{nb} += 1;
892             }
893 0           return;
894             }
895            
896             sub visitAccessPath {
897 0     0     my $self = shift;
898 0           my ($opcode) = @_;
899 0           my $pragma = $opcode->{Value};
900 0           my $value = $pragma->{OpCode}->{Index};
901 0 0         if ($self->{action}) {
902 0           WAP::wmls::verbose::Source($opcode);
903 0           WAP::wmls::asm::asmPragma1(ACCESS_PATH, $value);
904             }
905             else {
906 0           $self->{size} += 1;
907 0           $self->{size} += WAP::wmls::multibyte::size($value);
908 0           $self->{nb} += 1;
909             }
910 0           return;
911             }
912            
913 0     0     sub visitMetaName {}
914            
915 0     0     sub visitMetaHttpEquiv {}
916            
917             sub visitMetaUserAgent {
918 0     0     my $self = shift;
919 0           my ($opcode) = @_;
920 0           my $pragma1 = $opcode->{Value};
921 0           my $value1 = $pragma1->{OpCode}->{Index};
922 0           my $pragma2 = $pragma1->{Next};
923 0           my $value2 = $pragma2->{OpCode}->{Index};
924 0           my $pragma3 = $pragma2->{Next};
925 0 0         if (defined $pragma3) {
926 0           my $value3 = $pragma3->{OpCode}->{Index};
927 0 0         if ($self->{action}) {
928 0           WAP::wmls::verbose::Source($opcode);
929 0           WAP::wmls::asm::asmPragma3(USER_AGENT_PROPERTY_AND_SCHEME, $value1, $value2, $value3);
930             }
931             else {
932 0           $self->{size} += 1;
933 0           $self->{size} += WAP::wmls::multibyte::size($value1);
934 0           $self->{size} += WAP::wmls::multibyte::size($value2);
935 0           $self->{size} += WAP::wmls::multibyte::size($value3);
936 0           $self->{nb} += 1;
937             }
938             }
939             else {
940 0 0         if ($self->{action}) {
941 0           WAP::wmls::verbose::Source($opcode);
942 0           WAP::wmls::asm::asmPragma2(USER_AGENT_PROPERTY, $value1, $value2);
943             }
944             else {
945 0           $self->{size} += 1;
946 0           $self->{size} += WAP::wmls::multibyte::size($value1);
947 0           $self->{size} += WAP::wmls::multibyte::size($value2);
948 0           $self->{nb} += 1;
949             }
950             }
951 0           return;
952             }
953            
954             ###############################################################################
955            
956             package WAP::wmls::codeVisitor;
957            
958 1     1   6 use Carp;
  1         3  
  1         91  
959            
960 1     1   5 use constant JUMP_FW_S => 0x80;
  1         1  
  1         45  
961 1     1   5 use constant JUMP_FW => 0x01;
  1         2  
  1         45  
962 1     1   5 use constant JUMP_FW_W => 0x02;
  1         1  
  1         49  
963 1     1   5 use constant JUMP_BW_S => 0xA0;
  1         1  
  1         49  
964 1     1   6 use constant JUMP_BW => 0x03;
  1         1  
  1         46  
965 1     1   5 use constant JUMP_BW_W => 0x04;
  1         2  
  1         37  
966 1     1   5 use constant TJUMP_FW_S => 0xC0;
  1         9  
  1         308  
967 1     1   6 use constant TJUMP_FW => 0x05;
  1         2  
  1         42  
968 1     1   5 use constant TJUMP_FW_W => 0x06;
  1         2  
  1         47  
969 1     1   5 use constant TJUMP_BW => 0x07;
  1         2  
  1         44  
970 1     1   12 use constant TJUMP_BW_W => 0x08;
  1         1  
  1         39  
971 1     1   5 use constant CALL_S => 0x60;
  1         2  
  1         45  
972 1     1   4 use constant CALL => 0x09;
  1         2  
  1         38  
973 1     1   5 use constant CALL_LIB_S => 0x68;
  1         2  
  1         53  
974 1     1   5 use constant CALL_LIB => 0x0A;
  1         2  
  1         43  
975 1     1   4 use constant CALL_LIB_W => 0x0B;
  1         2  
  1         36  
976 1     1   5 use constant CALL_URL => 0x0C;
  1         2  
  1         42  
977 1     1   5 use constant CALL_URL_W => 0x0D;
  1         2  
  1         35  
978 1     1   5 use constant LOAD_VAR_S => 0xE0;
  1         2  
  1         44  
979 1     1   5 use constant LOAD_VAR => 0x0E;
  1         2  
  1         42  
980 1     1   5 use constant STORE_VAR_S => 0x40;
  1         1  
  1         37  
981 1     1   5 use constant STORE_VAR => 0x0F;
  1         1  
  1         136  
982 1     1   6 use constant INCR_VAR_S => 0x70;
  1         1  
  1         44  
983 1     1   5 use constant INCR_VAR => 0x10;
  1         2  
  1         44  
984 1     1   4 use constant DECR_VAR => 0x11;
  1         2  
  1         43  
985 1     1   5 use constant LOAD_CONST_S => 0x50;
  1         2  
  1         44  
986 1     1   4 use constant LOAD_CONST => 0x12;
  1         2  
  1         49  
987 1     1   4 use constant LOAD_CONST_W => 0x13;
  1         2  
  1         40  
988 1     1   5 use constant CONST_0 => 0x14;
  1         1  
  1         51  
989 1     1   5 use constant CONST_1 => 0x15;
  1         7  
  1         45  
990 1     1   5 use constant CONST_M1 => 0x16;
  1         2  
  1         36  
991 1     1   4 use constant CONST_ES => 0x17;
  1         2  
  1         48  
992 1     1   5 use constant CONST_INVALID => 0x18;
  1         1  
  1         37  
993 1     1   5 use constant CONST_TRUE => 0x19;
  1         6  
  1         37  
994 1     1   5 use constant CONST_FALSE => 0x1A;
  1         1  
  1         42  
995 1     1   4 use constant INCR => 0x1B;
  1         2  
  1         37  
996 1     1   5 use constant DECR => 0x1C;
  1         1  
  1         58  
997 1     1   5 use constant ADD_ASG => 0x1D;
  1         1  
  1         37  
998 1     1   5 use constant SUB_ASG => 0x1E;
  1         2  
  1         49  
999 1     1   5 use constant UMINUS => 0x1F;
  1         1  
  1         37  
1000 1     1   10 use constant ADD => 0x20;
  1         1  
  1         171  
1001 1     1   6 use constant SUB => 0x21;
  1         1  
  1         41  
1002 1     1   5 use constant MUL => 0x22;
  1         2  
  1         33  
1003 1     1   5 use constant DIV => 0x23;
  1         1  
  1         48  
1004 1     1   5 use constant IDIV => 0x24;
  1         1  
  1         45  
1005 1     1   15 use constant REM => 0x25;
  1         1  
  1         34  
1006 1     1   5 use constant B_AND => 0x26;
  1         1  
  1         40  
1007 1     1   4 use constant B_OR => 0x27;
  1         1  
  1         44  
1008 1     1   5 use constant B_XOR => 0x28;
  1         1  
  1         34  
1009 1     1   4 use constant B_NOT => 0x29;
  1         1  
  1         44  
1010 1     1   4 use constant B_LSHIFT => 0x2A;
  1         2  
  1         30  
1011 1     1   5 use constant B_RSSHIFT => 0x2B;
  1         1  
  1         38  
1012 1     1   5 use constant B_RSZSHIFT => 0x2C;
  1         1  
  1         46  
1013 1     1   4 use constant _EQ => 0x2D;
  1         2  
  1         31  
1014 1     1   4 use constant _LE => 0x2E;
  1         1  
  1         35  
1015 1     1   4 use constant _LT => 0x2F;
  1         1  
  1         31  
1016 1     1   4 use constant _GE => 0x30;
  1         2  
  1         35  
1017 1     1   4 use constant _GT => 0x31;
  1         2  
  1         30  
1018 1     1   4 use constant _NE => 0x32;
  1         1  
  1         36  
1019 1     1   4 use constant NOT => 0x33;
  1         2  
  1         45  
1020 1     1   4 use constant SCAND => 0x34;
  1         1  
  1         48  
1021 1     1   4 use constant SCOR => 0x35;
  1         2  
  1         47  
1022 1     1   5 use constant TOBOOL => 0x36;
  1         1  
  1         33  
1023 1     1   5 use constant POP => 0x37;
  1         1  
  1         38  
1024 1     1   4 use constant TYPEOF => 0x38;
  1         2  
  1         41  
1025 1     1   4 use constant ISVALID => 0x39;
  1         2  
  1         30  
1026 1     1   5 use constant RETURN => 0x3A;
  1         2  
  1         43  
1027 1     1   4 use constant RETURN_ES => 0x3B;
  1         2  
  1         42  
1028 1     1   4 use constant DEBUG => 0x3C;
  1         2  
  1         30  
1029            
1030 1     1   5 use constant UINT3_MAX => 7;
  1         1  
  1         35  
1031 1     1   5 use constant UINT4_MAX => 15;
  1         1  
  1         30  
1032 1     1   5 use constant UINT5_MAX => 31;
  1         1  
  1         37  
1033 1     1   4 use constant UINT8_MAX => 255;
  1         2  
  1         39  
1034 1     1   4 use constant UINT16_MAX => 65535;
  1         2  
  1         5738  
1035            
1036             sub new {
1037 0     0     my $proto = shift;
1038 0   0       my $class = ref($proto) || $proto;
1039 0           my $self = {};
1040 0           bless($self, $class);
1041 0           my ($parser) = @_;
1042 0           $self->{parser} = $parser;
1043 0           $self->{nb} = 0;
1044 0           $self->{size} = 0;
1045 0           $self->{action} = 0;
1046 0           return $self;
1047             }
1048            
1049             sub visitFunction {
1050 0     0     my $self = shift;
1051 0           my ($opcode) = @_;
1052 0           my $func = $opcode->{Value};
1053 0           my $def = $opcode->{Definition};
1054 0           my $save_size = $self->{size};
1055 0           $self->{size} = 0;
1056 0 0         if ($self->{action}) {
1057 0           my $FunctionSize = $opcode->{Index};
1058 0           WAP::wmls::asm::asmComment("function prologue");
1059 0           WAP::wmls::asm::asmByte("NumberOfArguments", $def->{NumberOfArguments});
1060 0           WAP::wmls::asm::asmByte("NumberOfLocalVariables", $def->{NumberOfLocalVariables});
1061 0           WAP::wmls::asm::asmMultiByte("FunctionSize", $FunctionSize);
1062 0           WAP::wmls::asm::asmComment("function code");
1063 0 0         $func->visitActive($self)
1064             if (defined $func);
1065 0           WAP::wmls::verbose::Source($opcode);
1066             }
1067             else {
1068 0           my $nb = $self->_indexeVariables($func, $def->{NumberOfArguments});
1069 0 0         if ($nb > UINT8_MAX) {
1070 0           $self->{parser}->genError($opcode, "too many variables");
1071             }
1072             else {
1073 0           $def->{NumberOfLocalVariables} = $nb - $def->{NumberOfArguments};
1074 0           my $func_size;
1075 0   0       do {
1076 0           $func_size = $self->{size};
1077 0           $self->{size} = 0;
1078 0 0         $func->visitActive($self)
1079             if (defined $func);
1080             # print "size : $self->{size}\n";
1081             }
1082             while ( $func_size != $self->{size}
1083             and !exists $self->{parser}->YYData->{nb_error} );
1084             }
1085 0           $opcode->{Index} = $self->{size};
1086             }
1087 0           $self->{size} = $save_size;
1088 0           $self->{size} += 2;
1089 0           $self->{size} += WAP::wmls::multibyte::size($opcode->{Index});
1090 0           $self->{size} += $opcode->{Index};
1091 0           return;
1092             }
1093            
1094             sub _indexeVariables {
1095 0     0     my $self = shift;
1096 0           my ($func, $nb_args) = @_;
1097 0           my $idx = $nb_args;
1098 0 0         if (defined $func) {
1099 0           for (my $node = $func->getFirstActive(); defined $node; $node = $node->getNextActive()) {
1100 0           my $opcode = $node->{OpCode};
1101 0 0 0       if ( $opcode->isa('LoadVar')
      0        
      0        
      0        
      0        
1102             or $opcode->isa('StoreVar')
1103             or $opcode->isa('IncrVar')
1104             or $opcode->isa('DecrVar')
1105             or $opcode->isa('AddAsg')
1106             or $opcode->isa('SubAsg') ) {
1107 0           my $def = $opcode->{Definition};
1108 0 0         if ($def->{ID} == 0xffff) {
1109 0           $def->{ID} = $idx;
1110 0           $idx ++;
1111             }
1112             }
1113             }
1114             }
1115 0           return $idx;
1116             }
1117            
1118             sub visitLoadVar {
1119 0     0     my $self = shift;
1120 0           my ($opcode) = @_;
1121 0 0         if ($self->{action}) {
1122 0           WAP::wmls::verbose::Source($opcode);
1123             }
1124 0           my $def = $opcode->{Definition};
1125 0           my $vindex = $def->{ID};
1126 0 0         croak "INTERNAL ERROR in codeVisitor::visitDecrVar\n"
1127             unless ($vindex <= UINT8_MAX);
1128 0 0         if ($vindex <= UINT5_MAX) {
1129 0 0         if ($self->{action}) {
1130 0           WAP::wmls::asm::asmOpcode1s(LOAD_VAR_S, $vindex);
1131             }
1132 0           $self->{size} += 1;
1133             }
1134             else {
1135 0 0         if ($self->{action}) {
1136 0           WAP::wmls::asm::asmOpcode2(LOAD_VAR, $vindex);
1137             }
1138 0           $self->{size} += 2;
1139             }
1140 0 0         if ($self->{action}) {
1141 0           WAP::wmls::asm::asmComment($def->{Symbol});
1142             }
1143 0           return;
1144             }
1145            
1146             sub visitStoreVar {
1147 0     0     my $self = shift;
1148 0           my ($opcode) = @_;
1149 0 0         if ($self->{action}) {
1150 0           WAP::wmls::verbose::Source($opcode);
1151             }
1152 0           my $def = $opcode->{Definition};
1153 0           my $vindex = $def->{ID};
1154 0 0         croak "INTERNAL ERROR in codeVisitor::visitDecrVar\n"
1155             unless ($vindex <= UINT8_MAX);
1156 0 0         if ($vindex <= UINT4_MAX) {
1157 0 0         if ($self->{action}) {
1158 0           WAP::wmls::asm::asmOpcode1s(STORE_VAR_S, $vindex);
1159             }
1160 0           $self->{size} += 1;
1161             }
1162             else {
1163 0 0         if ($self->{action}) {
1164 0           WAP::wmls::asm::asmOpcode2(STORE_VAR, $vindex);
1165             }
1166 0           $self->{size} += 2;
1167             }
1168 0 0         if ($self->{action}) {
1169 0           WAP::wmls::asm::asmComment($def->{Symbol});
1170             }
1171 0           return;
1172             }
1173            
1174             sub visitIncrVar {
1175 0     0     my $self = shift;
1176 0           my ($opcode) = @_;
1177 0 0         if ($self->{action}) {
1178 0           WAP::wmls::verbose::Source($opcode);
1179             }
1180 0           my $def = $opcode->{Definition};
1181 0           my $vindex = $def->{ID};
1182 0 0         croak "INTERNAL ERROR in codeVisitor::visitDecrVar\n"
1183             unless ($vindex <= UINT8_MAX);
1184 0 0         if ($vindex <= UINT3_MAX) {
1185 0 0         if ($self->{action}) {
1186 0           WAP::wmls::asm::asmOpcode1s(INCR_VAR_S, $vindex);
1187             }
1188 0           $self->{size} += 1;
1189             }
1190             else {
1191 0 0         if ($self->{action}) {
1192 0           WAP::wmls::asm::asmOpcode2(INCR_VAR, $vindex);
1193             }
1194 0           $self->{size} += 2;
1195             }
1196 0 0         if ($self->{action}) {
1197 0           WAP::wmls::asm::asmComment($def->{Symbol});
1198             }
1199 0           return;
1200             }
1201            
1202             sub visitDecrVar {
1203 0     0     my $self = shift;
1204 0           my ($opcode) = @_;
1205 0           my $def = $opcode->{Definition};
1206 0           my $vindex = $def->{ID};
1207 0 0         croak "INTERNAL ERROR in codeVisitor::visitDecrVar\n"
1208             unless ($vindex <= UINT8_MAX);
1209 0 0         if ($self->{action}) {
1210 0           WAP::wmls::verbose::Source($opcode);
1211 0           WAP::wmls::asm::asmOpcode2(DECR_VAR, $vindex);
1212 0           WAP::wmls::asm::asmComment($def->{Symbol});
1213             }
1214 0           $self->{size} += 2;
1215 0           return;
1216             }
1217            
1218             sub visitAddAsg {
1219 0     0     my $self = shift;
1220 0           my ($opcode) = @_;
1221 0           my $def = $opcode->{Definition};
1222 0           my $vindex = $def->{ID};
1223 0 0         croak "INTERNAL ERROR in codeVisitor::visitAddAsg\n"
1224             unless ($vindex <= UINT8_MAX);
1225 0 0         if ($self->{action}) {
1226 0           WAP::wmls::verbose::Source($opcode);
1227 0           WAP::wmls::asm::asmOpcode2(ADD_ASG, $vindex);
1228 0           WAP::wmls::asm::asmComment($def->{Symbol});
1229             }
1230 0           $self->{size} += 2;
1231 0           return;
1232             }
1233            
1234             sub visitSubAsg {
1235 0     0     my $self = shift;
1236 0           my ($opcode) = @_;
1237 0           my $def = $opcode->{Definition};
1238 0           my $vindex = $def->{ID};
1239 0 0         croak "INTERNAL ERROR in codeVisitor::visitSubAsg\n"
1240             unless ($vindex <= UINT8_MAX);
1241 0 0         if ($self->{action}) {
1242 0           WAP::wmls::verbose::Source($opcode);
1243 0           WAP::wmls::asm::asmOpcode2(SUB_ASG, $vindex);
1244 0           WAP::wmls::asm::asmComment($def->{Symbol});
1245             }
1246 0           $self->{size} += 2;
1247 0           return;
1248             }
1249            
1250             sub visitLabel {
1251 0     0     my $self = shift;
1252 0           my ($opcode) = @_;
1253 0 0         if ($self->{action}) {
1254             # no verbose
1255 0           WAP::wmls::asm::asmComment($opcode->{Definition}->{Symbol});
1256             }
1257 0           $opcode->{Definition}->{Index} = $self->{size};
1258 0           return;
1259             }
1260            
1261             sub visitPop {
1262 0     0     my $self = shift;
1263 0           my ($opcode) = @_;
1264 0 0         if ($self->{action}) {
1265             # no verbose
1266 0           WAP::wmls::asm::asmOpcode1(POP);
1267 0           WAP::wmls::asm::asmComment();
1268             }
1269 0           $self->{size} += 1;
1270 0           return;
1271             }
1272            
1273             sub visitToBool {
1274 0     0     my $self = shift;
1275 0           my ($opcode) = @_;
1276 0 0         if ($self->{action}) {
1277 0           WAP::wmls::verbose::Source($opcode);
1278 0           WAP::wmls::asm::asmOpcode1(TOBOOL);
1279 0           WAP::wmls::asm::asmComment();
1280             }
1281 0           $self->{size} += 1;
1282 0           return;
1283             }
1284            
1285             sub visitScOr {
1286 0     0     my $self = shift;
1287 0           my ($opcode) = @_;
1288 0 0         if ($self->{action}) {
1289 0           WAP::wmls::verbose::Source($opcode);
1290 0           WAP::wmls::asm::asmOpcode1(SCOR);
1291 0           WAP::wmls::asm::asmComment();
1292             }
1293 0           $self->{size} += 1;
1294 0           return;
1295             }
1296            
1297             sub visitScAnd {
1298 0     0     my $self = shift;
1299 0           my ($opcode) = @_;
1300 0 0         if ($self->{action}) {
1301 0           WAP::wmls::verbose::Source($opcode);
1302 0           WAP::wmls::asm::asmOpcode1(SCAND);
1303 0           WAP::wmls::asm::asmComment();
1304             }
1305 0           $self->{size} += 1;
1306 0           return;
1307             }
1308            
1309             sub visitReturn {
1310 0     0     my $self = shift;
1311 0           my ($opcode) = @_;
1312 0 0         if ($self->{action}) {
1313 0           WAP::wmls::verbose::Source($opcode);
1314 0           WAP::wmls::asm::asmOpcode1(RETURN);
1315 0           WAP::wmls::asm::asmComment();
1316             }
1317 0           $self->{size} += 1;
1318 0           return;
1319             }
1320            
1321             sub visitReturnES {
1322 0     0     my $self = shift;
1323 0           my ($opcode) = @_;
1324 0 0         if ($self->{action}) {
1325 0           WAP::wmls::verbose::Source($opcode);
1326 0           WAP::wmls::asm::asmOpcode1(RETURN_ES);
1327 0           WAP::wmls::asm::asmComment();
1328             }
1329 0           $self->{size} += 1;
1330 0           return;
1331             }
1332            
1333             sub visitCall {
1334 0     0     my $self = shift;
1335 0           my ($opcode) = @_;
1336 0 0         if ($self->{action}) {
1337 0           WAP::wmls::verbose::Source($opcode);
1338             }
1339 0           my $def = $opcode->{Definition};
1340 0           my $symb = $def->{Symbol};
1341 0 0         if ($def->{Type} ne 'UNDEF_FUNC') {
1342 0           my $nb_args = $def->{NumberOfArguments};
1343 0           my $findex = $def->{ID};
1344 0 0         croak "INTERNAL ERROR in codeVisitor::visitCallLib\n"
1345             unless ($nb_args <= UINT8_MAX);
1346 0 0         croak "INTERNAL ERROR in codeVisitor::visitCall\n"
1347             unless ($findex <= UINT8_MAX);
1348 0 0         if ($nb_args != $opcode->{Index}) {
    0          
1349 0           $self->{parser}->genError($opcode, "Wrong argument number for local function - $symb.\n");
1350             }
1351             elsif ($findex <= UINT3_MAX) {
1352 0 0         if ($self->{action}) {
1353 0           WAP::wmls::asm::asmOpcode1s(CALL_S, $findex);
1354             }
1355 0           $self->{size} += 1;
1356             }
1357             else {
1358 0 0         if ($self->{action}) {
1359 0           WAP::wmls::asm::asmOpcode2(CALL, $findex);
1360             }
1361 0           $self->{size} += 2;
1362             }
1363 0 0         if ($self->{action}) {
1364 0           WAP::wmls::asm::asmComment($def->{Symbol});
1365             }
1366             }
1367             else {
1368 0           $self->{parser}->genError($opcode, "Undefined function - $symb.\n");
1369             }
1370 0           return;
1371             }
1372            
1373             sub visitCallLib {
1374 0     0     my $self = shift;
1375 0           my ($opcode) = @_;
1376 0 0         if ($self->{action}) {
1377 0           WAP::wmls::verbose::Source($opcode);
1378             }
1379 0           my $def = $opcode->{Definition};
1380 0           my $findex = $def->{ID};
1381 0           my $lindex = $def->{LibraryID};
1382 0 0         croak "INTERNAL ERROR in codeVisitor::visitCallLib\n"
1383             unless ($findex <= UINT8_MAX);
1384 0 0 0       if ($findex <= UINT3_MAX and $lindex <= UINT8_MAX) {
    0          
1385 0 0         if ($self->{action}) {
1386 0           WAP::wmls::asm::asmOpcode2s(CALL_LIB_S, $findex, $lindex);
1387             }
1388 0           $self->{size} += 2;
1389             }
1390             elsif ($lindex <= UINT8_MAX) {
1391 0 0         if ($self->{action}) {
1392 0           WAP::wmls::asm::asmOpcode3(CALL_LIB, $findex, $lindex);
1393             }
1394 0           $self->{size} += 3;
1395             }
1396             else {
1397 0 0         if ($self->{action}) {
1398 0           WAP::wmls::asm::asmOpcode4w(CALL_LIB_W, $findex, $lindex);
1399             }
1400 0           $self->{size} += 4;
1401             }
1402 0 0         if ($self->{action}) {
1403 0           WAP::wmls::asm::asmComment($def->{Symbol});
1404             }
1405 0           return;
1406             }
1407            
1408             sub visitCallUrl {
1409 0     0     my $self = shift;
1410 0           my ($opcode) = @_;
1411 0 0         if ($self->{action}) {
1412 0           WAP::wmls::verbose::Source($opcode);
1413             }
1414 0           my $urlindex = $opcode->{Url}->{Index};
1415 0           my $findex = $opcode->{Index};
1416 0           my $def = $opcode->{Definition};
1417 0           my $nb_args = $def->{NumberOfArguments};
1418 0 0 0       croak "INTERNAL ERROR in codeVisitor::visitCallUrl\n"
1419             unless ($urlindex <= UINT16_MAX and $findex <= UINT16_MAX);
1420 0 0         croak "INTERNAL ERROR in codeVisitor::visitCallUrl\n"
1421             unless ($nb_args <= UINT8_MAX);
1422 0 0 0       if ($urlindex <= UINT8_MAX and $findex <= UINT8_MAX) {
1423 0 0         if ($self->{action}) {
1424 0           WAP::wmls::asm::asmOpcode4(CALL_URL, $urlindex, $findex, $nb_args);
1425             }
1426 0           $self->{size} += 4;
1427             }
1428             else {
1429 0 0         if ($self->{action}) {
1430 0           WAP::wmls::asm::asmOpcode6(CALL_URL_W, $urlindex, $findex, $nb_args);
1431             }
1432 0           $self->{size} += 6;
1433             }
1434 0 0         if ($self->{action}) {
1435 0           WAP::wmls::asm::asmComment($def->{Symbol});
1436             }
1437 0           return;
1438             }
1439            
1440             sub visitJump {
1441 0     0     my $self = shift;
1442 0           my ($opcode) = @_;
1443 0           my $def = $opcode->{Definition};
1444 0           my $dest = $def->{Index};
1445             # no verbose
1446 0 0         if ($dest > $self->{size}) {
1447 0           my $offset = $dest - $self->{size};
1448 0 0         if ($offset <= UINT5_MAX + 1) {
    0          
    0          
1449 0 0         if ($self->{action}) {
1450 0           WAP::wmls::asm::asmOpcode1s(JUMP_FW_S, $offset - 1);
1451             }
1452 0           $self->{size} += 1;
1453             }
1454             elsif ($offset <= UINT8_MAX + 2) {
1455 0 0         if ($self->{action}) {
1456 0           WAP::wmls::asm::asmOpcode2(JUMP_FW, $offset - 2);
1457             }
1458 0           $self->{size} += 2;
1459             }
1460             elsif ($offset <= UINT16_MAX + 3) {
1461 0 0         if ($self->{action}) {
1462 0           WAP::wmls::asm::asmOpcode3w(JUMP_FW_W, $offset - 3);
1463             }
1464 0           $self->{size} += 3;
1465             }
1466             else {
1467 0 0         if ($self->{action}) {
1468 0           $self->{parser}->genError($opcode, "Too long JUMP_FW");
1469             }
1470 0           $self->{size} += 3;
1471             }
1472             }
1473             else {
1474 0           my $offset = $self->{size} - $dest;
1475 0 0         if ($offset <= UINT5_MAX) {
    0          
    0          
1476 0 0         if ($self->{action}) {
1477 0           WAP::wmls::asm::asmOpcode1s(JUMP_BW_S, $offset);
1478             }
1479 0           $self->{size} += 1;
1480             }
1481             elsif ($offset <= UINT8_MAX) {
1482 0 0         if ($self->{action}) {
1483 0           WAP::wmls::asm::asmOpcode2(JUMP_BW, $offset);
1484             }
1485 0           $self->{size} += 2;
1486             }
1487             elsif ($offset <= UINT16_MAX) {
1488 0 0         if ($self->{action}) {
1489 0           WAP::wmls::asm::asmOpcode3w(JUMP_BW_W, $offset);
1490             }
1491 0           $self->{size} += 3;
1492             }
1493             else {
1494 0 0         if ($self->{action}) {
1495 0           $self->{parser}->genError($opcode, "Too long JUMP_BW");
1496             }
1497 0           $self->{size} += 3;
1498             }
1499             }
1500 0 0         if ($self->{action}) {
1501 0           WAP::wmls::asm::asmComment($def->{Symbol});
1502             }
1503 0           return;
1504             }
1505            
1506             sub visitFalseJump {
1507 0     0     my $self = shift;
1508 0           my ($opcode) = @_;
1509 0           my $def = $opcode->{Definition};
1510 0           my $dest = $def->{Index};
1511             # no verbose
1512 0 0         if ($dest > $self->{size}) {
1513 0           my $offset = $dest - $self->{size};
1514 0 0         if ($offset <= UINT5_MAX + 1) {
    0          
    0          
1515 0 0         if ($self->{action}) {
1516 0           WAP::wmls::asm::asmOpcode1s(TJUMP_FW_S, $offset - 1);
1517             }
1518 0           $self->{size} += 1;
1519             }
1520             elsif ($offset <= UINT8_MAX + 2) {
1521 0 0         if ($self->{action}) {
1522 0           WAP::wmls::asm::asmOpcode2(TJUMP_FW, $offset - 2);
1523             }
1524 0           $self->{size} += 2;
1525             }
1526             elsif ($offset <= UINT16_MAX + 3) {
1527 0 0         if ($self->{action}) {
1528 0           WAP::wmls::asm::asmOpcode3w(TJUMP_FW_W, $offset - 3);
1529             }
1530 0           $self->{size} += 3;
1531             }
1532             else {
1533 0 0         if ($self->{action}) {
1534 0           $self->{parser}->genError($opcode, "Too long TJUMP_FW");
1535             }
1536 0           $self->{size} += 3;
1537             }
1538             }
1539             else {
1540 0           my $offset = $self->{size} - $dest;
1541 0 0         if ($offset <= UINT8_MAX) {
    0          
1542 0 0         if ($self->{action}) {
1543 0           WAP::wmls::asm::asmOpcode2(TJUMP_BW, $offset);
1544             }
1545 0           $self->{size} += 2;
1546             }
1547             elsif ($offset <= UINT16_MAX) {
1548 0 0         if ($self->{action}) {
1549 0           WAP::wmls::asm::asmOpcode3w(TJUMP_BW_W, $offset);
1550             }
1551 0           $self->{size} += 3;
1552             }
1553             else {
1554 0 0         if ($self->{action}) {
1555 0           $self->{parser}->genError($opcode, "Too long TJUMP_BW");
1556             }
1557 0           $self->{size} += 3;
1558             }
1559             }
1560 0 0         if ($self->{action}) {
1561 0           WAP::wmls::asm::asmComment($def->{Symbol});
1562             }
1563 0           return;
1564             }
1565            
1566             sub visitUnaryOp {
1567 0     0     my $self = shift;
1568 0           my ($opcode) = @_;
1569 0 0         if ($self->{action}) {
1570 0           WAP::wmls::verbose::Source($opcode);
1571 0           my $oper = $opcode->{Operator};
1572 0 0         if ($oper eq 'typeof') {
    0          
    0          
    0          
    0          
    0          
    0          
1573 0           WAP::wmls::asm::asmOpcode1(TYPEOF);
1574             }
1575             elsif ($oper eq 'isvalid') {
1576 0           WAP::wmls::asm::asmOpcode1(ISVALID);
1577             }
1578             elsif ($oper eq '-') {
1579 0           WAP::wmls::asm::asmOpcode1(UMINUS);
1580             }
1581             elsif ($oper eq '~') {
1582 0           WAP::wmls::asm::asmOpcode1(B_NOT);
1583             }
1584             elsif ($oper eq '!') {
1585 0           WAP::wmls::asm::asmOpcode1(NOT);
1586             }
1587             elsif ($oper eq '++') {
1588 0           WAP::wmls::asm::asmOpcode1(INCR);
1589             }
1590             elsif ($oper eq '--') {
1591 0           WAP::wmls::asm::asmOpcode1(DECR);
1592             }
1593             else {
1594 0           croak "INTERNAL ERROR in codeVisitor::visitUnaryOp (oper:$oper)\n";
1595             }
1596 0           WAP::wmls::asm::asmComment();
1597             }
1598 0           $self->{size} += 1;
1599 0           return;
1600             }
1601            
1602             sub visitBinaryOp {
1603 0     0     my $self = shift;
1604 0           my ($opcode) = @_;
1605 0 0         if ($self->{action}) {
1606 0           WAP::wmls::verbose::Source($opcode);
1607 0           my $oper = $opcode->{Operator};
1608 0 0         if ($oper eq '+') {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1609 0           WAP::wmls::asm::asmOpcode1(ADD);
1610             }
1611             elsif ($oper eq '-') {
1612 0           WAP::wmls::asm::asmOpcode1(SUB);
1613             }
1614             elsif ($oper eq '*') {
1615 0           WAP::wmls::asm::asmOpcode1(MUL);
1616             }
1617             elsif ($oper eq '/') {
1618 0           WAP::wmls::asm::asmOpcode1(DIV);
1619             }
1620             elsif ($oper eq 'div') {
1621 0           WAP::wmls::asm::asmOpcode1(IDIV);
1622             }
1623             elsif ($oper eq '%') {
1624 0           WAP::wmls::asm::asmOpcode1(REM);
1625             }
1626             elsif ($oper eq '<<') {
1627 0           WAP::wmls::asm::asmOpcode1(B_LSHIFT);
1628             }
1629             elsif ($oper eq '>>') {
1630 0           WAP::wmls::asm::asmOpcode1(B_RSSHIFT);
1631             }
1632             elsif ($oper eq '>>>') {
1633 0           WAP::wmls::asm::asmOpcode1(B_RSZSHIFT);
1634             }
1635             elsif ($oper eq '<') {
1636 0           WAP::wmls::asm::asmOpcode1(_LT);
1637             }
1638             elsif ($oper eq '>') {
1639 0           WAP::wmls::asm::asmOpcode1(_GT);
1640             }
1641             elsif ($oper eq '<=') {
1642 0           WAP::wmls::asm::asmOpcode1(_LE);
1643             }
1644             elsif ($oper eq '>=') {
1645 0           WAP::wmls::asm::asmOpcode1(_GE);
1646             }
1647             elsif ($oper eq '==') {
1648 0           WAP::wmls::asm::asmOpcode1(_EQ);
1649             }
1650             elsif ($oper eq '!=') {
1651 0           WAP::wmls::asm::asmOpcode1(_NE);
1652             }
1653             elsif ($oper eq '&') {
1654 0           WAP::wmls::asm::asmOpcode1(B_AND);
1655             }
1656             elsif ($oper eq '^') {
1657 0           WAP::wmls::asm::asmOpcode1(B_XOR);
1658             }
1659             elsif ($oper eq '|') {
1660 0           WAP::wmls::asm::asmOpcode1(B_OR);
1661             }
1662             else {
1663 0           croak "INTERNAL ERROR in codeVisitor::visitBinaryOp (oper:$oper)\n";
1664             }
1665 0           WAP::wmls::asm::asmComment();
1666             }
1667 0           $self->{size} += 1;
1668 0           return;
1669             }
1670            
1671             sub visitLoadConst {
1672 0     0     my $self = shift;
1673 0           my ($opcode) = @_;
1674 0 0         if ($self->{action}) {
1675 0           WAP::wmls::verbose::Source($opcode);
1676             }
1677 0           my $type = $opcode->{TypeDef};
1678 0           my $value = $opcode->{Value};
1679             # print "index $opcode->{Index} cst $value\n";
1680 0 0 0       if ($type eq 'TYPE_INVALID') {
    0          
    0          
    0          
    0          
1681 0 0         if ($self->{action}) {
1682 0           WAP::wmls::asm::asmOpcode1(CONST_INVALID);
1683 0           WAP::wmls::asm::asmComment();
1684             }
1685 0           $self->{size} += 1;
1686             }
1687             elsif ($type eq 'TYPE_BOOLEAN') {
1688 0 0         if ($self->{action}) {
1689 0 0         if ($value) {
1690 0           WAP::wmls::asm::asmOpcode1(CONST_TRUE);
1691 0           WAP::wmls::asm::asmComment();
1692             }
1693             else {
1694 0           WAP::wmls::asm::asmOpcode1(CONST_FALSE);
1695 0           WAP::wmls::asm::asmComment();
1696             }
1697             }
1698 0           $self->{size} += 1;
1699             }
1700             elsif ($type eq 'TYPE_STRING' or $type eq 'TYPE_UTF8_STRING') {
1701 0 0         if (length $value == 0) {
1702 0 0         if ($self->{action}) {
1703 0           WAP::wmls::asm::asmOpcode1(CONST_ES);
1704 0           WAP::wmls::asm::asmComment();
1705             }
1706 0           $self->{size} += 1;
1707             }
1708             else {
1709 0           goto load_const;
1710             }
1711             }
1712             elsif ($type eq 'TYPE_FLOAT') {
1713 0           load_const:
1714             my $cindex = $opcode->{Index};
1715 0 0         croak "INTERNAL ERROR in codeVisitor::visitLoadConst\n"
1716             unless ($cindex <= UINT16_MAX);
1717 0 0         if ($cindex <= UINT4_MAX) {
    0          
1718 0 0         if ($self->{action}) {
1719 0           WAP::wmls::asm::asmOpcode1s(LOAD_CONST_S, $cindex);
1720             }
1721 0           $self->{size} += 1;
1722             }
1723             elsif ($cindex <= UINT8_MAX) {
1724 0 0         if ($self->{action}) {
1725 0           WAP::wmls::asm::asmOpcode2(LOAD_CONST, $cindex);
1726             }
1727 0           $self->{size} += 2;
1728             }
1729             else {
1730 0 0         if ($self->{action}) {
1731 0           WAP::wmls::asm::asmOpcode3w(LOAD_CONST_W, $cindex);
1732             }
1733 0           $self->{size} += 3;
1734             }
1735 0 0         if ($self->{action}) {
1736 0           WAP::wmls::asm::asmComment($value);
1737             }
1738             }
1739             elsif ($type eq 'TYPE_INTEGER') {
1740 0 0         if ($value == 0) {
    0          
    0          
1741 0 0         if ($self->{action}) {
1742 0           WAP::wmls::asm::asmOpcode1(CONST_0);
1743 0           WAP::wmls::asm::asmComment();
1744             }
1745 0           $self->{size} += 1;
1746             }
1747             elsif ($value == 1) {
1748 0 0         if ($self->{action}) {
1749 0           WAP::wmls::asm::asmOpcode1(CONST_1);
1750 0           WAP::wmls::asm::asmComment();
1751             }
1752 0           $self->{size} += 1;
1753             }
1754             elsif ($value == -1) {
1755 0 0         if ($self->{action}) {
1756 0           WAP::wmls::asm::asmOpcode1(CONST_M1);
1757 0           WAP::wmls::asm::asmComment();
1758             }
1759 0           $self->{size} += 1;
1760             }
1761             else {
1762 0           goto load_const;
1763             }
1764             }
1765             else {
1766 0           croak "INTERNAL ERROR in codeVisitor::visitLoadConst (type:$type)\n";
1767             }
1768 0           return;
1769             }
1770            
1771             ###############################################################################
1772            
1773             package WAP::wmls::parser;
1774            
1775 1     1   8 use constant WMLS_MAJOR_VERSION => 1;
  1         2  
  1         68  
1776 1     1   6 use constant WMLS_MINOR_VERSION => 1;
  1         2  
  1         1376  
1777            
1778             sub genError {
1779 0     0 0   my $parser = shift;
1780 0           my ($opcode, $msg) = @_;
1781            
1782 0 0         if (exists $parser->YYData->{nb_error}) {
1783 0           $parser->YYData->{nb_error} ++;
1784             }
1785             else {
1786 0           $parser->YYData->{nb_error} = 1;
1787             }
1788            
1789 0 0 0       print STDOUT '#',$parser->YYData->{filename},':',$opcode->{Lineno},'#Error: ',$msg
1790             if ( exists $parser->YYData->{verbose_error}
1791             and $parser->YYData->{verbose_error});
1792 0           return;
1793             }
1794            
1795             sub genWarning {
1796 0     0 0   my $parser = shift;
1797 0           my ($opcode, $msg) = @_;
1798            
1799 0 0         if (exists $parser->YYData->{nb_warning}) {
1800 0           $parser->YYData->{nb_warning} ++;
1801             }
1802             else {
1803 0           $parser->YYData->{nb_warning} = 1;
1804             }
1805            
1806 0 0 0       print STDOUT '#',$parser->YYData->{filename},':',$opcode->{Lineno},'#Warning: ',$msg
1807             if ( exists $parser->YYData->{verbose_warning}
1808             and $parser->YYData->{verbose_warning});
1809 0           return;
1810             }
1811            
1812             sub generate {
1813 0     0 0   my $parser = shift;
1814            
1815 0           my $CharacterSet = 4; # iso-8859-1
1816             # ConstantPool
1817 0           my $CodeSize = 0;
1818 0           my $constantVisitor = new WAP::wmls::constantVisitor($parser);
1819 0 0         $parser->YYData->{PragmaList}->visit($constantVisitor)
1820             if (defined $parser->YYData->{PragmaList});
1821 0 0         $parser->YYData->{FunctionList}->visitActive($constantVisitor)
1822             if (defined $parser->YYData->{FunctionList});
1823 0           my $NumberOfConstants = $constantVisitor->{nb};
1824 0 0         $parser->genError($parser->YYData->{FunctionList}, "Too many constants ($NumberOfConstants)")
1825             if ($NumberOfConstants > 65535);
1826 0           $CodeSize += WAP::wmls::multibyte::size($NumberOfConstants);
1827 0           $CodeSize += WAP::wmls::multibyte::size($CharacterSet);
1828 0           $CodeSize += $constantVisitor->{size};
1829             # PragmaPool
1830 0           my $pragmaVisitor = new WAP::wmls::pragmaVisitor($parser);
1831 0 0         $parser->YYData->{PragmaList}->visit($pragmaVisitor)
1832             if (defined $parser->YYData->{PragmaList});
1833 0           my $NumberOfPragmas = $pragmaVisitor->{nb};
1834 0 0         $parser->genError($parser->YYData->{PragmaList}, "Too many pragmas ($NumberOfPragmas)")
1835             if ($NumberOfPragmas > 65535);
1836 0           $CodeSize += WAP::wmls::multibyte::size($NumberOfPragmas);
1837 0           $CodeSize += $pragmaVisitor->{size};
1838             # FunctionPool
1839 0           my $NumberOfFunctions = 0;
1840 0           for (my $func = $parser->YYData->{FunctionList}; defined $func; $func = $func->{Next}) {
1841 0           $NumberOfFunctions ++;
1842             }
1843 0 0         $parser->genError($parser->YYData->{FunctionList}, "Too many functions ($NumberOfFunctions).\n")
1844             if ($NumberOfFunctions > 255);
1845 0           $CodeSize += 1; # NumberOfFunctions
1846 0           my $NumberOfFunctionNames = 0;
1847 0           for (my $func = $parser->YYData->{FunctionList}; defined $func; $func = $func->{Next}) {
1848 0           my $def = $func->{OpCode}->{Definition};
1849 0 0         next if ($def->{Type} ne 'PUBLIC_FUNC');
1850 0           $NumberOfFunctionNames ++;
1851 0           $CodeSize += 1; # idx
1852 0           $CodeSize += 1; # length
1853 0           $CodeSize += length $def->{Symbol};
1854             }
1855 0 0         $parser->genError($parser->YYData->{FunctionList}->{OpCode}, "No external function defined.\n")
1856             unless ($NumberOfFunctionNames);
1857 0           $CodeSize += 1; # NumberOfFunctionNames
1858 0           my $codeVisitor = new WAP::wmls::codeVisitor($parser);
1859 0 0         $parser->YYData->{FunctionList}->visitActive($codeVisitor)
1860             if (defined $parser->YYData->{FunctionList});
1861 0           $CodeSize += $codeVisitor->{size};
1862            
1863 0 0         unless (exists $parser->YYData->{nb_error}) {
1864 0           my $filename = $parser->YYData->{filename};
1865 0           $filename =~ s/\.wmls$//;
1866 0           $filename .= '.wmlsc';
1867 0 0         open $WAP::wmls::asm::OUT, '>', $filename
1868             or die "can't open $filename ($!)\n";
1869 0           binmode $WAP::wmls::asm::OUT, ':raw';
1870            
1871 0           WAP::wmls::asm::asmComment($filename);
1872 0           WAP::wmls::asm::asmComment("");
1873 0           WAP::wmls::asm::asmComment("Bytecode Header");
1874 0           WAP::wmls::asm::asmComment("");
1875 0           WAP::wmls::asm::asmByte("VersionNumber", 16 * (WMLS_MAJOR_VERSION - 1) + WMLS_MINOR_VERSION);
1876 0           WAP::wmls::asm::asmMultiByte("CodeSize", $CodeSize);
1877 0           WAP::wmls::asm::asmComment("Constant Pool");
1878 0           WAP::wmls::asm::asmComment("");
1879 0           WAP::wmls::asm::asmMultiByte("NumberOfConstants", $NumberOfConstants);
1880 0           WAP::wmls::asm::asmMultiByte("CharacterSet", $CharacterSet);
1881 0           $constantVisitor->{action} = 1;
1882 0 0         $parser->YYData->{PragmaList}->visit($constantVisitor)
1883             if (defined $parser->YYData->{PragmaList});
1884 0 0         $parser->YYData->{FunctionList}->visitActive($constantVisitor)
1885             if (defined $parser->YYData->{FunctionList});
1886 0           WAP::wmls::asm::asmComment("Pragma Pool");
1887 0           WAP::wmls::asm::asmComment("");
1888 0           WAP::wmls::asm::asmMultiByte("NumberOfPragmas", $NumberOfPragmas);
1889 0           $pragmaVisitor->{nb} = 0;
1890 0           $pragmaVisitor->{action} = 1;
1891 0 0         $parser->YYData->{PragmaList}->visit($pragmaVisitor)
1892             if (defined $parser->YYData->{PragmaList});
1893 0           WAP::wmls::asm::asmComment("Function Pool");
1894 0           WAP::wmls::asm::asmComment("");
1895 0           WAP::wmls::asm::asmByte("NumberOfFunctions", $NumberOfFunctions);
1896 0           WAP::wmls::asm::asmComment("Function Name Table");
1897 0           WAP::wmls::asm::asmComment("");
1898 0           WAP::wmls::asm::asmByte("NumberOfFunctionNames", $NumberOfFunctionNames);
1899 0           for (my $func = $parser->YYData->{FunctionList}; defined $func; $func = $func->{Next}) {
1900 0           my $def = $func->{OpCode}->{Definition};
1901 0 0         next if ($def->{Type} ne 'PUBLIC_FUNC');
1902 0           WAP::wmls::asm::asmFunctionName($def->{ID}, $def->{Symbol});
1903             }
1904 0           WAP::wmls::asm::asmComment("Functions");
1905 0           WAP::wmls::asm::asmComment("");
1906 0           $codeVisitor->{action} = 1;
1907 0 0         $parser->YYData->{FunctionList}->visitActive($codeVisitor)
1908             if (defined $parser->YYData->{FunctionList});
1909            
1910 0           close $WAP::wmls::asm::OUT;
1911 0 0         unlink($filename) if (exists $parser->YYData->{nb_error});
1912             }
1913 0           return;
1914             }
1915            
1916             1;
1917