001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.bytecode;
031:
032: import com.caucho.log.Log;
033: import com.caucho.util.IntArray;
034: import com.caucho.util.L10N;
035:
036: import java.util.ArrayList;
037: import java.util.logging.Logger;
038:
039: /**
040: * Visitor for travelling the code.
041: */
042: public class CodeVisitor {
043: static private final Logger log = Log.open(CodeVisitor.class);
044: static private final L10N L = new L10N(CodeVisitor.class);
045:
046: private JavaClass _javaClass;
047: protected CodeAttribute _codeAttr;
048: private byte[] _code;
049: protected int _offset;
050:
051: public CodeVisitor() {
052: }
053:
054: public CodeVisitor(JavaClass javaClass, CodeAttribute codeAttr) {
055: init(javaClass, codeAttr);
056: }
057:
058: public void init(JavaClass javaClass, CodeAttribute codeAttr) {
059: _javaClass = javaClass;
060: _codeAttr = codeAttr;
061: _code = codeAttr.getCode();
062: _offset = 0;
063: }
064:
065: /**
066: * Returns the java class.
067: */
068: public JavaClass getJavaClass() {
069: return _javaClass;
070: }
071:
072: /**
073: * Returns the code attribute.
074: */
075: public CodeAttribute getCodeAttribute() {
076: return _codeAttr;
077: }
078:
079: /**
080: * Returns the offset.
081: */
082: public int getOffset() {
083: return _offset;
084: }
085:
086: /**
087: * Sets the offset.
088: */
089: public void setOffset(int offset) {
090: _offset = offset;
091: }
092:
093: /**
094: * Returns the code buffer.
095: */
096: public byte[] getCode() {
097: return _code;
098: }
099:
100: /**
101: * Returns the exceptions.
102: */
103: public ArrayList<CodeAttribute.ExceptionItem> getExceptions() {
104: return _codeAttr.getExceptions();
105: }
106:
107: /**
108: * Returns the opcode at the cursor.
109: */
110: public int getOpcode() {
111: int op = getCode()[_offset] & 0xff;
112:
113: if (op == WIDE)
114: return getCode()[_offset + 1] & 0xff;
115: else
116: return op;
117: }
118:
119: /**
120: * Goes to the next opcode.
121: */
122: public boolean next() {
123: _offset = nextOffset();
124:
125: return _offset >= 0;
126: }
127:
128: /**
129: * Goes to the next opcode.
130: */
131: protected int nextOffset() {
132: int opcode = getCode()[_offset] & 0xff;
133:
134: int length = OP_LEN[opcode];
135:
136: switch (opcode) {
137: case GOTO:
138: case GOTO_W:
139: case RET:
140: case IRETURN:
141: case LRETURN:
142: case FRETURN:
143: case DRETURN:
144: case ARETURN:
145: case RETURN:
146: case ATHROW:
147: return -1;
148:
149: case TABLESWITCH: {
150: int arg = _offset + 1;
151: arg += (4 - arg % 4) % 4;
152:
153: int low = getInt(arg + 4);
154: int high = getInt(arg + 8);
155:
156: return arg + 12 + (high - low + 1) * 4;
157: }
158:
159: case LOOKUPSWITCH: {
160: return -1;
161:
162: /*
163: int arg = _offset + 1;
164: arg += (4 - arg % 4) % 4;
165:
166: int n = getInt(arg + 4);
167:
168: int next = arg + 12 + n * 8;
169:
170: return next;
171: */
172: }
173:
174: case WIDE: {
175: int op2 = getCode()[_offset + 1] & 0xff;
176:
177: if (op2 == IINC)
178: length = 5;
179: else
180: length = 3;
181: break;
182: }
183: }
184:
185: if (length < 0 || length > 0x10)
186: throw new UnsupportedOperationException(L.l(
187: "{0}: can't handle opcode {1}", "" + _offset, ""
188: + getOpcode()));
189:
190: return _offset + length + 1;
191: }
192:
193: /**
194: * Returns true for a simple branch, i.e. a branch with a simple target.
195: */
196: public boolean isBranch() {
197: switch (getOpcode()) {
198: case IFNULL:
199: case IFNONNULL:
200: case IFNE:
201: case IFEQ:
202: case IFLT:
203: case IFGE:
204: case IFGT:
205: case IFLE:
206: case IF_ICMPEQ:
207: case IF_ICMPNE:
208: case IF_ICMPLT:
209: case IF_ICMPGE:
210: case IF_ICMPGT:
211: case IF_ICMPLE:
212: case IF_ACMPEQ:
213: case IF_ACMPNE:
214: case JSR:
215: case JSR_W:
216: case GOTO:
217: case GOTO_W:
218: return true;
219: }
220:
221: return false;
222: }
223:
224: /**
225: * Returns the branch target.
226: */
227: public int getBranchTarget() {
228: switch (getOpcode()) {
229: case IFNULL:
230: case IFNONNULL:
231: case IFNE:
232: case IFEQ:
233: case IFLT:
234: case IFGE:
235: case IFGT:
236: case IFLE:
237: case IF_ICMPEQ:
238: case IF_ICMPNE:
239: case IF_ICMPLT:
240: case IF_ICMPLE:
241: case IF_ICMPGE:
242: case IF_ICMPGT:
243: case IF_ACMPEQ:
244: case IF_ACMPNE:
245: case GOTO:
246: case JSR:
247: return _offset + getShortArg();
248:
249: case GOTO_W:
250: case JSR_W:
251: return _offset + getIntArg();
252:
253: default:
254: throw new UnsupportedOperationException();
255: }
256: }
257:
258: /**
259: * Returns true for a switch.
260: */
261: public boolean isSwitch() {
262: switch (getOpcode()) {
263: case TABLESWITCH:
264: case LOOKUPSWITCH:
265: return true;
266: default:
267: return false;
268: }
269: }
270:
271: /**
272: * Returns the branch target.
273: */
274: public int[] getSwitchTargets() {
275: switch (getOpcode()) {
276: case TABLESWITCH: {
277: int arg = _offset + 1;
278: arg += (4 - arg % 4) % 4;
279:
280: int low = getInt(arg + 4);
281: int high = getInt(arg + 8);
282:
283: int[] targets = new int[high - low + 2];
284: targets[0] = getInt(arg) + _offset;
285:
286: for (int i = 0; i <= high - low; i++) {
287: targets[i + 1] = getInt(arg + 12 + i * 4) + _offset;
288: }
289:
290: return targets;
291: }
292:
293: case LOOKUPSWITCH: {
294: int arg = _offset + 1;
295: arg += (4 - arg % 4) % 4;
296:
297: int n = getInt(arg + 4);
298:
299: int[] targets = new int[n + 1];
300: targets[0] = getInt(arg) + _offset;
301:
302: for (int i = 0; i < n; i++) {
303: int off = arg + 8 + i * 8 + 4;
304:
305: targets[i + 1] = getInt(off) + _offset;
306: }
307:
308: return targets;
309: }
310:
311: default:
312: throw new UnsupportedOperationException("getSwitchTargets");
313: }
314: }
315:
316: /**
317: * Returns a constant pool item.
318: */
319: public ConstantPoolEntry getConstantArg() {
320: switch (getOpcode()) {
321: case LDC:
322: return _javaClass.getConstantPool().getEntry(getByteArg());
323:
324: case LDC_W:
325: return _javaClass.getConstantPool().getEntry(getShortArg());
326:
327: default:
328: throw new UnsupportedOperationException();
329: }
330: }
331:
332: /**
333: * Reads a byte argument.
334: */
335: public int getByteArg() {
336: return getCode()[_offset + 1];
337: }
338:
339: /**
340: * Gets a byte arg
341: */
342: public int getByteArg(int offset) {
343: return getByte(_offset + offset);
344: }
345:
346: /**
347: * Sets a byte value.
348: */
349: public void setByteArg(int offset, int value) {
350: getCode()[_offset + offset + 0] = (byte) value;
351: }
352:
353: /**
354: * Reads a short argument.
355: */
356: public int getShortArg() {
357: return getShort(_offset + 1);
358: }
359:
360: /**
361: * Sets a short value.
362: */
363: public int getShortArg(int offset) {
364: return getShort(_offset + offset);
365: }
366:
367: /**
368: * Sets a short value.
369: */
370: public void setShortArg(int offset, int value) {
371: setShort(_offset + offset, value);
372: }
373:
374: /**
375: * Sets a short value.
376: */
377: public void setShort(int offset, int value) {
378: byte[] code = getCode();
379:
380: code[offset + 0] = (byte) (value >> 8);
381: code[offset + 1] = (byte) (value);
382: }
383:
384: /**
385: * Reads an integer.
386: */
387: public int getIntArg() {
388: return getInt(_offset + 1);
389: }
390:
391: /**
392: * Sets a short value.
393: */
394: public void setInt(int offset, int value) {
395: byte[] code = getCode();
396:
397: code[offset + 0] = (byte) (value >> 24);
398: code[offset + 1] = (byte) (value >> 16);
399: code[offset + 2] = (byte) (value >> 8);
400: code[offset + 3] = (byte) (value);
401: }
402:
403: /**
404: * Reads a byte value.
405: */
406: public int getByte(int offset) {
407: return getCode()[offset + 0] & 0xff;
408: }
409:
410: /**
411: * Reads a short value.
412: */
413: public int getShort(int offset) {
414: int b0 = getCode()[offset + 0] & 0xff;
415: int b1 = getCode()[offset + 1] & 0xff;
416:
417: return (short) ((b0 << 8) + b1);
418: }
419:
420: /**
421: * Reads an int argument.
422: */
423: public int getInt(int offset) {
424: byte[] code = getCode();
425:
426: int b0 = code[offset + 0] & 0xff;
427: int b1 = code[offset + 1] & 0xff;
428: int b2 = code[offset + 2] & 0xff;
429: int b3 = code[offset + 3] & 0xff;
430:
431: return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3;
432: }
433:
434: /**
435: * Analyzes the code for a method
436: */
437: public void analyze(Analyzer analyzer) throws Exception {
438: analyze(analyzer, true);
439: }
440:
441: /**
442: * Analyzes the code for a method
443: */
444: public void analyze(Analyzer analyzer, boolean allowFlow)
445: throws Exception {
446: analyzeImpl(analyzer, allowFlow, new IntArray(), new IntArray());
447: }
448:
449: /**
450: * Analyzes the code for a method
451: */
452: protected void analyzeImpl(Analyzer analyzer, boolean allowFlow,
453: IntArray pendingTargets, IntArray completedTargets)
454: throws Exception {
455: setOffset(0);
456:
457: pendingTargets.add(0);
458:
459: ArrayList<CodeAttribute.ExceptionItem> exns;
460: exns = getExceptions();
461:
462: for (int i = 0; i < exns.size(); i++) {
463: CodeAttribute.ExceptionItem exn = exns.get(i);
464:
465: pendingTargets.add(exn.getHandler());
466: }
467:
468: analyze(analyzer, allowFlow, pendingTargets, completedTargets);
469: }
470:
471: /**
472: * Analyzes the code for a basic block.
473: */
474: private void analyze(Analyzer analyzer, boolean allowFlow,
475: IntArray pendingTargets, IntArray completedTargets)
476: throws Exception {
477: pending: while (pendingTargets.size() > 0) {
478: int pc = pendingTargets.pop();
479:
480: if (allowFlow) {
481: if (completedTargets.contains(pc))
482: continue pending;
483:
484: completedTargets.add(pc);
485: }
486:
487: setOffset(pc);
488:
489: flow: do {
490: pc = getOffset();
491:
492: if (pc < 0)
493: throw new IllegalStateException();
494:
495: if (!allowFlow) {
496: if (completedTargets.contains(pc))
497: break flow;
498:
499: completedTargets.add(pc);
500: }
501:
502: if (isBranch()) {
503: int targetPC = getBranchTarget();
504:
505: if (!pendingTargets.contains(targetPC))
506: pendingTargets.add(targetPC);
507: } else if (isSwitch()) {
508: int[] switchTargets = getSwitchTargets();
509:
510: for (int i = 0; i < switchTargets.length; i++) {
511: if (!pendingTargets.contains(switchTargets[i]))
512: pendingTargets.add(switchTargets[i]);
513: }
514: }
515:
516: analyzer.analyze(this );
517: } while (next());
518: }
519: }
520:
521: public static final int NOP = 0x00;
522: public static final int ACONST_NULL = 0x01;
523: public static final int ICONST_M1 = 0x02;
524: public static final int ICONST_0 = 0x03;
525: public static final int ICONST_1 = 0x04;
526: public static final int ICONST_2 = 0x05;
527: public static final int ICONST_3 = 0x06;
528: public static final int ICONST_4 = 0x07;
529: public static final int ICONST_5 = 0x08;
530: public static final int LCONST_0 = 0x09;
531: public static final int LCONST_1 = 0x0a;
532: public static final int FCONST_0 = 0x0b;
533: public static final int FCONST_1 = 0x0c;
534: public static final int FCONST_2 = 0x0d;
535: public static final int DCONST_0 = 0x0e;
536: public static final int DCONST_1 = 0x0f;
537:
538: public static final int BIPUSH = 0x10;
539: public static final int SIPUSH = 0x11;
540: public static final int LDC = 0x12;
541: public static final int LDC_W = 0x13;
542: public static final int LDC2_W = 0x14;
543: public static final int ILOAD = 0x15;
544: public static final int LLOAD = 0x16;
545: public static final int FLOAD = 0x17;
546: public static final int DLOAD = 0x18;
547: public static final int ALOAD = 0x19;
548: public static final int ILOAD_0 = 0x1a;
549: public static final int ILOAD_1 = 0x1b;
550: public static final int ILOAD_2 = 0x1c;
551: public static final int ILOAD_3 = 0x1d;
552: public static final int LLOAD_0 = 0x1e;
553: public static final int LLOAD_1 = 0x1f;
554:
555: public static final int LLOAD_2 = 0x20;
556: public static final int LLOAD_3 = 0x21;
557: public static final int FLOAD_0 = 0x22;
558: public static final int FLOAD_1 = 0x23;
559: public static final int FLOAD_2 = 0x24;
560: public static final int FLOAD_3 = 0x25;
561: public static final int DLOAD_0 = 0x26;
562: public static final int DLOAD_1 = 0x27;
563: public static final int DLOAD_2 = 0x28;
564: public static final int DLOAD_3 = 0x29;
565: public static final int ALOAD_0 = 0x2a;
566: public static final int ALOAD_1 = 0x2b;
567: public static final int ALOAD_2 = 0x2c;
568: public static final int ALOAD_3 = 0x2d;
569: public static final int IALOAD = 0x2e;
570: public static final int LALOAD = 0x2f;
571:
572: public static final int FALOAD = 0x30;
573: public static final int DALOAD = 0x31;
574: public static final int AALOAD = 0x32;
575: public static final int BALOAD = 0x33;
576: public static final int CALOAD = 0x34;
577: public static final int SALOAD = 0x35;
578: public static final int ISTORE = 0x36;
579: public static final int LSTORE = 0x37;
580: public static final int FSTORE = 0x38;
581: public static final int DSTORE = 0x39;
582: public static final int ASTORE = 0x3a;
583: public static final int ISTORE_0 = 0x3b;
584: public static final int ISTORE_1 = 0x3c;
585: public static final int ISTORE_2 = 0x3d;
586: public static final int ISTORE_3 = 0x3e;
587: public static final int LSTORE_0 = 0x3f;
588:
589: public static final int LSTORE_1 = 0x40;
590: public static final int LSTORE_2 = 0x41;
591: public static final int LSTORE_3 = 0x42;
592: public static final int FSTORE_0 = 0x43;
593: public static final int FSTORE_1 = 0x44;
594: public static final int FSTORE_2 = 0x45;
595: public static final int FSTORE_3 = 0x46;
596: public static final int DSTORE_0 = 0x47;
597: public static final int DSTORE_1 = 0x48;
598: public static final int DSTORE_2 = 0x49;
599: public static final int DSTORE_3 = 0x4a;
600: public static final int ASTORE_0 = 0x4b;
601: public static final int ASTORE_1 = 0x4c;
602: public static final int ASTORE_2 = 0x4d;
603: public static final int ASTORE_3 = 0x4e;
604: public static final int IASTORE = 0x4f;
605:
606: public static final int LASTORE = 0x50;
607: public static final int FASTORE = 0x51;
608: public static final int DASTORE = 0x52;
609: public static final int AASTORE = 0x53;
610: public static final int BASTORE = 0x54;
611: public static final int CASTORE = 0x55;
612: public static final int SASTORE = 0x56;
613: public static final int POP = 0x57;
614: public static final int POP2 = 0x58;
615: public static final int DUP = 0x59;
616: public static final int DUP_X1 = 0x5a;
617: public static final int DUP_X2 = 0x5b;
618: public static final int DUP2 = 0x5c;
619: public static final int DUP2_X1 = 0x5d;
620: public static final int DUP2_X2 = 0x5e;
621: public static final int SWAP = 0x5f;
622:
623: public static final int IADD = 0x60;
624: public static final int LADD = 0x61;
625: public static final int FADD = 0x62;
626: public static final int DADD = 0x63;
627: public static final int ISUB = 0x64;
628: public static final int LSUB = 0x65;
629: public static final int FSUB = 0x66;
630: public static final int DSUB = 0x67;
631: public static final int IMUL = 0x68;
632: public static final int LMUL = 0x69;
633: public static final int FMUL = 0x6a;
634: public static final int DMUL = 0x6b;
635: public static final int IDIV = 0x6c;
636: public static final int LDIV = 0x6d;
637: public static final int FDIV = 0x6e;
638: public static final int DDIV = 0x6f;
639:
640: public static final int IREM = 0x70;
641: public static final int LREM = 0x71;
642: public static final int FREM = 0x72;
643: public static final int DREM = 0x73;
644: public static final int INEG = 0x74;
645: public static final int LNEG = 0x75;
646: public static final int FNEG = 0x76;
647: public static final int DNEG = 0x77;
648: public static final int ISHL = 0x78;
649: public static final int LSHL = 0x79;
650: public static final int ISHR = 0x7a;
651: public static final int LSHR = 0x7b;
652: public static final int IUSHR = 0x7c;
653: public static final int LUSHR = 0x7d;
654: public static final int IAND = 0x7e;
655: public static final int LAND = 0x7f;
656:
657: public static final int IOR = 0x80;
658: public static final int LOR = 0x81;
659: public static final int IXOR = 0x82;
660: public static final int LXOR = 0x83;
661: public static final int IINC = 0x84;
662: public static final int I2L = 0x85;
663: public static final int I2F = 0x86;
664: public static final int I2D = 0x87;
665: public static final int L2I = 0x88;
666: public static final int L2F = 0x89;
667: public static final int L2D = 0x8a;
668: public static final int F2I = 0x8b;
669: public static final int F2L = 0x8c;
670: public static final int F2D = 0x8d;
671: public static final int D2I = 0x8e;
672: public static final int D2L = 0x8f;
673:
674: public static final int D2F = 0x90;
675: public static final int I2B = 0x91;
676: public static final int I2C = 0x92;
677: public static final int I2S = 0x93;
678: public static final int LCMP = 0x94;
679: public static final int FCMPL = 0x95;
680: public static final int FCMPG = 0x96;
681: public static final int DCMPL = 0x97;
682: public static final int DCMPG = 0x98;
683: public static final int IFEQ = 0x99;
684: public static final int IFNE = 0x9a;
685: public static final int IFLT = 0x9b;
686: public static final int IFGE = 0x9c;
687: public static final int IFGT = 0x9d;
688: public static final int IFLE = 0x9e;
689: public static final int IF_ICMPEQ = 0x9f;
690:
691: public static final int IF_ICMPNE = 0xa0;
692: public static final int IF_ICMPLT = 0xa1;
693: public static final int IF_ICMPGE = 0xa2;
694: public static final int IF_ICMPGT = 0xa3;
695: public static final int IF_ICMPLE = 0xa4;
696: public static final int IF_ACMPEQ = 0xa5;
697: public static final int IF_ACMPNE = 0xa6;
698: public static final int GOTO = 0xa7;
699: public static final int JSR = 0xa8;
700: public static final int RET = 0xa9;
701: public static final int TABLESWITCH = 0xaa;
702: public static final int LOOKUPSWITCH = 0xab;
703: public static final int IRETURN = 0xac;
704: public static final int LRETURN = 0xad;
705: public static final int FRETURN = 0xae;
706: public static final int DRETURN = 0xaf;
707:
708: public static final int ARETURN = 0xb0;
709: public static final int RETURN = 0xb1;
710: public static final int GETSTATIC = 0xb2;
711: public static final int PUTSTATIC = 0xb3;
712: public static final int GETFIELD = 0xb4;
713: public static final int PUTFIELD = 0xb5;
714: public static final int INVOKEVIRTUAL = 0xb6;
715: public static final int INVOKESPECIAL = 0xb7;
716: public static final int INVOKESTATIC = 0xb8;
717: public static final int INVOKEINTERFACE = 0xb9;
718: public static final int RESERVED_0 = 0xba;
719: public static final int NEW = 0xbb;
720: public static final int NEWARRAY = 0xbc;
721: public static final int ANEWARRAY = 0xbd;
722: public static final int ARRAYLENGTH = 0xbe;
723: public static final int ATHROW = 0xbf;
724:
725: public static final int CHECKCAST = 0xc0;
726: public static final int INSTANCEOF = 0xc1;
727: public static final int MONITORENTER = 0xc2;
728: public static final int MONITOREXIT = 0xc3;
729: public static final int WIDE = 0xc4;
730: public static final int MULTIANEWARRAY = 0xc5;
731: public static final int IFNULL = 0xc6;
732: public static final int IFNONNULL = 0xc7;
733: public static final int GOTO_W = 0xc8;
734: public static final int JSR_W = 0xc9;
735:
736: // the reset are reserved
737:
738: private static final int OP_LEN[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
739: 0, 0, 0, 0, 0, 0, /* 00 */
740: 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 10 */
741: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 */
742: 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 30 */
743:
744: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 */
745: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50 */
746: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 */
747: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70 */
748:
749: 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 */
750: 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, /* 90 */
751: 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 99, 99, 0, 0, 0, 0, /* a0 */
752: 0, 0, 2, 2, 2, 2, 2, 2, 2, 4, -1, 2, 1, 2, 0, 0, /* b0 */
753:
754: 2, 2, 0, 0, 99, 3, 2, 2, 4, 4, -1, -1, -1, -1, -1, -1, /* c0 */
755: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
756: -1, /* d0 */
757: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
758: -1, /* e0 */
759: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
760: -1, /* f0 */
761: };
762: }
|