use of com.codename1.ui.List in project CodenameOne by codenameone.
the class SMSShare method share.
/**
* {@inheritDoc}
*/
public void share(final String toShare) {
final Form currentForm = Display.getInstance().getCurrent();
final Form contactsForm = new Form("Contacts");
contactsForm.setScrollable(false);
contactsForm.setLayout(new BorderLayout());
contactsForm.addComponent(BorderLayout.CENTER, new Label("Please wait..."));
contactsForm.show();
Display.getInstance().startThread(new Runnable() {
public void run() {
String[] ids = ContactsManager.getAllContacts();
if (ids == null || ids.length == 0) {
Display.getInstance().callSerially(new Runnable() {
public void run() {
Dialog.show("Failed to Share", "No Contacts Found", "Ok", null);
currentForm.showBack();
}
});
return;
}
ContactsModel model = new ContactsModel(ids);
final List contacts = new List(model);
contacts.setRenderer(createListRenderer());
Display.getInstance().callSerially(new Runnable() {
public void run() {
contacts.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
final ShareForm[] f = new ShareForm[1];
final Hashtable contact = (Hashtable) contacts.getSelectedItem();
f[0] = new ShareForm(contactsForm, "Send SMS", (String) contact.get("phone"), toShare, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
try {
Display.getInstance().sendSMS(f[0].getTo(), f[0].getMessage());
} catch (IOException ex) {
Log.e(ex);
System.out.println("failed to send sms to " + (String) contact.get("phone"));
}
finish();
}
});
f[0].show();
}
});
contactsForm.addComponent(BorderLayout.CENTER, contacts);
Command back = new Command("Back") {
public void actionPerformed(ActionEvent evt) {
currentForm.showBack();
}
};
contactsForm.addCommand(back);
contactsForm.setBackCommand(back);
contactsForm.revalidate();
}
});
}
}, "SMS Thread").start();
}
use of com.codename1.ui.List in project CodenameOne by codenameone.
the class LazyValueC method getFormState.
/**
* Returns the state of the current form which we are about to leave as part
* of the navigation logic. When a back command will return to this form the
* state would be restored using setFormState.
* The default implementation of this method restores focus and list selection.
* You can add arbitrary keys to the form state, keys starting with a $ sign
* are reserved for the UIBuilder base class use.
*
* @param f the form whose state should be preserved
* @return arbitrary state object
*/
protected Hashtable getFormState(Form f) {
Component c = f.getFocused();
Hashtable h = new Hashtable();
// can happen if we navigate away from a form that was shown without the GUI builder
if (f.getName() != null) {
h.put(FORM_STATE_KEY_NAME, f.getName());
}
if (c != null) {
if (c instanceof List) {
h.put(FORM_STATE_KEY_SELECTION, new Integer(((List) c).getSelectedIndex()));
}
if (c.getName() != null) {
h.put(FORM_STATE_KEY_FOCUS, c.getName());
}
if (f.getTitle() != null) {
h.put(FORM_STATE_KEY_TITLE, f.getTitle());
}
}
storeComponentState(f, h);
return h;
}
use of com.codename1.ui.List in project CodenameOne by codenameone.
the class LazyValueC method createComponent.
private Component createComponent(DataInputStream in, Container parent, Container root, Resources res, Hashtable componentListeners, EmbeddedContainer embedded) throws Exception {
String name = in.readUTF();
int property = in.readInt();
// special case for the base form
if (property == PROPERTY_BASE_FORM) {
String baseFormName = name;
initBaseForm(baseFormName);
if (!ignorBaseForm) {
Form base = (Form) createContainer(res, baseFormName);
Container destination = (Container) findByName("destination", base);
// try finding an appropriate empty container if no "fixed" destination is defined
if (destination == null) {
destination = findEmptyContainer(base.getContentPane());
if (destination == null) {
System.out.println("Couldn't find appropriate 'destination' container in base form: " + baseFormName);
return null;
}
}
root = base;
Component cmp = createComponent(in, destination, root, res, componentListeners, embedded);
if (destination.getLayout() instanceof BorderLayout) {
destination.addComponent(BorderLayout.CENTER, cmp);
} else {
destination.addComponent(cmp);
}
return root;
} else {
name = in.readUTF();
property = in.readInt();
}
}
Component cmp = createComponentType(name);
if (componentListeners != null) {
Object listeners = componentListeners.get(name);
if (listeners != null) {
if (listeners instanceof Vector) {
Vector v = (Vector) listeners;
for (int iter = 0; iter < v.size(); iter++) {
bindListenerToComponent(cmp, v.elementAt(iter));
}
} else {
bindListenerToComponent(cmp, listeners);
}
}
}
Component actualLead = cmp;
if (actualLead instanceof Container) {
Container cnt = (Container) actualLead;
actualLead = cnt.getLeadComponent();
if (actualLead == null) {
actualLead = cmp;
}
}
if (actualLead instanceof Button) {
ActionListener l = getFormListenerInstance(root, embedded);
if (l != null) {
((Button) actualLead).addActionListener(l);
}
} else {
if (actualLead instanceof TextArea) {
ActionListener l = getFormListenerInstance(root, embedded);
if (l != null) {
((TextArea) actualLead).addActionListener(l);
}
} else {
if (actualLead instanceof List) {
ActionListener l = getFormListenerInstance(root, embedded);
if (l != null) {
((List) actualLead).addActionListener(l);
}
} else {
if (actualLead instanceof ContainerList) {
ActionListener l = getFormListenerInstance(root, embedded);
if (l != null) {
((ContainerList) actualLead).addActionListener(l);
}
} else {
if (actualLead instanceof com.codename1.ui.Calendar) {
ActionListener l = getFormListenerInstance(root, embedded);
if (l != null) {
((com.codename1.ui.Calendar) actualLead).addActionListener(l);
}
}
}
}
}
}
cmp.putClientProperty(TYPE_KEY, name);
if (root == null) {
root = (Container) cmp;
}
while (property != -1) {
modifyingProperty(cmp, property);
switch(property) {
case PROPERTY_CUSTOM:
String customPropertyName = in.readUTF();
modifyingCustomProperty(cmp, customPropertyName);
boolean isNull = in.readBoolean();
if (isNull) {
cmp.setPropertyValue(customPropertyName, null);
break;
}
boolean cl = cmp instanceof ContainerList;
String[] propertyNames = cmp.getPropertyNames();
for (int iter = 0; iter < propertyNames.length; iter++) {
if (propertyNames[iter].equals(customPropertyName)) {
Class type = cmp.getPropertyTypes()[iter];
String[] typeNames = cmp.getPropertyTypeNames();
String typeName = null;
if (typeNames != null && typeNames.length > iter) {
typeName = typeNames[iter];
}
Object value = readCustomPropertyValue(in, type, typeName, res, propertyNames[iter]);
if (cl && customPropertyName.equals("ListItems") && setListModel((ContainerList) cmp)) {
break;
}
cmp.setPropertyValue(customPropertyName, value);
break;
}
}
break;
case PROPERTY_EMBED:
root.putClientProperty(EMBEDDED_FORM_FLAG, "");
((EmbeddedContainer) cmp).setEmbed(in.readUTF());
Container embed = createContainer(res, ((EmbeddedContainer) cmp).getEmbed(), (EmbeddedContainer) cmp);
if (embed != null) {
if (embed instanceof Form) {
embed = formToContainer((Form) embed);
}
((EmbeddedContainer) cmp).addComponent(BorderLayout.CENTER, embed);
// this isn't exactly the "right thing" but its the best we can do to make all
// use cases work
beforeShowContainer(embed);
postShowContainer(embed);
}
break;
case PROPERTY_TOGGLE_BUTTON:
((Button) cmp).setToggle(in.readBoolean());
break;
case PROPERTY_RADIO_GROUP:
((RadioButton) cmp).setGroup(in.readUTF());
break;
case PROPERTY_SELECTED:
boolean isSelected = in.readBoolean();
if (cmp instanceof RadioButton) {
((RadioButton) cmp).setSelected(isSelected);
} else {
((CheckBox) cmp).setSelected(isSelected);
}
break;
case PROPERTY_SCROLLABLE_X:
((Container) cmp).setScrollableX(in.readBoolean());
break;
case PROPERTY_SCROLLABLE_Y:
((Container) cmp).setScrollableY(in.readBoolean());
break;
case PROPERTY_TENSILE_DRAG_ENABLED:
cmp.setTensileDragEnabled(in.readBoolean());
break;
case PROPERTY_TACTILE_TOUCH:
cmp.setTactileTouch(in.readBoolean());
break;
case PROPERTY_SNAP_TO_GRID:
cmp.setSnapToGrid(in.readBoolean());
break;
case PROPERTY_FLATTEN:
cmp.setFlatten(in.readBoolean());
break;
case PROPERTY_TEXT:
if (cmp instanceof Label) {
((Label) cmp).setText(in.readUTF());
} else {
((TextArea) cmp).setText(in.readUTF());
}
break;
case PROPERTY_TEXT_MAX_LENGTH:
((TextArea) cmp).setMaxSize(in.readInt());
break;
case PROPERTY_TEXT_CONSTRAINT:
((TextArea) cmp).setConstraint(in.readInt());
if (cmp instanceof TextField) {
int cons = ((TextArea) cmp).getConstraint();
if ((cons & TextArea.NUMERIC) == TextArea.NUMERIC) {
((TextField) cmp).setInputModeOrder(new String[] { "123" });
}
}
break;
case PROPERTY_ALIGNMENT:
if (cmp instanceof Label) {
((Label) cmp).setAlignment(in.readInt());
} else {
((TextArea) cmp).setAlignment(in.readInt());
}
break;
case PROPERTY_TEXT_AREA_GROW:
((TextArea) cmp).setGrowByContent(in.readBoolean());
break;
case PROPERTY_LAYOUT:
Layout layout = null;
switch(in.readShort()) {
case LAYOUT_BORDER_LEGACY:
layout = new BorderLayout();
break;
case LAYOUT_BORDER_ANOTHER_LEGACY:
{
BorderLayout b = new BorderLayout();
if (in.readBoolean()) {
b.defineLandscapeSwap(BorderLayout.NORTH, in.readUTF());
}
if (in.readBoolean()) {
b.defineLandscapeSwap(BorderLayout.EAST, in.readUTF());
}
if (in.readBoolean()) {
b.defineLandscapeSwap(BorderLayout.WEST, in.readUTF());
}
if (in.readBoolean()) {
b.defineLandscapeSwap(BorderLayout.SOUTH, in.readUTF());
}
if (in.readBoolean()) {
b.defineLandscapeSwap(BorderLayout.CENTER, in.readUTF());
}
layout = b;
break;
}
case LAYOUT_BORDER:
{
BorderLayout b = new BorderLayout();
if (in.readBoolean()) {
b.defineLandscapeSwap(BorderLayout.NORTH, in.readUTF());
}
if (in.readBoolean()) {
b.defineLandscapeSwap(BorderLayout.EAST, in.readUTF());
}
if (in.readBoolean()) {
b.defineLandscapeSwap(BorderLayout.WEST, in.readUTF());
}
if (in.readBoolean()) {
b.defineLandscapeSwap(BorderLayout.SOUTH, in.readUTF());
}
if (in.readBoolean()) {
b.defineLandscapeSwap(BorderLayout.CENTER, in.readUTF());
}
b.setAbsoluteCenter(in.readBoolean());
layout = b;
break;
}
case LAYOUT_BOX_X:
layout = new BoxLayout(BoxLayout.X_AXIS);
break;
case LAYOUT_BOX_Y:
layout = new BoxLayout(BoxLayout.Y_AXIS);
break;
case LAYOUT_FLOW_LEGACY:
layout = new FlowLayout();
break;
case LAYOUT_FLOW:
FlowLayout f = new FlowLayout();
f.setFillRows(in.readBoolean());
f.setAlign(in.readInt());
f.setValign(in.readInt());
layout = f;
break;
case LAYOUT_LAYERED:
layout = new LayeredLayout();
break;
case LAYOUT_GRID:
layout = new GridLayout(in.readInt(), in.readInt());
break;
case LAYOUT_TABLE:
layout = new TableLayout(in.readInt(), in.readInt());
break;
}
((Container) cmp).setLayout(layout);
break;
case PROPERTY_TAB_PLACEMENT:
((Tabs) cmp).setTabPlacement(in.readInt());
break;
case PROPERTY_TAB_TEXT_POSITION:
((Tabs) cmp).setTabTextPosition(in.readInt());
break;
case PROPERTY_PREFERRED_WIDTH:
cmp.setPreferredW(in.readInt());
break;
case PROPERTY_PREFERRED_HEIGHT:
cmp.setPreferredH(in.readInt());
break;
case PROPERTY_UIID:
cmp.setUIID(in.readUTF());
break;
case PROPERTY_DIALOG_UIID:
((Dialog) cmp).setDialogUIID(in.readUTF());
break;
case PROPERTY_DISPOSE_WHEN_POINTER_OUT:
((Dialog) cmp).setDisposeWhenPointerOutOfBounds(in.readBoolean());
break;
case PROPERTY_CLOUD_BOUND_PROPERTY:
cmp.setCloudBoundProperty(in.readUTF());
break;
case PROPERTY_CLOUD_DESTINATION_PROPERTY:
cmp.setCloudDestinationProperty(in.readUTF());
break;
case PROPERTY_DIALOG_POSITION:
String pos = in.readUTF();
if (pos.length() > 0) {
((Dialog) cmp).setDialogPosition(pos);
}
break;
case PROPERTY_FOCUSABLE:
cmp.setFocusable(in.readBoolean());
break;
case PROPERTY_ENABLED:
cmp.setEnabled(in.readBoolean());
break;
case PROPERTY_SCROLL_VISIBLE:
cmp.setScrollVisible(in.readBoolean());
break;
case PROPERTY_ICON:
((Label) cmp).setIcon(res.getImage(in.readUTF()));
break;
case PROPERTY_ROLLOVER_ICON:
((Button) cmp).setRolloverIcon(res.getImage(in.readUTF()));
break;
case PROPERTY_PRESSED_ICON:
((Button) cmp).setPressedIcon(res.getImage(in.readUTF()));
break;
case PROPERTY_DISABLED_ICON:
((Button) cmp).setDisabledIcon(res.getImage(in.readUTF()));
break;
case PROPERTY_GAP:
((Label) cmp).setGap(in.readInt());
break;
case PROPERTY_VERTICAL_ALIGNMENT:
if (cmp instanceof TextArea) {
((TextArea) cmp).setVerticalAlignment(in.readInt());
} else {
((Label) cmp).setVerticalAlignment(in.readInt());
}
break;
case PROPERTY_TEXT_POSITION:
((Label) cmp).setTextPosition(in.readInt());
break;
case PROPERTY_CLIENT_PROPERTIES:
int count = in.readInt();
StringBuilder sb = new StringBuilder();
for (int iter = 0; iter < count; iter++) {
String k = in.readUTF();
String v = in.readUTF();
cmp.putClientProperty(k, v);
sb.append(k);
if (iter < count - 1) {
sb.append(",");
}
}
cmp.putClientProperty("cn1$Properties", sb.toString());
break;
case PROPERTY_NAME:
String componentName = in.readUTF();
cmp.setName(componentName);
root.putClientProperty("%" + componentName + "%", cmp);
break;
case PROPERTY_LAYOUT_CONSTRAINT:
if (parent.getLayout() instanceof BorderLayout) {
cmp.putClientProperty("layoutConstraint", in.readUTF());
} else {
TableLayout tl = (TableLayout) parent.getLayout();
TableLayout.Constraint con = tl.createConstraint(in.readInt(), in.readInt());
con.setHeightPercentage(in.readInt());
con.setWidthPercentage(in.readInt());
con.setHorizontalAlign(in.readInt());
con.setHorizontalSpan(in.readInt());
con.setVerticalAlign(in.readInt());
con.setVerticalSpan(in.readInt());
cmp.putClientProperty("layoutConstraint", con);
}
break;
case PROPERTY_TITLE:
((Form) cmp).setTitle(in.readUTF());
break;
case PROPERTY_COMPONENTS:
int componentCount = in.readInt();
if (cmp instanceof Tabs) {
for (int iter = 0; iter < componentCount; iter++) {
String tab = in.readUTF();
Component child = createComponent(in, (Container) cmp, root, res, componentListeners, embedded);
((Tabs) cmp).addTab(tab, child);
}
} else {
for (int iter = 0; iter < componentCount; iter++) {
Component child = createComponent(in, (Container) cmp, root, res, componentListeners, embedded);
Object con = child.getClientProperty("layoutConstraint");
if (con != null) {
((Container) cmp).addComponent(con, child);
} else {
((Container) cmp).addComponent(child);
}
}
}
break;
case PROPERTY_COLUMNS:
((TextArea) cmp).setColumns(in.readInt());
break;
case PROPERTY_ROWS:
((TextArea) cmp).setRows(in.readInt());
break;
case PROPERTY_HINT:
if (cmp instanceof List) {
((List) cmp).setHint(in.readUTF());
} else {
((TextArea) cmp).setHint(in.readUTF());
}
break;
case PROPERTY_HINT_ICON:
if (cmp instanceof List) {
((List) cmp).setHintIcon(res.getImage(in.readUTF()));
} else {
((TextArea) cmp).setHintIcon(res.getImage(in.readUTF()));
}
break;
case PROPERTY_ITEM_GAP:
((List) cmp).setItemGap(in.readInt());
break;
case PROPERTY_LIST_FIXED:
((List) cmp).setFixedSelection(in.readInt());
break;
case PROPERTY_LIST_ORIENTATION:
((List) cmp).setOrientation(in.readInt());
break;
case PROPERTY_LIST_ITEMS_LEGACY:
String[] items = new String[in.readInt()];
for (int iter = 0; iter < items.length; iter++) {
items[iter] = in.readUTF();
}
if (!setListModel(((List) cmp))) {
((List) cmp).setModel(new DefaultListModel((Object[]) items));
}
break;
case PROPERTY_LIST_ITEMS:
Object[] elements = readObjectArrayForListModel(in, res);
if (!setListModel(((List) cmp))) {
((List) cmp).setModel(new DefaultListModel(elements));
}
break;
case PROPERTY_LIST_RENDERER:
if (cmp instanceof ContainerList) {
((ContainerList) cmp).setRenderer(readRendererer(res, in));
} else {
((List) cmp).setRenderer(readRendererer(res, in));
}
break;
case PROPERTY_NEXT_FORM:
String nextForm = in.readUTF();
setNextForm(cmp, nextForm, res, root);
break;
case PROPERTY_COMMANDS:
readCommands(in, cmp, res, false);
break;
case PROPERTY_COMMANDS_LEGACY:
readCommands(in, cmp, res, true);
break;
case PROPERTY_CYCLIC_FOCUS:
((Form) cmp).setCyclicFocus(in.readBoolean());
break;
case PROPERTY_RTL:
cmp.setRTL(in.readBoolean());
break;
case PROPERTY_SLIDER_THUMB:
((Slider) cmp).setThumbImage(res.getImage(in.readUTF()));
break;
case PROPERTY_INFINITE:
((Slider) cmp).setInfinite(in.readBoolean());
break;
case PROPERTY_PROGRESS:
((Slider) cmp).setProgress(in.readInt());
break;
case PROPERTY_VERTICAL:
((Slider) cmp).setVertical(in.readBoolean());
break;
case PROPERTY_EDITABLE:
if (cmp instanceof TextArea) {
((TextArea) cmp).setEditable(in.readBoolean());
} else {
((Slider) cmp).setEditable(in.readBoolean());
}
break;
case PROPERTY_INCREMENTS:
((Slider) cmp).setIncrements(in.readInt());
break;
case PROPERTY_RENDER_PERCENTAGE_ON_TOP:
((Slider) cmp).setRenderPercentageOnTop(in.readBoolean());
break;
case PROPERTY_MAX_VALUE:
((Slider) cmp).setMaxValue(in.readInt());
break;
case PROPERTY_MIN_VALUE:
((Slider) cmp).setMinValue(in.readInt());
break;
}
property = in.readInt();
}
postCreateComponent(cmp);
return cmp;
}
use of com.codename1.ui.List in project CodenameOne by codenameone.
the class ComponentTreeModel method getIndexOfChild.
public int getIndexOfChild(Object parent, Object child) {
Component cmp = (Component) parent;
Component chd = (Component) child;
if (cmp instanceof List || cmp instanceof ContainerList) {
if (chd.hasFocus()) {
return 1;
}
return 0;
}
if (cmp instanceof Container) {
return ((Container) cmp).getComponentIndex(chd);
}
return -1;
}
use of com.codename1.ui.List in project CodenameOne by codenameone.
the class BytecodeMethod method optimize.
boolean optimize() {
int instructionCount = instructions.size();
// optimize away a method that only contains the void return instruction e.g. blank constructors etc.
if (instructionCount < 6) {
int realCount = instructionCount;
Instruction actual = null;
for (int iter = 0; iter < instructionCount; iter++) {
Instruction current = instructions.get(iter);
if (current instanceof LabelInstruction) {
realCount--;
continue;
}
if (current instanceof LineNumber) {
realCount--;
continue;
}
actual = current;
}
if (realCount == 1 && actual != null && actual.getOpcode() == Opcodes.RETURN) {
return false;
}
}
boolean astoreCalls = false;
boolean hasInstructions = false;
boolean hasTryCatch = false;
for (int iter = 0; iter < instructionCount - 1; iter++) {
Instruction current = instructions.get(iter);
if (current instanceof TryCatch) {
hasTryCatch = true;
}
current.setMethod(this);
if (current.isOptimized()) {
continue;
}
int currentOpcode = current.getOpcode();
switch(currentOpcode) {
case Opcodes.CHECKCAST:
{
// Remove the check cast for now as it gets in the way of other optimizations
instructions.remove(iter);
iter--;
instructionCount--;
break;
}
}
}
for (int iter = 0; iter < instructionCount - 1; iter++) {
Instruction current = instructions.get(iter);
if (current.isOptimized()) {
// we should skip it and proceed to the next one
continue;
}
Instruction next = instructions.get(iter + 1);
int currentOpcode = current.getOpcode();
int nextOpcode = next.getOpcode();
if (ArithmeticExpression.isArithmeticOp(current)) {
int addedIndex = ArithmeticExpression.tryReduce(instructions, iter);
if (addedIndex >= 0) {
iter = addedIndex;
instructionCount = instructions.size();
continue;
}
}
if (current instanceof Field) {
int newIter = Field.tryReduce(instructions, iter);
if (newIter >= 0) {
iter = newIter;
instructionCount = instructions.size();
continue;
}
}
switch(currentOpcode) {
case Opcodes.ARRAYLENGTH:
{
if (!dependentClasses.contains("java_lang_NullPointerException")) {
dependentClasses.add("java_lang_NullPointerException");
}
int newIter = ArrayLengthExpression.tryReduce(instructions, iter);
if (newIter >= 0) {
instructionCount = instructions.size();
iter = newIter;
continue;
}
break;
}
case Opcodes.DUP:
{
int newIter = DupExpression.tryReduce(instructions, iter);
if (newIter >= 0) {
iter = newIter;
instructionCount = instructions.size();
continue;
}
break;
}
case Opcodes.POP:
{
if (iter > 0) {
Instruction prev = instructions.get(iter - 1);
if (prev instanceof CustomInvoke) {
CustomInvoke inv = (CustomInvoke) prev;
if (inv.methodHasReturnValue()) {
inv.setNoReturn(true);
instructions.remove(iter);
iter--;
instructionCount--;
continue;
}
}
}
break;
}
case Opcodes.ASTORE:
case Opcodes.ISTORE:
case Opcodes.DSTORE:
case Opcodes.LSTORE:
case Opcodes.FSTORE:
{
if (iter > 0 && current instanceof VarOp) {
VarOp currentVarOp = (VarOp) current;
Instruction prev = instructions.get(iter - 1);
if (prev instanceof AssignableExpression) {
AssignableExpression expr = (AssignableExpression) prev;
StringBuilder sb = new StringBuilder();
if (currentVarOp.assignFrom(expr, sb)) {
instructions.remove(iter - 1);
instructions.remove(iter - 1);
instructions.add(iter - 1, new CustomIntruction(sb.toString(), sb.toString(), dependentClasses));
iter = iter - 1;
instructionCount = instructions.size();
continue;
}
} else if (prev instanceof CustomInvoke) {
CustomInvoke inv = (CustomInvoke) prev;
StringBuilder sb = new StringBuilder();
if (currentVarOp.assignFrom(inv, sb)) {
instructions.remove(iter - 1);
instructions.remove(iter - 1);
instructions.add(iter - 1, new CustomIntruction(sb.toString(), sb.toString(), dependentClasses));
iter = iter - 1;
instructionCount = instructions.size();
continue;
}
}
}
break;
}
case Opcodes.IRETURN:
case Opcodes.FRETURN:
case Opcodes.ARETURN:
case Opcodes.LRETURN:
case Opcodes.DRETURN:
{
if (iter > 0 && current instanceof BasicInstruction) {
Instruction prev = instructions.get(iter - 1);
if (prev instanceof AssignableExpression) {
AssignableExpression expr = (AssignableExpression) prev;
StringBuilder sb = new StringBuilder();
if (expr.assignTo(null, sb)) {
instructions.remove(iter - 1);
instructions.remove(iter - 1);
String exprString = sb.toString().trim();
String retVal = exprString;
sb.setLength(0);
if (!prev.isConstant()) {
sb.append("\n{\n ");
switch(currentOpcode) {
case Opcodes.IRETURN:
sb.append("JAVA_INT");
break;
case Opcodes.FRETURN:
sb.append("JAVA_FLOAT");
break;
case Opcodes.ARETURN:
sb.append("JAVA_OBJECT");
break;
case Opcodes.LRETURN:
sb.append("JAVA_LONG");
break;
case Opcodes.DRETURN:
sb.append("JAVA_DOUBLE");
break;
}
sb.append(" ___returnValue=").append(exprString).append(";\n");
retVal = "___returnValue";
}
if (synchronizedMethod) {
if (staticMethod) {
sb.append(" monitorExit(threadStateData, (JAVA_OBJECT)&class__");
sb.append(getClsName());
sb.append(");\n");
} else {
sb.append(" monitorExit(threadStateData, __cn1ThisObject);\n");
}
}
if (hasTryCatch) {
sb.append(" releaseForReturnInException(threadStateData, cn1LocalsBeginInThread, methodBlockOffset); return ").append(retVal).append(";\n");
} else {
sb.append(" releaseForReturn(threadStateData, cn1LocalsBeginInThread); return ").append(retVal).append(";\n");
}
if (!prev.isConstant()) {
sb.append("}\n");
}
instructions.add(iter - 1, new CustomIntruction(sb.toString(), sb.toString(), dependentClasses));
iter--;
instructionCount = instructions.size();
continue;
}
} else if (prev instanceof CustomInvoke) {
CustomInvoke expr = (CustomInvoke) prev;
String returnType = expr.getReturnValue();
if (returnType != null && !"JAVA_OBJECT".equals(returnType)) {
// We can't safely return a JAVA_OBJECT directly because it needs to be added
// to the stack for the GC
StringBuilder sb = new StringBuilder();
if (expr.appendExpression(sb)) {
instructions.remove(iter - 1);
instructions.remove(iter - 1);
String exprString = sb.toString().trim();
String retVal = exprString;
sb.setLength(0);
if (!expr.isConstant()) {
sb.append("\n{\n ");
switch(currentOpcode) {
case Opcodes.IRETURN:
sb.append("JAVA_INT");
break;
case Opcodes.FRETURN:
sb.append("JAVA_FLOAT");
break;
case Opcodes.ARETURN:
sb.append("JAVA_OBJECT");
break;
case Opcodes.LRETURN:
sb.append("JAVA_LONG");
break;
case Opcodes.DRETURN:
sb.append("JAVA_DOUBLE");
break;
}
sb.append(" ___returnValue=").append(exprString).append(";\n");
retVal = "___returnValue";
}
if (synchronizedMethod) {
if (staticMethod) {
sb.append(" monitorExit(threadStateData, (JAVA_OBJECT)&class__");
sb.append(getClsName());
sb.append(");\n");
} else {
sb.append(" monitorExit(threadStateData, __cn1ThisObject);\n");
}
}
if (hasTryCatch) {
sb.append(" releaseForReturnInException(threadStateData, cn1LocalsBeginInThread, methodBlockOffset); return ").append(retVal).append(";\n");
} else {
sb.append(" releaseForReturn(threadStateData, cn1LocalsBeginInThread); return ").append(retVal).append(";\n");
}
if (!expr.isConstant()) {
sb.append("}\n");
}
instructions.add(iter - 1, new CustomIntruction(sb.toString(), sb.toString(), dependentClasses));
iter--;
instructionCount = instructions.size();
continue;
}
}
}
}
break;
}
case Opcodes.BASTORE:
case Opcodes.SASTORE:
case Opcodes.CASTORE:
case Opcodes.AASTORE:
case Opcodes.IASTORE:
case Opcodes.DASTORE:
case Opcodes.LASTORE:
case Opcodes.FASTORE:
{
if (iter > 2 && current instanceof BasicInstruction) {
StringBuilder devNull = new StringBuilder();
String arrayLiteral = null;
String indexLiteral = null;
String valueLiteral = null;
Instruction prev3 = instructions.get(iter - 3);
if (prev3 instanceof AssignableExpression) {
if (((AssignableExpression) prev3).assignTo(null, devNull)) {
arrayLiteral = devNull.toString().trim();
}
}
devNull.setLength(0);
Instruction prev2 = instructions.get(iter - 2);
if (prev2 instanceof AssignableExpression) {
if (((AssignableExpression) prev2).assignTo(null, devNull)) {
indexLiteral = devNull.toString().trim();
}
}
devNull.setLength(0);
Instruction prev1 = instructions.get(iter - 1);
if (prev1 instanceof AssignableExpression) {
if (((AssignableExpression) prev1).assignTo(null, devNull)) {
valueLiteral = devNull.toString().trim();
}
} else if (prev1 instanceof CustomInvoke) {
devNull.setLength(0);
if (((CustomInvoke) prev1).appendExpression(devNull)) {
valueLiteral = devNull.toString().trim();
}
}
if (arrayLiteral != null && indexLiteral != null && valueLiteral != null) {
String elementType = null;
switch(current.getOpcode()) {
case Opcodes.AASTORE:
elementType = "OBJECT";
break;
case Opcodes.IASTORE:
elementType = "INT";
break;
case Opcodes.DASTORE:
elementType = "DOUBLE";
break;
case Opcodes.LASTORE:
elementType = "LONG";
break;
case Opcodes.FASTORE:
elementType = "FLOAT";
break;
case Opcodes.CASTORE:
elementType = "CHAR";
break;
case Opcodes.BASTORE:
elementType = "BYTE";
break;
case Opcodes.SASTORE:
elementType = "SHORT";
break;
}
if (elementType == null) {
break;
}
instructions.remove(iter - 3);
instructions.remove(iter - 3);
instructions.remove(iter - 3);
instructions.remove(iter - 3);
String code = " CN1_SET_ARRAY_ELEMENT_" + elementType + "(" + arrayLiteral + ", " + indexLiteral + ", " + valueLiteral + ");\n";
instructions.add(iter - 3, new CustomIntruction(code, code, dependentClasses));
iter = iter - 3;
instructionCount = instructions.size();
continue;
}
}
break;
}
case Opcodes.FALOAD:
case Opcodes.BALOAD:
case Opcodes.IALOAD:
case Opcodes.LALOAD:
case Opcodes.DALOAD:
case Opcodes.AALOAD:
case Opcodes.SALOAD:
case Opcodes.CALOAD:
{
int newIter = ArrayLoadExpression.tryReduce(instructions, iter);
if (newIter >= 0) {
iter = newIter;
instructionCount = instructions.size();
continue;
}
break;
}
/* Try to optimize if statements that just use constants
and local variables so that they don't need the intermediate
push and pop from the stack.
*/
case Opcodes.IF_ACMPEQ:
case Opcodes.IF_ACMPNE:
case Opcodes.IF_ICMPLE:
case Opcodes.IF_ICMPLT:
case Opcodes.IF_ICMPNE:
case Opcodes.IF_ICMPGT:
case Opcodes.IF_ICMPEQ:
case Opcodes.IF_ICMPGE:
{
if (iter > 1) {
Instruction leftArg = instructions.get(iter - 2);
Instruction rightArg = instructions.get(iter - 1);
String leftLiteral = null;
String rightLiteral = null;
if (leftArg instanceof AssignableExpression) {
StringBuilder sb = new StringBuilder();
if (((AssignableExpression) leftArg).assignTo(null, sb)) {
leftLiteral = sb.toString().trim();
}
} else if (leftArg instanceof CustomInvoke) {
CustomInvoke inv = (CustomInvoke) leftArg;
StringBuilder sb = new StringBuilder();
if (!"JAVA_OBJECT".equals(inv.getReturnValue()) && inv.appendExpression(sb)) {
leftLiteral = sb.toString().trim();
}
}
if (rightArg instanceof AssignableExpression) {
StringBuilder sb = new StringBuilder();
if (((AssignableExpression) rightArg).assignTo(null, sb)) {
rightLiteral = sb.toString().trim();
}
} else if (rightArg instanceof CustomInvoke) {
CustomInvoke inv = (CustomInvoke) rightArg;
StringBuilder sb = new StringBuilder();
if (!"JAVA_OBJECT".equals(inv.getReturnValue()) && inv.appendExpression(sb)) {
rightLiteral = sb.toString().trim();
}
}
if (rightLiteral != null && leftLiteral != null) {
Jump jmp = (Jump) current;
instructions.remove(iter - 2);
instructions.remove(iter - 2);
instructions.remove(iter - 2);
// instructions.remove(iter-2);
iter -= 2;
// instructionCount -= 2;
StringBuilder sb = new StringBuilder();
String operator = null;
String opName = null;
switch(currentOpcode) {
case Opcodes.IF_ICMPLE:
operator = "<=";
opName = "IF_ICMPLE";
break;
case Opcodes.IF_ICMPLT:
operator = "<";
opName = "IF_IMPLT";
break;
case Opcodes.IF_ICMPNE:
operator = "!=";
opName = "IF_ICMPNE";
break;
case Opcodes.IF_ICMPGT:
operator = ">";
opName = "IF_ICMPGT";
break;
case Opcodes.IF_ICMPGE:
operator = ">=";
opName = "IF_ICMPGE";
break;
case Opcodes.IF_ICMPEQ:
operator = "==";
opName = "IF_ICMPEQ";
break;
case Opcodes.IF_ACMPEQ:
operator = "==";
opName = "IF_ACMPEQ";
break;
case Opcodes.IF_ACMPNE:
operator = "!=";
opName = "IF_ACMPNE";
break;
default:
throw new RuntimeException("Invalid operator during optimization of integer comparison");
}
sb.append("if (").append(leftLiteral).append(operator).append(rightLiteral).append(") /* ").append(opName).append(" CustomJump */ ");
CustomJump newJump = CustomJump.create(jmp, sb.toString());
// jmp.setCustomCompareCode(sb.toString());
newJump.setOptimized(true);
instructions.add(iter, newJump);
instructionCount = instructions.size();
}
}
break;
}
case Opcodes.IFNONNULL:
case Opcodes.IFNULL:
case Opcodes.IFLE:
case Opcodes.IFLT:
case Opcodes.IFNE:
case Opcodes.IFGT:
case Opcodes.IFEQ:
case Opcodes.IFGE:
{
String rightArg = "0";
if (currentOpcode == Opcodes.IFNONNULL || currentOpcode == Opcodes.IFNULL) {
rightArg = "JAVA_NULL";
}
if (iter > 0) {
Instruction leftArg = instructions.get(iter - 1);
String leftLiteral = null;
if (leftArg instanceof AssignableExpression) {
StringBuilder sb = new StringBuilder();
if (((AssignableExpression) leftArg).assignTo(null, sb)) {
leftLiteral = sb.toString().trim();
}
} else if (leftArg instanceof CustomInvoke) {
CustomInvoke inv = (CustomInvoke) leftArg;
StringBuilder sb = new StringBuilder();
if (inv.appendExpression(sb)) {
leftLiteral = sb.toString().trim();
}
}
if (leftLiteral != null) {
Jump jmp = (Jump) current;
instructions.remove(iter - 1);
instructions.remove(iter - 1);
// instructions.remove(iter-2);
iter -= 1;
// instructionCount -= 2;
StringBuilder sb = new StringBuilder();
String operator = null;
String opName = null;
switch(currentOpcode) {
case Opcodes.IFLE:
operator = "<=";
opName = "IFLE";
break;
case Opcodes.IFLT:
operator = "<";
opName = "IFLT";
break;
case Opcodes.IFNE:
operator = "!=";
opName = "IFNE";
break;
case Opcodes.IFGT:
operator = ">";
opName = "IFGT";
break;
case Opcodes.IFGE:
operator = ">=";
opName = "IFGE";
break;
case Opcodes.IFEQ:
operator = "==";
opName = "IFEQ";
break;
case Opcodes.IFNULL:
operator = "==";
opName = "IFNULL";
break;
case Opcodes.IFNONNULL:
operator = "!=";
opName = "IFNONNULL";
break;
default:
throw new RuntimeException("Invalid operator during optimization of integer comparison");
}
sb.append("if (").append(leftLiteral).append(operator).append(rightArg).append(") /* ").append(opName).append(" CustomJump */ ");
CustomJump newJump = CustomJump.create(jmp, sb.toString());
// jmp.setCustomCompareCode(sb.toString());
newJump.setOptimized(true);
instructions.add(iter, newJump);
instructionCount = instructions.size();
}
}
break;
}
case Opcodes.INVOKEVIRTUAL:
case Opcodes.INVOKESTATIC:
case Opcodes.INVOKESPECIAL:
case Opcodes.INVOKEINTERFACE:
{
if (current instanceof Invoke) {
Invoke inv = (Invoke) current;
List<ByteCodeMethodArg> invocationArgs = inv.getArgs();
int numArgs = invocationArgs.size();
// }
if (iter >= numArgs) {
String[] argLiterals = new String[numArgs];
StringBuilder devNull = new StringBuilder();
for (int i = 0; i < numArgs; i++) {
devNull.setLength(0);
Instruction instr = instructions.get(iter - numArgs + i);
if (instr instanceof AssignableExpression && ((AssignableExpression) instr).assignTo(null, devNull)) {
argLiterals[i] = devNull.toString().trim();
} else if (instr instanceof CustomInvoke) {
CustomInvoke cinv = (CustomInvoke) instr;
devNull.setLength(0);
if (!"JAVA_OBJECT".equals(cinv.getReturnValue()) && cinv.appendExpression(devNull)) {
// We can't add invocations that return objects directly
// because they need to be added to the stack for GC
argLiterals[i] = devNull.toString().trim();
}
} else if (instr instanceof ArithmeticExpression) {
argLiterals[i] = ((ArithmeticExpression) instr).getExpressionAsString().trim();
} else if (instr instanceof VarOp) {
VarOp var = (VarOp) instr;
switch(instr.getOpcode()) {
case Opcodes.ALOAD:
{
if (!isStatic() && var.getIndex() == 0) {
argLiterals[i] = "__cn1ThisObject";
} else {
argLiterals[i] = "locals[" + var.getIndex() + "].data.o";
}
break;
}
case Opcodes.ILOAD:
{
argLiterals[i] = "ilocals_" + var.getIndex() + "_";
break;
}
case Opcodes.ACONST_NULL:
{
argLiterals[i] = "JAVA_NULL";
break;
}
case Opcodes.DLOAD:
{
argLiterals[i] = "dlocals_" + var.getIndex() + "_";
break;
}
case Opcodes.FLOAD:
{
argLiterals[i] = "flocals_" + var.getIndex() + "_";
break;
}
case Opcodes.LLOAD:
{
argLiterals[i] = "llocals_" + var.getIndex() + "_";
break;
}
case Opcodes.ICONST_0:
{
argLiterals[i] = "0";
break;
}
case Opcodes.ICONST_1:
{
argLiterals[i] = "1";
break;
}
case Opcodes.ICONST_2:
{
argLiterals[i] = "2";
break;
}
case Opcodes.ICONST_3:
{
argLiterals[i] = "3";
break;
}
case Opcodes.ICONST_4:
{
argLiterals[i] = "4";
break;
}
case Opcodes.ICONST_5:
{
argLiterals[i] = "5";
break;
}
case Opcodes.ICONST_M1:
{
argLiterals[i] = "-1";
break;
}
case Opcodes.LCONST_0:
{
argLiterals[i] = "(JAVA_LONG)0";
break;
}
case Opcodes.LCONST_1:
{
argLiterals[i] = "(JAVA_LONG)1";
break;
}
case Opcodes.BIPUSH:
case Opcodes.SIPUSH:
{
argLiterals[i] = String.valueOf(var.getIndex());
break;
}
}
} else {
switch(instr.getOpcode()) {
case Opcodes.ACONST_NULL:
{
argLiterals[i] = "JAVA_NULL";
break;
}
case Opcodes.ICONST_0:
{
argLiterals[i] = "0";
break;
}
case Opcodes.ICONST_1:
{
argLiterals[i] = "1";
break;
}
case Opcodes.ICONST_2:
{
argLiterals[i] = "2";
break;
}
case Opcodes.ICONST_3:
{
argLiterals[i] = "3";
break;
}
case Opcodes.ICONST_4:
{
argLiterals[i] = "4";
break;
}
case Opcodes.ICONST_5:
{
argLiterals[i] = "5";
break;
}
case Opcodes.ICONST_M1:
{
argLiterals[i] = "-1";
break;
}
case Opcodes.LCONST_0:
{
argLiterals[i] = "(JAVA_LONG)0";
break;
}
case Opcodes.LCONST_1:
{
argLiterals[i] = "(JAVA_LONG)1";
break;
}
case Opcodes.BIPUSH:
{
if (instr instanceof BasicInstruction) {
argLiterals[i] = String.valueOf(((BasicInstruction) instr).getValue());
}
break;
}
case Opcodes.LDC:
{
if (instr instanceof Ldc) {
Ldc ldc = (Ldc) instr;
argLiterals[i] = ldc.getValueAsString();
}
break;
}
}
}
}
// Check to make sure that we have all the args as literals.
boolean missingLiteral = false;
for (String lit : argLiterals) {
if (lit == null) {
missingLiteral = true;
break;
}
}
// add them to our invoke instruction.
if (!missingLiteral) {
CustomInvoke newInvoke = CustomInvoke.create(inv);
instructions.remove(iter);
instructions.add(iter, newInvoke);
int newIter = iter;
for (int i = 0; i < numArgs; i++) {
instructions.remove(iter - numArgs);
newIter--;
newInvoke.setLiteralArg(i, argLiterals[i]);
}
if (inv.getOpcode() != Opcodes.INVOKESTATIC) {
Instruction ldTarget = instructions.get(iter - numArgs - 1);
if (ldTarget instanceof AssignableExpression) {
StringBuilder targetExprStr = new StringBuilder();
if (((AssignableExpression) ldTarget).assignTo(null, targetExprStr)) {
newInvoke.setTargetObjectLiteral(targetExprStr.toString().trim());
instructions.remove(iter - numArgs - 1);
newIter--;
}
} else if (ldTarget instanceof CustomInvoke) {
// WE Can't pass a custom invoke as the target directly
// because it the return value needs to be added to the
// stack for the GC
} else {
switch(ldTarget.getOpcode()) {
case Opcodes.ALOAD:
{
VarOp v = (VarOp) ldTarget;
if (isStatic() && v.getIndex() == 0) {
newInvoke.setTargetObjectLiteral("__cn1ThisObject");
} else {
newInvoke.setTargetObjectLiteral("locals[" + v.getIndex() + "].data.o");
}
instructions.remove(iter - numArgs - 1);
newIter--;
break;
}
}
}
}
newInvoke.setOptimized(true);
// iter = 0;
instructionCount = instructions.size();
iter = newIter;
}
}
}
break;
}
}
astoreCalls = astoreCalls || currentOpcode == Opcodes.ASTORE || currentOpcode == Opcodes.ISTORE || currentOpcode == Opcodes.LSTORE || currentOpcode == Opcodes.DSTORE || currentOpcode == Opcodes.FSTORE;
hasInstructions = hasInstructions | current.getOpcode() != -1;
}
return hasInstructions;
}
Aggregations