Package flex2.compiler.abc

Source Code of flex2.compiler.abc.AbcCompiler$BytecodeDecodingFailed

/*
*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*
*/

package flex2.compiler.abc;

import flash.util.FileUtils;
import flex2.compiler.AbstractSubCompiler;
import flex2.compiler.CompilationUnit;
import flex2.compiler.CompilerBenchmarkHelper;
import flex2.compiler.CompilerContext;
import flex2.compiler.Source;
import flex2.compiler.SymbolTable;
import flex2.compiler.as3.As3Compiler;
import flex2.compiler.as3.As3Configuration;
import flex2.compiler.as3.Extension;
import flex2.compiler.as3.SyntaxTreeEvaluator;
import flex2.compiler.as3.reflect.TypeTable;
import flex2.compiler.css.StyleConflictException;
import flex2.compiler.util.CompilerMessage;
import flex2.compiler.util.MimeMappings;
import flex2.compiler.util.Name;
import flex2.compiler.util.ThreadLocalToolkit;
import macromedia.abc.AbcParser;
import macromedia.asc.embedding.avmplus.GlobalBuilder;
import macromedia.asc.parser.ProgramNode;
import macromedia.asc.semantics.*;
import macromedia.asc.util.Context;

import java.io.IOException;
import java.util.*;

/**
* This subcompiler is used to process ABC (Actionscript Byte Code)
* blocks and to extract type information.
*
* @author Clement Wong
*/
public class AbcCompiler extends AbstractSubCompiler implements flex2.compiler.SubCompiler
{
  static
  {
    TypeValue.init();
    ObjectValue.init();
  }

  private static final String COMPILER_NAME = "abc";

  public AbcCompiler(As3Configuration as3Configuration)
  {
    mimeTypes = new String[]{MimeMappings.ABC};
    compilerExtensions = new ArrayList<Extension>();
  }

  private String[] mimeTypes;
  private List<Extension> compilerExtensions;

    /**
     * The name of this compiler as a simple String identifier.
     *
     * @return This SubCompiler's name.
     */
    public String getName()
    {
        return COMPILER_NAME;
    }

  public boolean isSupported(String mimeType)
  {
    return mimeTypes[0].equals(mimeType);
  }

  public String[] getSupportedMimeTypes()
  {
    return mimeTypes;
  }

  public void addCompilerExtension(Extension ext)
  {
    compilerExtensions.add(ext);
  }

  public Source preprocess(Source source)
  {
    return source;
  }

