Package macromedia.asc.semantics

Source Code of macromedia.asc.semantics.Builder

/*
* Written by Jeff Dyer
* Copyright (c) 1998-2003 Mountain View Compiler Company
* All rights reserved.
*/

package macromedia.asc.semantics;

import macromedia.asc.util.*;

import static macromedia.asc.parser.Tokens.*;
import static macromedia.asc.embedding.avmplus.RuntimeConstants.*;
import static macromedia.asc.semantics.Slot.*;

/**
*  A builder has two jobs to initialize a compile-time value (build()), and to
*  add and remove properties from a value (ExplicitVar, etc).
*
*  Different builders know how to create properties on different kinds of
*  objects. That is, each builder has a lexical context in which it is used.
*
*  Builders and their contexts
*  ---------------------------
*  ActivationBuilder - parameters
*  BlockBuilder - local block
*  ClassBuilder - class statics
*  InstanceBuilder - class non-statics
*  GlobalBuilder - global scope
*  PackageBuilder - package scope
*
*  Builders added properties to object values according to the meaning of
*  various add actions in the builder's context. The actions are:
*
*  Variable       - add a variable slot
*  Method         - add a method slot
*  ExplicitVar    - add a named variable
*  ImplicitVar    - add an unnamed variable (e.g. method closure)
*  ExplicitGet    - add a named get accessor
*  ImplicitGet    - add an unnamed get accessor
*  ExplicitCall   - add a named method
*  ImplicitCall   - add an unamed method, refrenced from an explicit trait
*  UnaryOperator  - add a unary operator
*  UnaryOverload  - add a unary operator that overloads a more generic unary operator
*  BinaryOperator - add a binary operator
*  BinaryOverload - add a binary operator that overloads a more generic binary operator
*
*  Variable and Method actions allocate a variable and method slot in either
*  the local or global frames depending on the builder. The Explicit/Implicit
*  actions add traits that reference a variable or method slot, to the object
*
*  var_offset indicates the meaning of the 0th var_index in this context. E.g.
*  In an activation object, var_offset = 1 to allow for 'this'. In a derived
*  instance object, var_offset might be 4 indicating that their are 4 instance
*  variable in the base class, so the 0th variable in the current class would
*  be at slot 4.
*
* @author Jeff Dyer
*/

public abstract class Builder
{
  /*
   * TODO: {pmd} I cant be sure, but I'd guess that removeBuilderNames was a temporary hack put in while shifting the names table from
   * here to ObjectValue, once someone verifies this, all references should be removed. It is an unclear thing to leave lying around.
   */
  public static final boolean removeBuilderNames = true;
 
  protected Builder()
  {
    //macromedia.asc.parser.Node.tally(this);
  }
 
  protected ObjectValue objectValue;
  // context I was defined in
  public int contextId;

  private Names names; // only used when !removeBuilderNames
 
  public QName classname;
  public String pkgname = "";

  public int var_offset;
  public int method_offset;
    public int method_count;
  public int reg_offset;
  public int temp_reg = -1;
    public boolean is_intrinsic;
    public boolean is_dynamic;
    public boolean is_final;
   
  public abstract void build(Context cx, ObjectValue ob);
  public void addNames(Names names)
  {
    if (names != null)
    {
      getNamesAndCreate().putAll(names);
    }
  }
 
  public Names getNames()
  {
    return removeBuilderNames ? objectValue.getNames() : names;
  }
 
  private Names getNamesAndCreate()
  {
    if(removeBuilderNames)
      return objectValue.getNamesAndCreate();
    else {
      if(names == null)
        names = new Names();
      return names;
    }     
  }
 
  public void clearNames()
  {
    if(!removeBuilderNames)
      names = null;
  }


  // Builder helpers

  public void UnaryOperator(Context cx, ObjectValue ob, TypeValue type, int call_seq, int slot_id)
  {
    cx.statics.pushExpectedSlotID(slot_id);

    CHECK_SLOT_INDEX(slot_id, ob.addMethodSlot(cx, type));
    ob.getSlot(cx, slot_id).attrs(call_seq, getUnaryOp(slot_id));
  }

  public void UnaryOverload(Context cx, ObjectValue ob, int slot_id, TypeValue type, TypeValue opd_type, int call_seq, int over_id)
  {
    cx.statics.pushExpectedSlotID(over_id);

    CHECK_SLOT_INDEX(over_id, ob.addSlotOverload(cx, slot_id, type, opd_type));
    ob.getSlot(cx, over_id).attrs(call_seq, getUnaryOp(over_id));
  }

  public void BinaryOperator(Context cx, ObjectValue ob, TypeValue type, int slot_id)
  {
    cx.statics.pushExpectedSlotID(slot_id);
   
    CHECK_SLOT_INDEX(slot_id, ob.addMethodSlot(cx, type));
    ob.getSlot(cx, slot_id).attrs(Slot.CALL_Binary, getBinaryOp(slot_id));
  }

  public void BinaryOverload(Context cx, ObjectValue ob, int slot_id, TypeValue type, TypeValue lhs_type, TypeValue rhs_type, int over_id)
  {
    cx.statics.pushExpectedSlotID(over_id);

    CHECK_SLOT_INDEX(over_id, ob.addSlotOverload(cx, slot_id, type, lhs_type, rhs_type));
    ob.getSlot(cx, over_id).attrs(Slot.CALL_Binary, getBinaryOp(over_id));
  }

  public int ExplicitGet(Context cx, ObjectValue ob, String name, ObjectValue ns, TypeValue type, boolean is_final, boolean is_override, int expected_id)
  {
    return ExplicitGet(cx, ob, name, ns, type, is_final, is_override, expected_id, -1, -1);
  }

  public int ExplicitGet(Context cx, ObjectValue ob, String name, ObjectValue ns, TypeValue type, boolean is_final, boolean is_override)
  {
    return ExplicitGet(cx, ob, name, ns, type, is_final, is_override, -1, -1, -1);
  }

  public int ExplicitGet(Context cx, ObjectValue ob, String name, ObjectValue ns, TypeValue type, boolean is_final, boolean is_override, int expected_id, int method_id, int var_id)
  {
    int slot_id = ob.addMethodSlot(cx, type);
    CHECK_SLOT_INDEX(expected_id, slot_id);
    ob.defineName(cx, GET_TOKEN, name, ns, slot_id);
    ob.getSlot(cx, slot_id).attrs(Slot.CALL_ThisMethod, method_id);

    if(!Builder.removeBuilderNames)
    {
      if (method_id >= 0)
      {
        Name(cx, GET_TOKEN, name, ns);
      }
    }
    return slot_id;
  }

  public int ExplicitGet( Context cx, ObjectValue ob, String name, Namespaces namespaces, TypeValue type, boolean is_final, boolean is_override)
  {
    return ExplicitGet(cx, ob, name, namespaces, type, is_final, is_override, -1, -1, -1);
  }

  public int ExplicitGet( Context cx, ObjectValue ob, String name, Namespaces namespaces, TypeValue type, boolean is_final, boolean is_override, int expected_id , int method_id , int var_id  )
  {
    int slot_id = ob.addMethodSlot(cx,type);
    CHECK_SLOT_INDEX(expected_id,slot_id);
    ob.defineNames(cx,GET_TOKEN,name,namespaces,slot_id);
    Slot slot = ob.getSlot(cx,slot_id);
    slot.attrs(CALL_ThisMethod,method_id);
    slot.setFinal(is_final);
    slot.setOverride(is_override);

    // do backend binding

    if(!Builder.removeBuilderNames)
    {
      if( method_id >= 0 )
      {
        for (ObjectValue n : namespaces)
        {
          Name(cx, GET_TOKEN, name,n);
        }
      }
    }

    return slot_id;
  }

  public int ExplicitSet(Context cx, ObjectValue ob, String name, ObjectValue ns, TypeValue type, boolean is_final, boolean is_override,int expected_id)
  {
    return ExplicitSet(cx, ob, name, ns, type, is_final, is_override,expected_id, -1, -1);
  }

