01: /*
02: * CallNodeCompiler.java
03: *
04: * Created on January 3, 2007, 4:11 PM
05: *
06: * To change this template, choose Tools | Template Manager
07: * and open the template in the editor.
08: */
09:
10: package org.jruby.compiler;
11:
12: import org.jruby.ast.CallNode;
13: import org.jruby.ast.IterNode;
14: import org.jruby.ast.Node;
15: import org.jruby.runtime.CallType;
16:
17: /**
18: *
19: * @author headius
20: */
21: public class CallNodeCompiler implements NodeCompiler {
22:
23: /** Creates a new instance of CallNodeCompiler */
24: public CallNodeCompiler() {
25: }
26:
27: public void compile(Node node, Compiler context) {
28: context.lineNumber(node.getPosition());
29:
30: CallNode callNode = (CallNode) node;
31:
32: if (NodeCompilerFactory.SAFE) {
33: if (NodeCompilerFactory.UNSAFE_CALLS.contains(callNode
34: .getName())) {
35: throw new NotCompilableException(
36: "Can't compile call safely: " + node);
37: }
38: }
39:
40: if (callNode.getIterNode() == null) {
41: // no block, go for simple version
42:
43: // handle receiver
44: NodeCompilerFactory.getCompiler(callNode.getReceiverNode())
45: .compile(callNode.getReceiverNode(), context);
46:
47: if (callNode.getArgsNode() != null) {
48: // args compiler processes args and results in an args array for invocation
49: NodeCompiler argsCompiler = NodeCompilerFactory
50: .getArgumentsCompiler(callNode.getArgsNode());
51:
52: argsCompiler.compile(callNode.getArgsNode(), context);
53:
54: context.invokeDynamic(callNode.getName(), true, true,
55: CallType.NORMAL, null, false);
56: } else {
57: context.invokeDynamic(callNode.getName(), true, false,
58: CallType.NORMAL, null, false);
59: }
60: } else {
61: // FIXME: Missing blockpassnode handling
62: final IterNode iterNode = (IterNode) callNode.getIterNode();
63:
64: final ClosureCallback closureArg = new ClosureCallback() {
65: public void compile(Compiler context) {
66: NodeCompilerFactory.getCompiler(iterNode).compile(
67: iterNode, context);
68: }
69: };
70:
71: // handle receiver
72: NodeCompilerFactory.getCompiler(callNode.getReceiverNode())
73: .compile(callNode.getReceiverNode(), context);
74:
75: if (callNode.getArgsNode() != null) {
76: // args compiler processes args and results in an args array for invocation
77: NodeCompiler argsCompiler = NodeCompilerFactory
78: .getArgumentsCompiler(callNode.getArgsNode());
79:
80: argsCompiler.compile(callNode.getArgsNode(), context);
81:
82: context.invokeDynamic(callNode.getName(), true, true,
83: CallType.NORMAL, closureArg, false);
84: } else {
85: context.invokeDynamic(callNode.getName(), true, false,
86: CallType.NORMAL, closureArg, false);
87: }
88: }
89: }
90:
91: }
|