  public CompilationUnit parse1(Source source, SymbolTable symbolTable)
  {
        if (benchmarkHelper != null)
            benchmarkHelper.startPhase(CompilerBenchmarkHelper.PARSE1, source.getNameForReporting());

    CompilationUnit unit = source.getCompilationUnit();

    if (unit != null && unit.hasTypeInfo)
    {
            if (unit.bytes.isEmpty())
            {
                copyBytecodes(source, unit);
            }

      return unit;
    }

    if ((unit != null) && (unit.getSyntaxTree() != null))
    {
      return unit;
    }

    final String path = source.getName();
    ProgramNode node = null;

    CompilerContext context = new CompilerContext();

    Context cx = new Context(symbolTable.perCompileData);

    cx.setScriptName(source.getName());
    cx.setPath(source.getParent());

    cx.setEmitter(symbolTable.emitter);
    cx.setHandler(new As3Compiler.CompilerHandler()
    {
      public void error2(String filename, int ln, int col, Object msg, String source)
      {
        filename = (filename == null || filename.length() == 0) ? path : filename;
        ThreadLocalToolkit.log((flex2.compiler.util.CompilerMessage) msg, filename);
      }

      public void warning2(String filename, int ln, int col, Object msg, String source)
      {
        filename = (filename == null || filename.length() == 0) ? path : filename;
        ThreadLocalToolkit.log((CompilerMessage) msg, filename);
      }

      public void error(String filename, int ln, int col, String msg, String source, int errorCode)
      {
        filename = (filename == null || filename.length() == 0) ? path : filename;
        if (errorCode != -1)
        {
          ThreadLocalToolkit.logError(filename, msg, errorCode);
        }
        else
        {
          ThreadLocalToolkit.logError(filename, msg);
        }
      }

      public void warning(String filename, int ln, int col, String msg, String source, int errorCode)
      {
        filename = (filename == null || filename.length() == 0) ? path : filename;
        if (errorCode != -1)
        {
          ThreadLocalToolkit.logWarning(filename, msg, errorCode);
        }
        else
        {
          ThreadLocalToolkit.logWarning(filename, msg);
        }
      }

      public void error(String filename, int ln, int col, String msg, String source)
      {
        filename = (filename == null || filename.length() == 0) ? path : filename;
        ThreadLocalToolkit.logError(filename, msg);
      }

      public void warning(String filename, int ln, int col, String msg, String source)
      {
        filename = (filename == null || filename.length() == 0) ? path : filename;
        ThreadLocalToolkit.logWarning(filename, msg);
      }

      public FileInclude findFileInclude(String parentPath, String filespec)
      {
        return null;
      }
    });
    symbolTable.perCompileData.handler = cx.getHandler();

    context.setAscContext(cx);

    byte[] abc = null;
    try
    {
      abc = source.toByteArray();

      if (abc == null)
      {
        abc = FileUtils.toByteArray(source.getInputStream());
      }

      if (abc == null || abc.length == 0)
      {
        ThreadLocalToolkit.log(new NoBytecodeIsAvailable(), source);
      }
      else
      {
          AbcParser parser = new AbcParser(cx, abc);
          node = parser.parseAbc();

                if (node == null && ThreadLocalToolkit.errorCount() == 0)
                {
                    ThreadLocalToolkit.log(new BytecodeDecodingFailed(), source);
                }

                As3Compiler.cleanNodeFactory(cx.getNodeFactory());
      }
    }
    catch (IOException ex)
    {
      ThreadLocalToolkit.logError(source.getNameForReporting(), ex.getLocalizedMessage());
    }

    if (ThreadLocalToolkit.errorCount() > 0)
    {
      return null;
    }

        if (unit == null)
        {
            unit = source.newCompilationUnit(node, context);
        }
        else
        {
            unit.setSyntaxTree(node);
            unit.getContext().setAttributes(context);
        }

    unit.bytes.set(abc, abc.length);

    SyntaxTreeEvaluator treeEvaluator = new SyntaxTreeEvaluator(unit);
    treeEvaluator.setLocalizationManager(ThreadLocalToolkit.getLocalizationManager());
    node.evaluate(cx, treeEvaluator);

    for (int i = 0, length = compilerExtensions.size(); i < length; i++)
    {
      compilerExtensions.get(i).parse1(unit, null);

      if (ThreadLocalToolkit.errorCount() > 0)
      {
        return null;
      }
    }

        if (benchmarkHelper != null)
            benchmarkHelper.endPhase(CompilerBenchmarkHelper.PARSE1);

    return unit;
  }
 
  public void parse2(CompilationUnit unit, SymbolTable symbolTable)
  {
        if (benchmarkHelper != null)
            benchmarkHelper.startPhase(CompilerBenchmarkHelper.PARSE2, unit.getSource().getNameForReporting());

        if (unit.hasTypeInfo)
    {
      return;
    }

    for (int i = 0, length = compilerExtensions.size(); i < length; i++)
    {
      compilerExtensions.get(i).parse2(unit, null);

      if (ThreadLocalToolkit.errorCount() > 0)
      {
        return;
      }
    }
       
        if (benchmarkHelper != null)
            benchmarkHelper.endPhase(CompilerBenchmarkHelper.PARSE2);
  }

  public void analyze1(CompilationUnit unit, SymbolTable symbolTable)
  {
        if (benchmarkHelper != null)
            benchmarkHelper.startPhase(CompilerBenchmarkHelper.ANALYZE1, unit.getSource().getNameForReporting());
       
        if (unit.hasTypeInfo)
    {
      return;
    }

    ProgramNode node = (ProgramNode) unit.getSyntaxTree();
    if (node.state != ProgramNode.Inheritance)
    {
      return;
    }

    CompilerContext context = unit.getContext();
    Context cx = context.getAscContext();
    symbolTable.perCompileData.handler = cx.getHandler();

    ObjectValue global = new ObjectValue(cx, new GlobalBuilder(), null);
    cx.pushScope(global); // first scope is always considered the global scope.

    // run FlowAnalyzer
    FlowGraphEmitter flowem = new FlowGraphEmitter(cx, unit.getSource().getName(), false);
    FlowAnalyzer flower = new FlowAnalyzer(flowem);
    context.setAttribute("FlowAnalyzer", flower);

    // 1. ProgramNode.state == Inheritance
    node.evaluate(cx, flower);
    cx.popScope();

    if (ThreadLocalToolkit.errorCount() > 0)
    {
      return;
    }

    unit.typeInfo = node.frame;

    for (int i = 0, length = compilerExtensions.size(); i < length; i++)
    {
      compilerExtensions.get(i).analyze1(unit, null);

      if (ThreadLocalToolkit.errorCount() > 0)
      {
        return;
      }
    }
       
        if (benchmarkHelper != null)
            benchmarkHelper.endPhase(CompilerBenchmarkHelper.ANALYZE1);
  }