  public int ExplicitSet(Context cx, ObjectValue ob, String name, ObjectValue ns, TypeValue type, boolean is_final, boolean is_override,int expected_id, int method_id)
  {
    return ExplicitSet(cx, ob, name, ns, type,  is_final, is_override,expected_id, method_id, -1);
  }

  public int ExplicitSet(Context cx, ObjectValue ob, String name, ObjectValue ns, TypeValue type, boolean is_final, boolean is_override, int expected_id, int method_id, int var_id)
  {
    int slot_id = ob.addMethodSlot(cx, type);
    CHECK_SLOT_INDEX(expected_id, slot_id);
    ob.defineName(cx, SET_TOKEN, name, ns, slot_id);
    Slot slot = ob.getSlot(cx,slot_id);
    slot.attrs(CALL_ThisMethod,method_id);
    slot.setFinal(is_final);
    slot.setOverride(is_override);

    if(!Builder.removeBuilderNames)
    {
      if( method_id >= 0 )
      {
        Name(cx,SET_TOKEN,name,ns);
      }
    }

    return slot_id;
  }

  public int ExplicitSet( Context cx, ObjectValue ob, String name, Namespaces namespaces, TypeValue type, boolean is_final, boolean is_override, int expected_id)
  {
    return ExplicitSet(cx, ob, name, namespaces, type, is_final, is_override, expected_id, -1, -1);
  }

  public int ExplicitSet( Context cx, ObjectValue ob, String name, Namespaces namespaces, TypeValue type, boolean is_final, boolean is_override, int expected_id, int method_id , int var_id )
  {
    int slot_id = ob.addMethodSlot(cx,type);
    CHECK_SLOT_INDEX(expected_id,slot_id);
    ob.defineNames(cx,SET_TOKEN,name,namespaces,slot_id);
    Slot slot = ob.getSlot(cx,slot_id);
    slot.attrs(CALL_ThisMethod,method_id);
    slot.setFinal(is_final);
    slot.setOverride(is_override);

    // do backend binding

    if(!Builder.removeBuilderNames)
    {
      if( method_id >= 0 )
      {
        for (ObjectValue n : namespaces)
        {
          Name(cx,SET_TOKEN,name,n);
        }
      }
    }

    return slot_id;
  }

  public int ExplicitVar(Context cx, ObjectValue ob, String name, ObjectValue ns, TypeValue type, int expected_id)
  {
    return ExplicitVar(cx, ob, name, ns, type, expected_id, -1, -1);
  }

  public int ExplicitVar(Context cx, ObjectValue ob, String name, ObjectValue ns, TypeValue type, int expected_id, int method_id, int var_id)
  {
    int slot_id = ob.addVariableSlot(cx, type, var_id);
    ob.getSlot(cx, slot_id).addType(type.getDefaultTypeInfo());
    CHECK_SLOT_INDEX(expected_id, slot_id);
    ob.defineName(cx, GET_TOKEN, name, ns, slot_id);   
    ob.defineName(cx, SET_TOKEN, name, ns, slot_id);
    ob.getSlot(cx, slot_id).attrs(Slot.CALL_ThisMethod, method_id);

    if ( var_id >= 0 )
    {
      Name(cx, VAR_TOKEN, name, ns);
    }
   
    return slot_id;
  }

  public int ExplicitVar( Context cx, ObjectValue ob, String name, Namespaces namespaces, TypeValue type, int expected_id)
  {
    return ExplicitVar(cx, ob, name, namespaces, type, expected_id, -1, -1);
  }

  public int ExplicitVar( Context cx, ObjectValue ob, String name, Namespaces namespaces, TypeValue type, int expected_id, int method_id, int var_id  )
  {
    int slot_id = ob.addVariableSlot(cx,type,var_id);
        ob.getSlot(cx, slot_id).addType(type.getDefaultTypeInfo());
        CHECK_SLOT_INDEX(expected_id,slot_id);
    ob.defineNames(cx,GET_TOKEN,name,namespaces,slot_id);   
    ob.defineNames(cx,SET_TOKEN,name,namespaces,slot_id);
    ob.getSlot(cx,slot_id).attrs(CALL_ThisMethod,method_id);

    // do backend binding

    if( var_id >= 0 )
    {
      for (ObjectValue n : namespaces)
      {
        Name(cx, VAR_TOKEN, name, n);
      }
    } 

    return slot_id;
  }

