001: /*
002: * $Id: InlinedCallNode.java,v 1.6 2002/09/16 08:05:04 jkl Exp $
003: *
004: * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
005: *
006: * Use is subject to license terms, as defined in
007: * Anvil Sofware License, Version 1.1. See LICENSE
008: * file, or http://njet.org/license-1.1.txt
009: */
010: package anvil.script.expression;
011:
012: import anvil.core.Any;
013: import anvil.ErrorListener;
014: import anvil.script.CompilableFunction;
015: import anvil.codec.Code;
016: import anvil.codec.ConstantPool;
017: import anvil.script.Grammar;
018: import anvil.script.compiler.ByteCompiler;
019: import anvil.script.Context;
020: import anvil.script.Type;
021: import anvil.script.statements.FunctionStatement;
022: import java.io.IOException;
023:
024: /**
025: * class InlinedCallNode
026: *
027: * @author: Jani Lehtimäki
028: */
029: public class InlinedCallNode extends MultiParent {
030:
031: protected FunctionStatement _context;
032: protected FunctionStatement _function;
033:
034: public InlinedCallNode(FunctionStatement context,
035: FunctionStatement function, Parent parameters) {
036: super (parameters);
037: _context = context;
038: _function = function;
039: }
040:
041: public int typeOf() {
042: return Node.EXPR_CALL;
043: }
044:
045: public boolean isConstant() {
046: return false;
047: }
048:
049: public Node optimize() {
050: optimizeChilds();
051: return this ;
052: }
053:
054: private static final String[] SIGNATURES_SELF = {
055: "(Lanvil/core/Any;Lanvil/script/Function;Lanvil/script/StackFrame;)Lanvil/core/Any;",
056: "(Lanvil/core/Any;Lanvil/script/Function;Lanvil/script/StackFrame;Lanvil/core/Any;)Lanvil/core/Any;",
057: "(Lanvil/core/Any;Lanvil/script/Function;Lanvil/script/StackFrame;Lanvil/core/Any;Lanvil/core/Any;)Lanvil/core/Any;",
058: "(Lanvil/core/Any;Lanvil/script/Function;Lanvil/script/StackFrame;Lanvil/core/Any;Lanvil/core/Any;Lanvil/core/Any;)Lanvil/core/Any;",
059: "(Lanvil/core/Any;Lanvil/script/Function;Lanvil/script/StackFrame;Lanvil/core/Any;Lanvil/core/Any;Lanvil/core/Any;Lanvil/core/Any;)Lanvil/core/Any;" };
060:
061: private static final String[] SIGNATURES_NO_SELF = {
062: "(Lanvil/script/Function;Lanvil/script/StackFrame;)Lanvil/core/Any;",
063: "(Lanvil/script/Function;Lanvil/script/StackFrame;Lanvil/core/Any;)Lanvil/core/Any;",
064: "(Lanvil/script/Function;Lanvil/script/StackFrame;Lanvil/core/Any;Lanvil/core/Any;)Lanvil/core/Any;",
065: "(Lanvil/script/Function;Lanvil/script/StackFrame;Lanvil/core/Any;Lanvil/core/Any;Lanvil/core/Any;)Lanvil/core/Any;",
066: "(Lanvil/script/Function;Lanvil/script/StackFrame;Lanvil/core/Any;Lanvil/core/Any;Lanvil/core/Any;Lanvil/core/Any;)Lanvil/core/Any;" };
067:
068: public void compile(ByteCompiler context, int operation) {
069: Code code = context.getCode();
070: ConstantPool pool = code.getPool();
071: boolean inClass = (_function.getType() != Type.FUNCTION);
072:
073: code.aload_first();
074: if (inClass) {
075: code.self();
076: }
077:
078: int parent = _function.getParent().getTypeRef(pool);
079: String name = (inClass ? "m_" : "f_") + _function.getName();
080: int field = pool.addFieldRef(parent, name,
081: "Lanvil/script/Function;");
082: code.getstatic(field);
083:
084: int depth = Grammar.countEscapeDepth(_context, _function);
085: code.aload(_context.getFrameIndex());
086: if (depth >= 0) {
087: code.iconst(depth + 1);
088: code.invokevirtual(pool.addMethodRef(
089: "anvil/script/StackFrame", "getEscape",
090: "(I)Lanvil/script/StackFrame;"));
091: }
092:
093: int n = childs();
094: if (!hasSplices() && n <= 4) {
095: for (int i = 0; i < n; i++) {
096: getChild(i).compile(context, GET);
097: }
098: code.invokevirtual(pool.addMethodRef(context.TYPE_CONTEXT,
099: "exec", inClass ? SIGNATURES_SELF[n]
100: : SIGNATURES_NO_SELF[n]));
101:
102: } else {
103: context.compileArgumentList(getChilds(0));
104: code
105: .invokevirtual(pool
106: .addMethodRef(
107: context.TYPE_CONTEXT,
108: "exec",
109: inClass ? "(Lanvil/core/Any;Lanvil/script/Function;Lanvil/script/StackFrame;[Lanvil/core/Any;)Lanvil/core/Any;"
110: : "(Lanvil/script/Function;Lanvil/script/StackFrame;[Lanvil/core/Any;)Lanvil/core/Any;"));
111:
112: }
113:
114: if (operation == GET_BOOLEAN) {
115: context.any2boolean();
116: }
117: }
118:
119: }
|