  public void analyze2(CompilationUnit unit, SymbolTable symbolTable)
  {
        if (benchmarkHelper != null)
            benchmarkHelper.startPhase(CompilerBenchmarkHelper.ANALYZE2, unit.getSource().getNameForReporting());

        if (unit.hasTypeInfo)
    {
      return;
    }

    ProgramNode node = (ProgramNode) unit.getSyntaxTree();
    if (node.state != ProgramNode.Else)
    {
      return;
    }
    CompilerContext context = unit.getContext();
    Context cx = context.getAscContext();
    symbolTable.perCompileData.handler = cx.getHandler();

    FlowAnalyzer flower = (FlowAnalyzer) context.getAttribute("FlowAnalyzer");
    context.setAttribute("processed", new HashSet(15));

    inheritSlots(unit, unit.inheritance, symbolTable);
    inheritSlots(unit, unit.namespaces, symbolTable);

    cx.pushScope(node.frame);
    // 2. ProgramNode.state == Else
    node.evaluate(cx, flower);
    cx.popScope();

    if (ThreadLocalToolkit.errorCount() > 0)
    {
      return;
    }

    for (int i = 0, length = compilerExtensions.size(); i < length; i++)
    {
      compilerExtensions.get(i).analyze2(unit, null);

      if (ThreadLocalToolkit.errorCount() > 0)
      {
        return;
      }
    }
       
        if (benchmarkHelper != null)
            benchmarkHelper.endPhase(CompilerBenchmarkHelper.ANALYZE2);
  }

  public void analyze3(CompilationUnit unit, SymbolTable symbolTable)
  {
        if (benchmarkHelper != null)
            benchmarkHelper.startPhase(CompilerBenchmarkHelper.ANALYZE3, unit.getSource().getNameForReporting());

        if (unit.hasTypeInfo)
    {
      return;
    }

    ProgramNode node = (ProgramNode) unit.getSyntaxTree();

    CompilerContext context = unit.getContext();
    Context cx = context.getAscContext();
    symbolTable.perCompileData.handler = cx.getHandler();

    inheritSlots(unit, unit.types, symbolTable);
    inheritSlots(unit, unit.namespaces, symbolTable);

    // run ConstantEvaluator
    cx.pushScope(node.frame);
    ConstantEvaluator analyzer = new ConstantEvaluator(cx);
    analyzer.PreprocessDefinitionTypeInfo(cx, node);
    cx.popScope();
    context.setAttribute("ConstantEvaluator", analyzer);

    if (ThreadLocalToolkit.errorCount() > 0)
    {
        return;
    }

    for (int i = 0, length = compilerExtensions.size(); i < length; i++)
    {
      compilerExtensions.get(i).analyze3(unit, null);

      if (ThreadLocalToolkit.errorCount() > 0)
      {
        return;
      }
    }
       
        if (benchmarkHelper != null)
            benchmarkHelper.endPhase(CompilerBenchmarkHelper.ANALYZE3);

  }

  public void analyze4(CompilationUnit unit, SymbolTable symbolTable)
  {
        if (benchmarkHelper != null)
            benchmarkHelper.startPhase(CompilerBenchmarkHelper.ANALYZE4, unit.getSource().getNameForReporting());

    TypeTable typeTable = null;
    if (symbolTable != null)
    {
      typeTable = (TypeTable) symbolTable.getContext().getAttribute(As3Compiler.AttrTypeTable);
      if (typeTable == null)
      {
        typeTable = new TypeTable(symbolTable);
        symbolTable.getContext().setAttribute(As3Compiler.AttrTypeTable, typeTable);
      }
    }

    if (unit.hasTypeInfo)
    {
            for (Map.Entry<String, AbcClass> entry : unit.classTable.entrySet())
            {
                AbcClass c = entry.getValue();
                c.setTypeTable(typeTable);
                symbolTable.registerClass(entry.getKey(), c);
            }

      try
      {
        symbolTable.registerStyles(unit.styles);
      }
      catch (StyleConflictException e)
      {
        // C: assume that StyleConflictException is going to be internationalized...
        ThreadLocalToolkit.logError(unit.getSource().getNameForReporting(), e.getLocalizedMessage());
      }

      As3Compiler.evaluateLoaderClassBase(unit, typeTable);
      return;
    }

    ProgramNode node = (ProgramNode) unit.getSyntaxTree();

    CompilerContext context = unit.getContext();
    Context cx = context.getAscContext();
    symbolTable.perCompileData.handler = cx.getHandler();

    // run ConstantEvaluator
    cx.pushScope(node.frame);
    ConstantEvaluator analyzer = (ConstantEvaluator) context.removeAttribute("ConstantEvaluator");
    node.evaluate(cx, analyzer);
    cx.popScope();

    if (ThreadLocalToolkit.errorCount() > 0)
    {
      return;
    }

    if (symbolTable != null)
    {
      Map classMap = typeTable.createClasses(node.clsdefs, unit.topLevelDefinitions);
      for (Iterator i = classMap.keySet().iterator(); i.hasNext();)
      {
        String className = (String) i.next();
        flex2.compiler.abc.AbcClass c = (flex2.compiler.abc.AbcClass) classMap.get(className);
        symbolTable.registerClass(className, c);
        unit.classTable.put(className, c);
      }

      try
      {
        symbolTable.registerStyles(unit.styles);
      }
      catch (StyleConflictException e)
      {
        // C: assume that StyleConflictException is going to be internationalized...
        ThreadLocalToolkit.logError(unit.getSource().getNameForReporting(), e.getLocalizedMessage());
      }

      As3Compiler.evaluateLoaderClassBase(unit, typeTable);
    }

    for (int i = 0, length = compilerExtensions.size(); i < length; i++)
    {
      compilerExtensions.get(i).analyze4(unit, typeTable);

      if (ThreadLocalToolkit.errorCount() > 0)
      {
        return;
      }
    }
       
        if (benchmarkHelper != null)
            benchmarkHelper.endPhase(CompilerBenchmarkHelper.ANALYZE4);
  }

  public void generate(CompilationUnit unit, SymbolTable symbolTable)
  {
        if (benchmarkHelper != null)
            benchmarkHelper.startPhase(CompilerBenchmarkHelper.GENERATE, unit.getSource().getNameForReporting());

    if (unit.hasTypeInfo)
    {
      return;
    }

    for (int i = 0, length = compilerExtensions.size(); i < length; i++)
    {
      compilerExtensions.get(i).generate(unit, null);

      if (ThreadLocalToolkit.errorCount() > 0)
      {
        return;
      }
    }

    Context cx = unit.getContext().removeAscContext();
    As3Compiler.cleanSlots(unit.typeInfo, cx, unit.topLevelDefinitions);
    cx.setHandler(null);

        if (benchmarkHelper != null)
            benchmarkHelper.endPhase(CompilerBenchmarkHelper.GENERATE);
  }

  public void postprocess(CompilationUnit unit, SymbolTable symbolTable)
  {
  }

    private void inheritSlots(CompilationUnit unit, Set<Name> types, SymbolTable symbolTable)
  {
    CompilerContext context = unit.getContext();
    ProgramNode node = (ProgramNode) unit.getSyntaxTree();
   
    Context cx = context.getAscContext();
       
    @SuppressWarnings("unchecked")
    Set<String> processed = (Set<String>) context.getAttribute("processed");

    for (Name name : types)
    {
      if (name instanceof flex2.compiler.util.QName)
      {
        flex2.compiler.util.QName qName = (flex2.compiler.util.QName) name;

        Source s = symbolTable.findSourceByQName(qName);
        CompilationUnit u = s.getCompilationUnit();
        if (unit == u)
        {
          continue;
        }
       
        ObjectValue frame = u.typeInfo;

        if (frame != null && !processed.contains(s.getName()))
        {
          //ThreadLocalToolkit.logDebug("import: " + s.getName() + " --> " + target);
          FlowAnalyzer.inheritContextSlots(frame, node.frame, node.frame.builder, cx);
          processed.add(s.getName());
        }
      }
    }
  }

  public static void copyBytecodes(Source source, CompilationUnit unit)
  {
    try
    {
      byte[] abc = source.toByteArray();

      if (abc == null)
      {
        abc = FileUtils.toByteArray(source.getInputStream());
      }

      if (abc == null || abc.length == 0)
      {
        ThreadLocalToolkit.log(new NoBytecodeIsAvailable(), source);
      }
      else
      {
          unit.bytes.set(abc, abc.length);
      }
    }
    catch (IOException ex)
    {
      ThreadLocalToolkit.logError(source.getNameForReporting(), ex.getLocalizedMessage());
    }
  }

  // error messages

  public static class NoBytecodeIsAvailable extends CompilerMessage.CompilerError
  {
    private static final long serialVersionUID = 2620612567115987550L;

        public NoBytecodeIsAvailable()
    {
      super();
    }
  }

  public static class BytecodeDecodingFailed extends CompilerMessage.CompilerError
  {
    private static final long serialVersionUID = -4085468421158774443L;

        public BytecodeDecodingFailed()
    {
      super();
    }
  }
}
TOP

Related Classes of flex2.compiler.abc.AbcCompiler$BytecodeDecodingFailed

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.