  public int ImplicitVar(Context cx, ObjectValue ob, String name, ObjectValue ns, TypeValue type, int expected_id)
  {
    return ImplicitVar(cx, ob, name, ns, type, expected_id, -1, -1);
  }

  public int ImplicitVar(Context cx, ObjectValue ob, String name, ObjectValue ns, TypeValue type, int expected_id, int method_id, int var_id)
  {
    cx.statics.pushExpectedSlotID(expected_id);
   
    int slot_id = ob.addVariableSlot(cx, type, var_id);
    CHECK_SLOT_INDEX(expected_id, slot_id);
    ob.defineName(cx, GET_TOKEN, name, ns, slot_id);
    ob.defineName(cx, SET_TOKEN, name, ns, slot_id);
    ob.getSlot(cx, slot_id).attrs(Slot.CALL_ThisMethod, method_id);

    return slot_id;   
  }

  public void ImplicitCall(Context cx, ObjectValue ob, int slot_id, TypeValue type, int call_seq, int method_id, int expected_id)
  {
    cx.statics.pushExpectedSlotID(expected_id);

    int implied_id = ob.addSlotImplicit(cx, slot_id, EMPTY_TOKEN, type);
    CHECK_SLOT_INDEX(expected_id, implied_id);
    ob.getSlot(cx, implied_id).attrs(call_seq, method_id);
    ob.getSlot(cx, implied_id).setGetter(false);
  }

  public int ExplicitCall(Context cx, ObjectValue ob, String name, ObjectValue ns, TypeValue type, boolean is_final, boolean is_override,  int expected_id)
  {
    return ExplicitCall(cx, ob, name, ns, type, is_final, is_override, expected_id, -1, -1);
  }

  public int ExplicitCall(Context cx, ObjectValue ob, String name, ObjectValue ns, TypeValue type, boolean is_final, boolean is_override, int expected_id, int method_id, int var_id)
  {
    TypeValue functionType = cx.useStaticSemantics() ? cx.functionType() : type;
    int slot_id = ob.addMethodSlot(cx, functionType);
    CHECK_SLOT_INDEX(expected_id, slot_id);
    ob.defineName(cx, EMPTY_TOKEN, name, ns, slot_id);
    Slot slot = ob.getSlot(cx,slot_id);
    ob.getSlot(cx,slot_id).attrs(CALL_ThisMethod,method_id);
    slot.setFinal(is_final);
    slot.setOverride(is_override);
    slot.setGetter(false);

    // do backend binding
    Name(cx,EMPTY_TOKEN,name,ns);

    return slot_id;
  }

  public int ExplicitCall( Context cx, ObjectValue ob, String name, Namespaces namespaces, TypeValue type, boolean is_final, boolean is_override, int expected_id, int method_id , int var_id )
  {
    TypeValue functionType = cx.useStaticSemantics() ? cx.functionType() : type;
    int slot_id = ob.addMethodSlot(cx,functionType);
    CHECK_SLOT_INDEX(expected_id,slot_id);
    ob.defineNames(cx,GET_TOKEN,name,namespaces,slot_id);
    Slot slot = ob.getSlot(cx,slot_id);
    ob.getSlot(cx,slot_id).attrs(CALL_ThisMethod,method_id);
    slot.setFinal(is_final);
    slot.setOverride(is_override);
    slot.setGetter(false);

    // do backend binding

    if( method_id >= 0 )
    {
      for (ObjectValue n : namespaces)
      {
        Name(cx, EMPTY_TOKEN, name, n);
      }
    }

    return slot_id;
  }

  public void ImplicitConstruct(Context cx, ObjectValue ob, int slot_id, TypeValue type, int call_seq, int method_id, int expected_id)
  {
        int implied_id = ob.addSlotImplicit(cx,slot_id,NEW_TOKEN,type);
        CHECK_SLOT_INDEX(expected_id,implied_id);
    ob.getSlot(cx, implied_id).attrs(call_seq, method_id);
    ob.getSlot(cx, implied_id).setGetter(false);
  }

