All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.dev.shell.rewrite.RewriteRefsToJsoClasses Maven / Gradle / Ivy

/*
 * Copyright 2008 Google Inc.
 *
 * Licensed 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 com.google.gwt.dev.shell.rewrite;

import com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.InstanceMethodOracle;

import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.Remapper;

import java.util.Set;

/**
 * Rewrites references to modified JSO subtypes.
 *
 * 
    *
  1. Changes the owner type for instructions that reference items in a JSO * class to the implementation class.
  2. *
  3. Rewrites instance calls to JSO classes into static calls.
  4. *
  5. Updates the descriptor for such call sites to includes a synthetic * this parameter. This modified method has same stack behavior * as the original instance method.
  6. *
*/ class RewriteRefsToJsoClasses extends ClassVisitor { /** * A method body rewriter to actually rewrite call sites. */ private class MyMethodAdapter extends MethodVisitor { private Remapper remapper = new Remapper() { @Override public String map(String typeName) { if (jsoDescriptors.contains(typeName)) { return HostedModeClassRewriter.JAVASCRIPTOBJECT_IMPL_DESC; } return typeName; } }; public MyMethodAdapter(MethodVisitor mv) { super(Opcodes.ASM5, mv); } @Override public void visitFieldInsn(int opcode, String owner, String name, String desc) { if (jsoDescriptors.contains(owner)) { // Change the owner to the rewritten class. owner += "$"; } super.visitFieldInsn(opcode, owner, name, desc); } @Override public void visitLdcInsn(Object cst) { cst = remapper.mapValue(cst); super.visitLdcInsn(cst); } @Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean dintf) { if (jsoDescriptors.contains(owner)) { // Find the class that actually declared the method. if (opcode == Opcodes.INVOKEVIRTUAL) { owner = mapper.findOriginalDeclaringClass(owner, name + desc); } if (!owner.equals("java/lang/Object")) { if (opcode == Opcodes.INVOKEVIRTUAL || opcode == Opcodes.INVOKESPECIAL) { // Instance/super call to JSO; rewrite as static. opcode = Opcodes.INVOKESTATIC; desc = HostedModeClassRewriter.addSyntheticThisParam(owner, desc); name += "$"; } // Change the owner to implementation class. owner += "$"; } } super.visitMethodInsn(opcode, owner, name, desc, dintf); } @Override public void visitMultiANewArrayInsn(String desc, int dims) { desc = remapper.mapType(desc); super.visitMultiANewArrayInsn(desc, dims); } @Override public void visitTypeInsn(int opcode, String type) { if (opcode == Opcodes.ANEWARRAY) { type = remapper.mapType(type); } super.visitTypeInsn(opcode, type); } } /** * An unmodifiable set of descriptors containing JavaScriptObject * and all subclasses. */ protected final Set jsoDescriptors; /** * Maps methods to the class in which they are declared. */ private InstanceMethodOracle mapper; /** * Construct a new rewriter instance. * * @param cv the visitor to chain to * @param jsoDescriptors an unmodifiable set of descriptors containing * JavaScriptObject and all subclasses * @param mapper maps methods to the class in which they are declared */ public RewriteRefsToJsoClasses(ClassVisitor cv, Set jsoDescriptors, InstanceMethodOracle mapper) { super(Opcodes.ASM5, cv); this.jsoDescriptors = jsoDescriptors; this.mapper = mapper; } @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { // Wrap the returned method visitor in my own. MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); return new MyMethodAdapter(mv); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy