call.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 965 行 · 第 1/2 页

JAVA
965
字号
/* * Copyright (c) 1998-2006 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 SoftwareFoundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.es;import java.util.Enumeration;import java.util.Iterator;/** * Implementation class representing a call context. */public final class Call extends ESBase {  static ESId ARGUMENTS = ESId.intern("arguments");  static ESId ARRAY = ESId.intern("Array");  Call caller;  ESObject callThis;  int callLength;  ESBase callee;  public ESBase []stack;  int top;  public ESGlobal global;  ESBase []scope;  int scopeLength;  public ESBase []values;  ESObject aux;  Call child; // just a cache  /**   * Create a new context object   */  Call()  {    prototype = esBase;    stack = new ESBase[64];    scope = new ESBase[16];    values = new ESBase[64];    top = 0;  }  void clear()  {    aux = null;    child = null;    top = 0;  }  public Call getCall()  {    Call child = this.child;    if (child == null)      child = this.child = new Call();    child.caller = this;    child.global = global;    return child;  }  Global getGlobalProto() { return Global.getGlobalProto(); }  public ESBase wrap(Object o) throws Throwable { return Global.wrap(o); }    public ESBase wrap(long n) throws Throwable  {    return ESNumber.create(n);  }    public ESBase wrapClass(Class cl) throws Throwable  {    return Global.getGlobalProto().classWrap(cl);  }  // public ESGlobal getGlobal() { return Global.getGlobal().global; }  final ESBase getArg(int i)  {    return stack[top + i];  }  public final ESBase getArg(int i, int len)   {     return i < len ? stack[top + i] : esUndefined;   }  public final int getArgInt32(int i, int len) throws Throwable  {    return i < len ? stack[top + i].toInt32() : 0;  }  public final double getArgNum(int i, int len) throws Throwable  {    return i < len ? stack[top + i].toNum() : (0.0/0.0);  }  public final String getArgString(int i, int len) throws Throwable  {    return i < len ? stack[top + i].toJavaString() : null;  }  public final Object getArgObject(int i, int len) throws Throwable  {    return i < len ? stack[top + i].toJavaObject() : null;  }  public ESObject createObject()  {    return new ESObject("Object", getGlobalProto().objProto);  }  public ESBase createDate(long time)  {    return new ESDate(time, getGlobalProto().dateProto);  }  public String printf(int length)    throws Throwable  {    return Printf.sprintf(this, length);  }  void setArg(int i, ESBase obj)  {    stack[top + i] = obj;  }  public final ESObject getThis() throws Throwable  {    return stack[top - 1].toObject();  }    public final Object getThisWrapper() throws Throwable  {     return stack[top - 1].toJavaObject();  }    void setThis(ESBase obj)  {    stack[top - 1] = obj;  }  public ESGlobal getGlobal()  {    return global;  }  public final ESObject getCallThis() throws Throwable  {     ESBase obj = caller.stack[caller.top - 1];    return obj.toObject();  }  ESBase getContext()  {    return scope[scopeLength - 1];  }  ESBase getFunctionContext()  {    if (caller == null || caller.scopeLength == 0)      return global;    else      return caller.scope[caller.scopeLength - 1];  }  public void pushScope(ESBase value)  {    scope[scopeLength++] = value;  }  public void popScope()  {    scopeLength--;  }  public ESObject getEval()  {    return (ESObject) scope[scopeLength - 1];  }    public ESObject createArg(ESId []args, int length)    throws Throwable  {    ESObject arg = ESArguments.create(args, this, length);    scope[scopeLength++] = arg;    return arg;  }  public void setProperty(ESString name, ESBase value) throws Throwable  {    //setProperty(name, value);  }  public ESBase delete(ESString key) throws Throwable  {    return aux == null ? ESBoolean.FALSE : aux.delete(key);   }   public ESBase findScopeProperty(ESString id) throws Throwable  {    for (int i = scopeLength - 1; i > 0; i--) {      if (scope[i].getProperty(id) != esEmpty)	return scope[i];    }    return global;  }  public ESBase scopeTypeof(ESString id) throws Throwable  {    for (int i = scopeLength - 1; i >= 0; i--) {      ESBase value;      if ((value = scope[i].getProperty(id)) != esEmpty)	return value.typeof();    }    return esEmpty.typeof();  }  public static ESBase setProperty(ESBase base, ESString field, ESBase value)    throws Throwable  {    base.setProperty(field, value);        return value;  }  public static ESBase doVoid(ESBase value)  {    return ESBase.esUndefined;  }  public ESBase array(ESBase value)    throws Throwable  {    ESBase array = call(global, ARRAY, 0);    array.setProperty(0, value);    return array;  }  public static ESBase comma(ESBase left, ESBase right)  {    return right;  }  public static ESBase _first(ESBase left, ESBase right)    throws Throwable  {    // This is only used for postfix    if (! (left instanceof ESNumber))      return ESNumber.create(left.toNum());    else      return left;  }  public static double _first(double left, double right)    throws Throwable  {    return left;  }  /**   * Returns the first value in a tuple.  Used   *   * @param left the first value   * @param right the right value   *   * @return the first value.   */  public static int _first(int left, int right)    throws Throwable  {    return left;  }  public static double _pre(ESBase expr, ESString field, int inc)    throws Throwable  {    double oldVal = expr.getProperty(field).toNum();    ESNumber newVal = ESNumber.create(oldVal + inc);    expr.setProperty(field, newVal);        return oldVal + inc;  }  public static double _post(ESBase expr, ESString field, int inc)    throws Throwable  {    double oldVal = expr.getProperty(field).toNum();    ESNumber newVal = ESNumber.create(oldVal + inc);    expr.setProperty(field, newVal);        return oldVal;  }  public double _pre(ESString field, int inc)    throws Throwable  {    double oldVal = getScopeProperty(field).toNum();    ESNumber newVal = ESNumber.create(oldVal + inc);    setScopeProperty(field, newVal);        return oldVal + inc;  }  public double _post(ESString field, int inc)    throws Throwable  {    double oldVal = getScopeProperty(field).toNum();    ESNumber newVal = ESNumber.create(oldVal + inc);    setScopeProperty(field, newVal);        return oldVal;  }  public ESBase setGlobalProperty(ESString id, ESBase value) throws Throwable  {    global.setProperty(id, value);        return value;  }  /**   * Returns the global variable of the id, throwing an exception if   * the it's undefined.   */  public ESBase getGlobalVariable(ESString id) throws Throwable  {    ESBase value = global.getProperty(id);    if (value == ESBase.esEmpty)      throw new ESUndefinedException("undefined variable `" + id + "'");    return value;  }  public ESBase getScopeProperty(ESString id) throws Throwable  {    for (int i = scopeLength - 1; i >= 0; i--) {      ESBase value;      if ((value = scope[i].getProperty(id)) != esEmpty) {	return value;      }    }    throw new ESUndefinedException("undefined variable `" + id + "'");  }  public void fillScope()  {    if (callee instanceof ESClosure) {      ESClosure closure = (ESClosure) callee;      if (closure.scopeLength == 0) {        scope[0] = caller.global;        scopeLength = 1;        return;      }      for (int i = 0; i < closure.scopeLength; i++) {        scope[i] = closure.scope[i];      }      scopeLength = closure.scopeLength;    }    else {      scope[0] = caller.global;      scopeLength = 1;    }  }  public ESBase hasScopeProperty(ESString id) throws Throwable  {    for (int i = scopeLength - 1; i >= 0; i--) {      ESBase value;      if ((value = scope[i].getProperty(id)) != esEmpty)	return value;    }    return esEmpty;  }  public ESBase setScopeProperty(ESString id, ESBase value) throws Throwable  {    if (value == esEmpty)      value = esUndefined;    for (int i = scopeLength - 1; i > 0; i--) {      if (scope[i].getProperty(id) != esEmpty) {	scope[i].setProperty(id, value);	return value;      }    }    global.setProperty(id, value);    return value;  }  public ESBase deleteScopeProperty(ESString id) throws Throwable  {    for (int i = scopeLength - 1; i > 0; i--) {      if (scope[i].getProperty(id) != esEmpty)	return scope[i].delete(id);    }    return global.delete(id);  }  /*  public ESBase startCallScopeProperty(ESString id, int i) throws Throwable  {    top = i + 1;     for (int j = scopeLength - 1; j >= 0; j--) {      ESBase value;       if ((value = scope[j].getProperty(id)) != esEmpty) {	stack[i] = global;	return value;      }    }    throw new ESUndefinedException("undefined call `" + id + "'");  }  */  public int arg(int i, ESBase arg)  {    stack[i + 1] = arg;        return 1;  }  public ESBase callScope(ESString id, int i) throws Throwable  {    top = i + 1;    int scopeLength = caller.scopeLength;    ESBase []scope = caller.scope;    for (int j = scopeLength - 1; j >= 0; j--) {      ESBase value;       if ((value = scope[j].getProperty(id)) != esEmpty) {        callee = value;	stack[i] = scope[j];	return value.call(this, 0);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?