  public int Variable(Context cx, ObjectValue ob)
  {
    return ob.addVar(cx);
  }

  public int Method(Context cx, ObjectValue ob, String name, Namespaces namespaces, boolean is_intrinsic)
  {
    if (this.is_intrinsic || is_intrinsic)
    {
      return -1;
    }

    return cx.getEmitter().GetMethodId(name,namespaces);
  }

    public int local_method_count;

  /*
  GetMethodId translates the name of a method into an index of the local
  method table. This mapping is different than is used for lookup.
  */

    /*
    GetMethodId translates the name of a method into an index of the local
    method table.  This mapping is different than is used for lookup
    */

    public int GetMethodId(Context cx, String name, Namespaces namespaces)
    {
    if(getNames() != null)
    {
          for (ObjectValue ns : namespaces)
          {
            if(!Builder.removeBuilderNames)
            {
                // old way
              int index = getNames().get(name, ns, Names.LOCAL_METHOD_NAMES);
              if(index != -1)
                return index;
            }
            else
            {
              // new way
              int slot_id = objectValue.getSlotIndex(cx, GET_TOKEN, name, ns);
              if(slot_id > 0)
              {
                Slot s = objectValue.getSlot(cx, slot_id);
                if(s.getMethodID() != -1 && s.declaredBy == objectValue)
                {
                  return s.getMethodID();
                }
              }
            }
          }
        }

        // We have a new name, so count it
        ++local_method_count;

        if(!Builder.removeBuilderNames)
        {
          // Add each namespace to the qualifiers map
          for (ObjectValue ns : namespaces)
          {
            getNamesAndCreate().putMask(name, ns, Names.LOCAL_METHOD_NAMES);
          }
        }
       
        return local_method_count;
    }

  public void Name(Context cx, int kind, String name, ObjectValue qualifier)
  {   
    int type = Names.getTypeFromKind(kind);
   
    if(Builder.removeBuilderNames && (type == Names.METHOD_NAMES || type == Names.VAR_NAMES))
      return;
 
    // Add the qualifier to the qualifiers map, and set its value to index.
    getNamesAndCreate().putMask(name, qualifier, type);
  }
 

  public final void CHECK_SLOT_INDEX(int a, int b)
  {
    if (a != -1 && a != b)
    {
      assert(false); // throw "Slot out of sync.";
    }
  }
 
    public void InheritCall(Context cx, ObjectValue ob, String name, ObjectValue ns, Slot explicitSlot, Slot implicitSlot)
    {
      ob.addSlot(explicitSlot);
      ob.addSlot(implicitSlot);
      ob.defineName(cx, GET_TOKEN, name, ns, explicitSlot.id);
      Name(cx, GET_TOKEN, name, ns);     
      Name(cx, EMPTY_TOKEN, name, ns);     
    }

    public void InheritGet(Context cx, ObjectValue ob, String name, ObjectValue ns, Slot slot)
    {
      ob.addSlot(slot);
      ob.defineName(cx, GET_TOKEN, name, ns, slot.id);
      Name(cx, GET_TOKEN, name, ns);     
    }

    public void InheritSet(Context cx, ObjectValue ob, String name, ObjectValue ns, Slot slot)
    {
      ob.addSlot(slot);
      ob.defineName(cx, SET_TOKEN, name, ns, slot.id);
      Name(cx, SET_TOKEN, name, ns);     
   

    public void InheritVar(Context cx, ObjectValue ob, String name, ObjectValue ns, Slot slot)
    {
      ob.addSlot(slot);
      ob.defineName(cx, GET_TOKEN, name, ns, slot.id);
      ob.defineName(cx, SET_TOKEN, name, ns, slot.id);     

    if (slot.getVarIndex() >= 0)
    {
      Name(cx, VAR_TOKEN, name, ns);
    }     
    }
   
    public boolean hasRegisterOffset() { return true; }
}
TOP

Related Classes of macromedia.asc.semantics.Builder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.