Source Code Cross Referenced for PrimProcedure.java in  » Scripting » Nice » gnu » expr » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » Nice » gnu.expr 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        // Copyright (c) 1999, 2000  Per M.A. Bothner.
002:        // This is free software;  for terms and warranty disclaimer see ./COPYING.
003:
004:        package gnu.expr;
005:
006:        import gnu.bytecode.*;
007:        import java.util.Hashtable;
008:        import gnu.mapping.*;
009:
010:        /** A primitive Procedure implemented by a plain Java method. */
011:
012:        public class PrimProcedure extends MethodProc implements 
013:                gnu.expr.Inlineable {
014:            Type retType;
015:            Type[] argTypes;
016:            Method method;
017:            int op_code;
018:
019:            /** If non-null, the LambdaExp that this PrimProcedure implements. */
020:            LambdaExp source;
021:
022:            java.lang.reflect.Member member;
023:
024:            public final int opcode() {
025:                return op_code;
026:            }
027:
028:            public Type getReturnType() {
029:                return retType;
030:            }
031:
032:            public void setReturnType(Type retType) {
033:                this .retType = retType;
034:            }
035:
036:            public Type getReturnType(Expression[] args) {
037:                return retType;
038:            }
039:
040:            /** Return true iff the last parameter is a "rest" argument. */
041:            public boolean takesVarArgs() {
042:                return method != null && method.getName().endsWith("$V");
043:            }
044:
045:            public int numArgs() {
046:                int num = argTypes.length;
047:                if (!getStaticFlag())
048:                    num++;
049:                return takesVarArgs() ? (num - 1) + (-1 << 12) : num
050:                        + (num << 12);
051:            }
052:
053:            public int match(CallContext ctx, Object[] args) {
054:                ctx.setArgsN(args);
055:
056:                int nargs = ctx.count;
057:                boolean takesVarArgs = takesVarArgs();
058:                int mlength = minArgs() + (takesVarArgs ? 1 : 0);
059:                int fixArgs = takesVarArgs ? mlength - 1 : mlength;
060:
061:                if (takesVarArgs) {
062:                    if (nargs < fixArgs)
063:                        return NO_MATCH_TOO_FEW_ARGS | fixArgs;
064:                } else {
065:                    if (nargs != mlength)
066:                        if (nargs < mlength)
067:                            return NO_MATCH_TOO_FEW_ARGS | fixArgs;
068:                        else
069:                            return NO_MATCH_TOO_MANY_ARGS | fixArgs;
070:                }
071:                int arg_count = argTypes.length;
072:                Type elementType = null;
073:                Object[] restArray = null;
074:                int this _count = getStaticFlag() ? 0 : 1;
075:                Object[] rargs = new Object[mlength - this _count];
076:                Object this Value;
077:                if (takesVarArgs) {
078:                    Type restType = argTypes[arg_count - 1];
079:                    if (restType == Compilation.scmListType) { // FIXME
080:                        rargs[rargs.length - 1] = gnu.lists.LList.makeList(
081:                                args, fixArgs);
082:                        nargs = fixArgs;
083:                    } else {
084:                        ArrayType restArrayType = (ArrayType) restType;
085:                        elementType = restArrayType.getComponentType();
086:                        Class elementClass = elementType.getReflectClass();
087:                        restArray = (Object[]) java.lang.reflect.Array
088:                                .newInstance(elementClass, nargs - fixArgs);
089:                        rargs[rargs.length - 1] = restArray;
090:                    }
091:                }
092:                if (this _count != 0)
093:                    this Value = method.getDeclaringClass().coerceFromObject(
094:                            ctx.getArgAsObject(0));
095:                else
096:                    this Value = null;
097:                for (int i = this _count; i < nargs; i++) {
098:                    try {
099:                        Object arg = ctx.getArgAsObject(i);
100:                        Type type = i < fixArgs ? argTypes[i - this _count]
101:                                : elementType;
102:                        if (type != Type.pointer_type)
103:                            arg = type.coerceFromObject(arg);
104:                        if (i < fixArgs)
105:                            rargs[i - this _count] = arg;
106:                        else
107:                            restArray[i - fixArgs] = arg;
108:                    } catch (ClassCastException ex) {
109:                        return NO_MATCH_BAD_TYPE | i;
110:                    }
111:                }
112:                ctx.value1 = this Value;
113:                ctx.value2 = rargs;
114:                return 0;
115:            }
116:
117:            public Object applyV(CallContext ctx) throws Throwable {
118:                int arg_count = argTypes.length;
119:                boolean is_constructor = op_code == 183;
120:                boolean is_static = getStaticFlag();
121:
122:                try {
123:                    if (member == null) {
124:                        Class clas = method.getDeclaringClass()
125:                                .getReflectClass();
126:                        Class[] paramTypes = new Class[arg_count];
127:                        for (int i = arg_count; --i >= 0;)
128:                            paramTypes[i] = argTypes[i].getReflectClass();
129:                        if (is_constructor)
130:                            member = clas.getConstructor(paramTypes);
131:                        else
132:                            member = clas.getMethod(method.getName(),
133:                                    paramTypes);
134:                    }
135:                    Object[] rargs = (Object[]) ctx.value2;
136:                    if (is_constructor)
137:                        return ((java.lang.reflect.Constructor) member)
138:                                .newInstance(rargs);
139:                    else {
140:                        java.lang.reflect.Method meth = (java.lang.reflect.Method) member;
141:                        Object result = meth.invoke(ctx.value1, rargs);
142:                        return retType.coerceToObject(result);
143:                    }
144:                } catch (java.lang.reflect.InvocationTargetException ex) {
145:                    throw ex.getTargetException();
146:                }
147:            }
148:
149:            public PrimProcedure(java.lang.reflect.Method method,
150:                    Class this Class, Class[] parameterClasses,
151:                    Interpreter interpreter) {
152:                Type[] parameterTypes = new Type[parameterClasses.length];
153:                Type[] implParameterTypes = new Type[parameterClasses.length];
154:                for (int i = parameterClasses.length; --i >= 0;) {
155:                    Type ptype = interpreter.getTypeFor(parameterClasses[i]);
156:                    parameterTypes[i] = ptype;
157:                    implParameterTypes[i] = ptype.getImplementationType();
158:                }
159:                Type returnType = interpreter
160:                        .getTypeFor(method.getReturnType());
161:                Type implReturnType = returnType.getImplementationType();
162:                ClassType this Type = (ClassType) interpreter
163:                        .getTypeFor(this Class);
164:                Method meth = this Type.addMethod(method.getName(), method
165:                        .getModifiers(), implParameterTypes, implReturnType);
166:                init(meth);
167:                argTypes = parameterTypes;
168:                retType = op_code == 183 ? meth.getDeclaringClass()
169:                        : returnType;
170:            }
171:
172:            public PrimProcedure(java.lang.reflect.Method method,
173:                    Interpreter interpreter) {
174:                this (method, method.getDeclaringClass(), method
175:                        .getParameterTypes(), interpreter);
176:            }
177:
178:            public PrimProcedure(Method method) {
179:                init(method);
180:            }
181:
182:            public PrimProcedure(Method method,
183:                    java.util.Stack[] parameterCopies) {
184:                init(method);
185:                this .parameterCopies = parameterCopies;
186:            }
187:
188:            private java.util.Stack[] parameterCopies;
189:
190:            public PrimProcedure(Method method, Interpreter interpreter) {
191:                init(method);
192:
193:                // This stuff deals with that a language may have its own mapping
194:                // from Java types to language types, for coercions and other reasons.
195:                Type[] pTypes = method.getParameterTypes();
196:                int nTypes = pTypes.length;
197:                argTypes = null;
198:                for (int i = nTypes; --i >= 0;) {
199:                    Type javaType = pTypes[i];
200:                    Type langType = interpreter.getTypeFor(javaType
201:                            .getReflectClass());
202:                    if (javaType != langType) {
203:                        if (argTypes == null) {
204:                            argTypes = new Type[nTypes];
205:                            System.arraycopy(pTypes, 0, argTypes, 0, nTypes);
206:                        }
207:                        argTypes[i] = langType;
208:                    }
209:                }
210:                if (argTypes == null)
211:                    argTypes = pTypes;
212:                retType = op_code == 183 ? method.getDeclaringClass()
213:                        : interpreter.getTypeFor(method.getReturnType()
214:                                .getReflectClass());
215:            }
216:
217:            private boolean isConstructor() {
218:                return "<init>".equals(method.getName());
219:            }
220:
221:            private void init(Method method) {
222:                this .method = method;
223:                this .argTypes = method.getParameterTypes();
224:                this .retType = method.getReturnType();
225:                int flags = method.getModifiers();
226:                if ((flags & Access.STATIC) != 0)
227:                    this .op_code = 184; // invokestatic
228:                else {
229:                    ClassType mclass = method.getDeclaringClass();
230:                    if ((mclass.getModifiers() & Access.INTERFACE) != 0)
231:                        this .op_code = 185; // invokeinterface
232:                    else if ("<init>".equals(method.getName())) {
233:                        this .op_code = 183; // invokespecial
234:                        this .retType = mclass;
235:                    } else
236:                        this .op_code = 182; // invokevirtual
237:                }
238:            }
239:
240:            public static PrimProcedure specialCall(Method method) {
241:                PrimProcedure res = new PrimProcedure(method);
242:                res.op_code = 183;
243:                return res;
244:            }
245:
246:            public PrimProcedure(Method method, LambdaExp source) {
247:                this (method);
248:                this .source = source;
249:            }
250:
251:            public PrimProcedure(int opcode, Type retType, Type[] argTypes) {
252:                this .op_code = opcode;
253:                this .retType = retType;
254:                this .argTypes = argTypes;
255:            }
256:
257:            public static PrimProcedure makeBuiltinBinary(int opcode, Type type) {
258:                // FIXME - should cache!
259:                Type[] args = new Type[2];
260:                args[0] = type;
261:                args[1] = type;
262:                return new PrimProcedure(opcode, type, args);
263:            }
264:
265:            public PrimProcedure(int op_code, ClassType classtype, String name,
266:                    Type retType, Type[] argTypes) {
267:                this .op_code = op_code;
268:                if (op_code == 185) // invokeinterface
269:                    classtype.access_flags |= Access.INTERFACE;
270:
271:                method = classtype.getDeclaredMethod(name, argTypes, retType);
272:
273:                if (method == null)
274:                    method = classtype.addMethod(name,
275:                            op_code == 184 ? Access.STATIC : 0, argTypes,
276:                            retType);
277:                else if ((op_code == 184) != method.getStaticFlag())
278:                    throw new Error("Method " + method + " should "
279:                            + (op_code == 184 ? "" : "not ") + "be static");
280:
281:                this .retType = retType;
282:                this .argTypes = argTypes;
283:            }
284:
285:            /** Use to compile new followed by constructor. */
286:            public PrimProcedure(ClassType classtype, Type[] argTypes) {
287:                this (183, classtype, "<init>", Type.void_type, argTypes);
288:                this .retType = classtype;
289:            }
290:
291:            public final boolean getStaticFlag() {
292:                return method == null || method.getStaticFlag()
293:                        || isConstructor();
294:            }
295:
296:            public final Type[] getParameterTypes() {
297:                return argTypes;
298:            }
299:
300:            public static void compileArgs(Expression[] args, Type this Type,
301:                    Type[] argTypes, boolean variable, String name,
302:                    LambdaExp source, Compilation comp) {
303:                compileArgs(args, this Type, argTypes, variable, name, source,
304:                        comp, source == null ? null : source.parameterCopies);
305:            }
306:
307:            /** Compile arguments and push unto stack.
308:             * @param args arguments to evaluate and push.
309:             * @param thisType If we are calling a non-static function,
310:             *   then args[0] is the receiver and thisType is its expected class.
311:             *   If thisType==Type.void_type, ignore argTypes[0].  (It is used to to
312:             *   pass a link to a closure environment, which was pushed by our caller.)
313:             *   If this_type==null, no special handling of args[0] or argTypes[0].
314:             */
315:            public static void compileArgs(Expression[] args, Type this Type,
316:                    Type[] argTypes, boolean variable, String name,
317:                    LambdaExp source, Compilation comp,
318:                    java.util.Stack[] parameterCopies) {
319:                Type arg_type = null;
320:                gnu.bytecode.CodeAttr code = comp.getCode();
321:                int skipArg = this Type == Type.void_type ? 1 : 0;
322:                int arg_count = argTypes.length - skipArg;
323:                boolean is_static = this Type == null || skipArg != 0;
324:                int fix_arg_count = variable ? arg_count - (is_static ? 1 : 2)
325:                        : args.length;
326:                Declaration argDecl = source == null ? null : source
327:                        .firstDecl();
328:
329:                Scope scope;
330:                if (parameterCopies == null)
331:                    scope = null;
332:                else
333:                    scope = code.pushScope();
334:
335:                for (int i = 0;; ++i) {
336:                    if (variable && i == fix_arg_count) {
337:                        arg_type = argTypes[arg_count - 1 + skipArg];
338:                        /*
339:                        if (arg_type == Compilation.scmListType)
340:                          {
341:                        gnu.kawa.functions.MakeList.compile(args, i, comp);
342:                        break;
343:                          }
344:                         */
345:                        code.emitPushInt(args.length - fix_arg_count);
346:                        arg_type = ((ArrayType) arg_type).getComponentType();
347:                        code.emitNewArray(arg_type);
348:                    }
349:                    if (i >= args.length)
350:                        break;
351:                    if (i >= fix_arg_count) {
352:                        code.emitDup(1); // dup array.
353:                        code.emitPushInt(i - fix_arg_count);
354:                    } else
355:                        arg_type = argDecl != null && (is_static || i > 0) ? argDecl
356:                                .getType()
357:                                : is_static ? argTypes[i + skipArg]
358:                                        : i == 0 ? this Type : argTypes[i - 1];
359:                    Target target = StackTarget.getInstance(arg_type);
360:                    args[i].compileNotePosition(comp, target);
361:                    if (parameterCopies != null && parameterCopies[i] != null) {
362:                        Variable value = scope.addVariable(code, target
363:                                .getType(), argDecl != null ? argDecl.getName()
364:                                : "l_" + i);
365:                        parameterCopies[i].push(value);
366:                        code.emitDup();
367:                        code.emitStore(value);
368:                    }
369:                    if (i >= fix_arg_count)
370:                        code.emitArrayStore(arg_type);
371:                    if (argDecl != null && (is_static || i > 0))
372:                        argDecl = argDecl.nextDecl();
373:                }
374:
375:                // Restore the state of the captured parameters,
376:                // so that a subsequent after a nested call use is possible.
377:                if (parameterCopies != null)
378:                    for (int i = 0; i < arg_count; i++)
379:                        if (parameterCopies[i] != null)
380:                            parameterCopies[i].pop();
381:
382:                if (scope != null)
383:                    code.popScope();
384:            }
385:
386:            public void compile(ApplyExp exp, Compilation comp, Target target) {
387:                gnu.bytecode.CodeAttr code = comp.getCode();
388:
389:                if (isConstructor()) {
390:                    ClassType type = method.getDeclaringClass();
391:                    code.emitNew(type);
392:                    code.emitDup(type);
393:                }
394:
395:                Expression[] args = exp.getArgs();
396:                String arg_error = WrongArguments.checkArgCount(this ,
397:                        args.length);
398:                if (arg_error != null)
399:                    comp.error('e', arg_error);
400:
401:                try {
402:                    compile(
403:                            getStaticFlag() ? null : method.getDeclaringClass(),
404:                            args, comp, target);
405:                } catch (VerificationError e) {
406:                    throw bossa.util.User.error(bossa.util.Location.make(exp),
407:                            e.getMessage());
408:                }
409:            }
410:
411:            public void compile(Type this Type, Expression[] args,
412:                    Compilation comp, Target target) {
413:                gnu.bytecode.CodeAttr code = comp.getCode();
414:                compileArgs(args, this Type, argTypes, takesVarArgs(),
415:                        getName(), source, comp, parameterCopies);
416:
417:                if (method == null)
418:                    code.emitPrimop(opcode(), args.length, retType);
419:                else
420:                    code.emitInvokeMethod(method, opcode());
421:                target.compileFromStack(comp, retType);
422:            }
423:
424:            public Type getParameterType(int index) {
425:                if (!getStaticFlag()) {
426:                    if (index == 0)
427:                        return method.getDeclaringClass();
428:                    index--;
429:                }
430:                int lenTypes = argTypes.length;
431:                if (index < lenTypes - 1)
432:                    return argTypes[index];
433:                boolean varArgs = takesVarArgs();
434:                if (index < lenTypes && !varArgs)
435:                    return argTypes[index];
436:                // if (! varArgs) ERROR;
437:                return ((ArrayType) argTypes[lenTypes - 1]).getComponentType();
438:            }
439:
440:            // This is null in JDK 1.1 and something else in JDK 1.2.
441:            private static ClassLoader systemClassLoader = PrimProcedure.class
442:                    .getClassLoader();
443:
444:            public static PrimProcedure getMethodFor(Procedure pproc,
445:                    Expression[] args) {
446:                return getMethodFor(pproc, null, args, Interpreter
447:                        .getInterpreter());
448:            }
449:
450:            /** Search for a matching static method in a procedure's class.
451:             * @return a PrimProcedure that is suitable, or null. */
452:            public static PrimProcedure getMethodFor(Procedure pproc,
453:                    Declaration decl, Expression[] args, Interpreter interpreter) {
454:                Class pclass = getProcedureClass(pproc);
455:                if (pclass == null)
456:                    return null;
457:                return getMethodFor(pclass, pproc.getName(), decl, args,
458:                        interpreter);
459:            }
460:
461:            public static Class getProcedureClass(Object pproc) {
462:                Class procClass;
463:                if (pproc instanceof  gnu.expr.ModuleMethod)
464:                    procClass = ((ModuleMethod) pproc).module.getClass();
465:                else
466:                    procClass = pproc.getClass();
467:                try {
468:                    if (procClass.getClassLoader() == systemClassLoader)
469:                        return procClass;
470:                } catch (SecurityException ex) {
471:                }
472:                return null;
473:            }
474:
475:            /** Get PrimProcedure for matching method in given class. */
476:            public static PrimProcedure getMethodFor(Class procClass,
477:                    String name, Declaration decl, Expression[] args,
478:                    Interpreter interpreter) {
479:                try {
480:                    java.lang.reflect.Method[] meths = procClass
481:                            .getDeclaredMethods();
482:                    java.lang.reflect.Method best = null;
483:                    Class[] bestTypes = null;
484:                    if (name == null)
485:                        return null;
486:                    String mangledName = decl == null || decl.field == null ? Compilation
487:                            .mangleName(name)
488:                            : decl.field.getName();
489:                    String mangledNameV = mangledName + "$V";
490:                    for (int i = meths.length; --i >= 0;) {
491:                        java.lang.reflect.Method meth = meths[i];
492:                        int mods = meth.getModifiers();
493:                        if ((mods & (Access.STATIC | Access.PUBLIC)) != (Access.STATIC | Access.PUBLIC)) {
494:                            if (decl == null || decl.base == null)
495:                                continue;
496:                        }
497:                        String mname = meth.getName();
498:                        boolean variable;
499:                        if (mname.equals("apply") || mname.equals(mangledName))
500:                            variable = false;
501:                        else if (mname.equals("apply$V")
502:                                || mname.equals(mangledNameV))
503:                            variable = true;
504:                        else
505:                            continue;
506:                        Class[] ptypes = meth.getParameterTypes();
507:                        if (variable ? ptypes.length - 1 > args.length
508:                                : ptypes.length != args.length)
509:                            continue;
510:                        // In the future, we may try to find the "best" match.
511:                        if (best != null)
512:                            return null;
513:                        best = meth;
514:                        bestTypes = ptypes;
515:                    }
516:                    if (best != null) {
517:                        PrimProcedure prproc = new PrimProcedure(best,
518:                                procClass, bestTypes, interpreter);
519:                        prproc.setName(name);
520:                        return prproc;
521:                    }
522:                } catch (SecurityException ex) {
523:                }
524:                return null;
525:            }
526:
527:            public String getName() {
528:                String name = super .getName();
529:                if (name != null)
530:                    return name;
531:                name = getVerboseName();
532:                setName(name);
533:                return name;
534:            }
535:
536:            public String getVerboseName() {
537:                StringBuffer buf = new StringBuffer(100);
538:                if (method == null) {
539:                    buf.append("<op ");
540:                    buf.append(op_code);
541:                    buf.append('>');
542:                } else {
543:                    buf.append(method.getDeclaringClass().getName());
544:                    buf.append('.');
545:                    buf.append(method.getName());
546:                }
547:                buf.append('(');
548:                for (int i = 0; i < argTypes.length; i++) {
549:                    if (i > 0)
550:                        buf.append(',');
551:                    buf.append(argTypes[i].getName());
552:                }
553:                buf.append(')');
554:                return buf.toString();
555:            }
556:
557:            public String toString() {
558:                StringBuffer buf = new StringBuffer(100);
559:                buf.append(retType.getName());
560:                buf.append(' ');
561:                buf.append(getVerboseName());
562:                return buf.toString();
563:            }
564:
565:            public void print(java.io.PrintWriter ps) {
566:                ps.print("#<primitive procedure ");
567:                ps.print(toString());
568:                ps.print('>');
569:            }
570:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.