function.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 385 行
JAVA
385 行
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */package com.caucho.quercus.program;import com.caucho.quercus.Location;import com.caucho.quercus.env.Env;import com.caucho.quercus.env.NullThisValue;import com.caucho.quercus.env.NullValue;import com.caucho.quercus.env.UnsetValue;import com.caucho.quercus.env.Value;import com.caucho.quercus.env.Var;import com.caucho.quercus.expr.Expr;import com.caucho.quercus.expr.ExprFactory;import com.caucho.util.L10N;import java.util.ArrayList;import java.util.HashMap;import java.util.logging.Logger;/** * Represents sequence of statements. */public class Function extends AbstractFunction { private static final Logger log = Logger.getLogger(Function.class.getName()); private static final L10N L = new L10N(Function.class); protected final FunctionInfo _info; protected final boolean _isReturnsReference; protected final String _name; protected final Arg []_args; protected final Statement _statement; protected boolean _isStatic = true; protected boolean _hasReturn; Function(Location location, String name, FunctionInfo info, Arg []args, Statement []statements) { super(location); _name = name.intern(); _info = info; _info.setFunction(this); _isReturnsReference = info.isReturnsReference(); _args = args; _statement = new BlockStatement(location, statements); setGlobal(info.isPageStatic()); } public Function(ExprFactory exprFactory, Location location, String name, FunctionInfo info, Arg []args, Statement []statements) { super(location); _name = name.intern(); _info = info; _info.setFunction(this); _isReturnsReference = info.isReturnsReference(); _args = new Arg[args.length]; System.arraycopy(args, 0, _args, 0, args.length); _statement = exprFactory.createBlock(location, statements); setGlobal(info.isPageStatic()); } /** * Returns the name. */ public String getName() { return _name; } /* * Returns the declaring class */ @Override public ClassDef getDeclaringClass() { return _info.getDeclaringClass(); } /* * Returns the declaring class */ @Override public String getDeclaringClassName() { ClassDef declaringClass = _info.getDeclaringClass(); if (declaringClass != null) return declaringClass.getName(); else return null; } /** * Returns the args. */ public Arg []getArgs() { return _args; } public void setStatic(boolean isStatic) { _isStatic = isStatic; } @Override public boolean isStatic() { return _isStatic; } public boolean isObjectMethod() { return false; } /** * True for a returns reference. */ public boolean isReturnsReference() { return _isReturnsReference; } public Value execute(Env env) { return null; } /** * Evaluates a function's argument, handling ref vs non-ref */ @Override public Value []evalArguments(Env env, Expr fun, Expr []args) { Value []values = new Value[args.length]; for (int i = 0; i < args.length; i++) { Arg arg = null; if (i < _args.length) arg = _args[i]; if (arg == null) values[i] = args[i].eval(env).copy(); else if (arg.isReference()) values[i] = args[i].evalRef(env); else { // php/0d04 values[i] = args[i].eval(env); } } return values; } public Value call(Env env, Expr []args) { return callImpl(env, args, false); } public Value callCopy(Env env, Expr []args) { return callImpl(env, args, false); } public Value callRef(Env env, Expr []args) { return callImpl(env, args, true); } private Value callImpl(Env env, Expr []args, boolean isRef) { HashMap<String,Var> map = new HashMap<String,Var>(); Value []values = new Value[args.length]; for (int i = 0; i < args.length; i++) { Arg arg = null; if (i < _args.length) { arg = _args[i]; } if (arg == null) { values[i] = args[i].eval(env).copy(); } else if (arg.isReference()) { values[i] = args[i].evalRef(env); map.put(arg.getName(), values[i].toRefVar()); } else { // php/0d04 values[i] = args[i].eval(env); Var var = values[i].toVar(); map.put(arg.getName(), var); values[i] = var.toValue(); } } for (int i = args.length; i < _args.length; i++) { Arg arg = _args[i]; Expr defaultExpr = arg.getDefault(); if (defaultExpr == null) return env.error("expected default expression"); else if (arg.isReference()) map.put(arg.getName(), defaultExpr.evalRef(env).toVar()); else { map.put(arg.getName(), defaultExpr.eval(env).copy().toVar()); } } HashMap<String,Var> oldMap = env.pushEnv(map); Value []oldArgs = env.setFunctionArgs(values); // php/0476 Value oldThis; if (isStatic()) { // php/0967 oldThis = env.setThis(NullThisValue.NULL); } else oldThis = env.getThis(); try { Value value = _statement.execute(env); if (value == null) return NullValue.NULL; else if (_isReturnsReference && isRef) return value; else return value.copyReturn(); } finally { env.restoreFunctionArgs(oldArgs); env.popEnv(oldMap); env.setThis(oldThis); } } public Value call(Env env, Value []args) { return callImpl(env, args, false); } public Value callCopy(Env env, Value []args) { return callImpl(env, args, false); } public Value callRef(Env env, Value []args) { return callImpl(env, args, true); } private Value callImpl(Env env, Value []args, boolean isRef) { HashMap<String,Var> map = new HashMap<String,Var>(); for (int i = 0; i < args.length; i++) { Arg arg = null; if (i < _args.length) { arg = _args[i]; } if (arg == null) { } else if (arg.isReference()) map.put(arg.getName(), args[i].toRefVar()); else { // quercus/0d04 map.put(arg.getName(), args[i].copy().toVar()); } } for (int i = args.length; i < _args.length; i++) { Arg arg = _args[i]; Expr defaultExpr = arg.getDefault(); if (defaultExpr == null) return env.error("expected default expression"); else if (arg.isReference()) map.put(arg.getName(), defaultExpr.evalRef(env).toVar()); else { map.put(arg.getName(), defaultExpr.eval(env).copy().toVar()); } } HashMap<String,Var> oldMap = env.pushEnv(map); Value []oldArgs = env.setFunctionArgs(args); Value oldThis; if (isStatic()) { // php/0967, php/091i oldThis = env.setThis(NullThisValue.NULL); } else oldThis = env.getThis(); try { Value value = _statement.execute(env); if (value == null) return NullValue.NULL; else if (_isReturnsReference && isRef) return value; else return value.copyReturn(); } finally { env.restoreFunctionArgs(oldArgs); env.popEnv(oldMap); env.setThis(oldThis); } } private boolean isVariableArgs() { return _info.isVariableArgs() || _args.length > 5; } private boolean isVariableMap() { // return _info.isVariableVar(); // php/3254 return _info.isUsesSymbolTable() || _info.isVariableVar(); } public String toString() { return getClass().getSimpleName() + "[" + _name + "]"; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?