private void invokeCallback(ConstructorCallback callback) { int index = staticContext.store(callback); // First, load the callback constructorBuilder.loadArgument(0).loadConstant(index).invoke(STATIC_CONTEXT_GET_METHOD).castOrUnbox(ConstructorCallback.class.getName()); // Load this and the InstanceContext constructorBuilder.loadThis().loadArgument(1); constructorBuilder.invoke(CONSTRUCTOR_CALLBACK_METHOD); }
private void invokeMethod(InstructionBuilder builder, PlasticMethod method) { // First, tell the Event object what method is being invoked. builder.loadArgument(1); builder.loadConstant( method.getMethodIdentifier()); builder.invoke(Event.class, void.class, "setMethodDescription", String.class); builder.loadThis(); // Methods either take no parameters, or take a MarkupWriter parameter. if (method.getParameters().size() > 0) { builder.loadArgument(0); } builder.invokeVirtual(method); // Non-void methods will pass a value to the event. if (!method.isVoid()) { builder.boxPrimitive(method.getDescription().returnType); builder.loadArgument(1).swap(); builder.invoke(Event.class, boolean.class, "storeResult", Object.class); builder.when(Condition.NON_ZERO, JUST_RETURN); } }
private Type implementListConstructor(InstructionBuilder builder, Tree listNode) { // First, create an empty instance of ArrayList int count = listNode.getChildCount(); builder.newInstance(ArrayList.class); builder.dupe().loadConstant(count).invokeConstructor(ArrayList.class, int.class); for (int i = 0; i < count; i++) { builder.dupe(); // the ArrayList Type expressionType = implementSubexpression(builder, null, listNode.getChild(i)); boxIfPrimitive(builder, GenericsUtils.asClass(expressionType)); // Add the value to the array, then pop off the returned boolean builder.invoke(ArrayListMethods.ADD).pop(); } return ArrayList.class; }
private void invokeCallback(ConstructorCallback callback) { int index = staticContext.store(callback); // First, load the callback constructorBuilder.loadArgument(0).loadConstant(index).invoke(STATIC_CONTEXT_GET_METHOD).castOrUnbox(ConstructorCallback.class.getName()); // Load this and the InstanceContext constructorBuilder.loadThis().loadArgument(1); constructorBuilder.invoke(CONSTRUCTOR_CALLBACK_METHOD); }
private Type implementMapConstructor(InstructionBuilder builder, Tree mapNode) { int count = mapNode.getChildCount(); builder.newInstance(HashMap.class); builder.dupe().loadConstant(count).invokeConstructor(HashMap.class, int.class); for (int i = 0; i < count; i += 2) { builder.dupe(); //build the key: Type keyType = implementSubexpression(builder, null, mapNode.getChild(i)); boxIfPrimitive(builder, GenericsUtils.asClass(keyType)); //and the value: Type valueType = implementSubexpression(builder, null, mapNode.getChild(i + 1)); boxIfPrimitive(builder, GenericsUtils.asClass(valueType)); //put the value into the array, then pop off the returned object. builder.invoke(HashMapMethods.PUT).pop(); } return HashMap.class; }
public void doBuild(InstructionBuilder builder) { invokeNavigateMethod(builder); Class propertyType = writeMethod.getParameterTypes()[0]; String propertyTypeName = PlasticUtils.toTypeName(propertyType); builder.loadArgument(1).castOrUnbox(propertyTypeName); builder.invoke(writeMethod); builder.returnResult(); } });
private void initializeComputedField(ComputedValue<?> computedValue) { int index = plasticClass.staticContext.store(computedValue); plasticClass.constructorBuilder.loadThis(); // for the putField() // Get the ComputedValue out of the StaticContext and onto the stack plasticClass.constructorBuilder.loadArgument(0).loadConstant(index); plasticClass.constructorBuilder.invoke(PlasticClassImpl.STATIC_CONTEXT_GET_METHOD).checkcast(ComputedValue.class); // Add the InstanceContext to the stack plasticClass.constructorBuilder.loadArgument(1); plasticClass.constructorBuilder.invoke(PlasticClassImpl.COMPUTED_VALUE_GET_METHOD).castOrUnbox(typeName); plasticClass.constructorBuilder.putField(plasticClass.className, node.name, typeName); }
private void initializeComputedField(ComputedValue<?> computedValue) { int index = plasticClass.staticContext.store(computedValue); plasticClass.constructorBuilder.loadThis(); // for the putField() // Get the ComputedValue out of the StaticContext and onto the stack plasticClass.constructorBuilder.loadArgument(0).loadConstant(index); plasticClass.constructorBuilder.invoke(PlasticClassImpl.STATIC_CONTEXT_GET_METHOD).checkcast(ComputedValue.class); // Add the InstanceContext to the stack plasticClass.constructorBuilder.loadArgument(1); plasticClass.constructorBuilder.invoke(PlasticClassImpl.COMPUTED_VALUE_GET_METHOD).castOrUnbox(typeName); plasticClass.constructorBuilder.putField(plasticClass.className, node.name, typeName); }
@Override public void doBuild(final LocalVariable invocation, InstructionBuilder builder) { builder.dupe().storeVariable(invocation); builder.invoke(AbstractMethodInvocation.class, MethodInvocation.class, "proceed"); if (description.checkedExceptionTypes.length > 0) { builder.invoke(MethodInvocation.class, boolean.class, "didThrowCheckedException"); builder.when(Condition.NON_ZERO, new InstructionBuilderCallback() { @Override public void doBuild(InstructionBuilder builder) { builder.loadVariable(invocation).loadTypeConstant(Exception.class); builder.invokeVirtual(invocationClassName, Throwable.class.getName(), "getCheckedException", Class.class.getName()); builder.throwException(); } }); } if (!isVoid) { builder.loadVariable(invocation).getField(invocationClassName, RETURN_VALUE, description.returnType); } builder.returnResult(); } });
private void bridgeToClojure(InstructionBuilder builder, MethodDescription description, PlasticField ifnField) { builder.loadThis().getField(ifnField); int count = description.argumentTypes.length; Class[] invokeParameterTypes = new Class[count]; for (int i = 0; i < count; i++) { invokeParameterTypes[i] = Object.class; builder.loadArgument(i).boxPrimitive(description.argumentTypes[i]); } Method ifnMethod = null; try { ifnMethod = IFn.class.getMethod("invoke", invokeParameterTypes); } catch (NoSuchMethodException ex) { throw new RuntimeException(String.format("Unable to find correct IFn.invoke() method: %s", ExceptionUtils.toMessage(ex)), ex); } builder.invoke(ifnMethod); builder.castOrUnbox(description.returnType); builder.returnResult(); } });
/** * Initializes a field from the static context. The injected value is added to the static * context and the class constructor updated to assign the value from the context (which includes casting and * possibly unboxing). */ void initializeFieldFromStaticContext(String fieldName, String fieldType, Object injectedFieldValue) { int index = staticContext.store(injectedFieldValue); // Although it feels nicer to do the loadThis() later and then swap(), that breaks // on primitive longs and doubles, so its just easier to do the loadThis() first // so its at the right place on the stack for the putField(). constructorBuilder.loadThis(); constructorBuilder.loadArgument(0).loadConstant(index); constructorBuilder.invoke(STATIC_CONTEXT_GET_METHOD); constructorBuilder.castOrUnbox(fieldType); constructorBuilder.putField(className, fieldName, fieldType); }
public Class implementNotExpression(InstructionBuilder builder, final Tree notNode) { Type expressionType = implementSubexpression(builder, null, notNode.getChild(0)); boxIfPrimitive(builder, expressionType); // Now invoke the delegate invert() method builder.loadThis().getField(getDelegateField()); builder.swap().invoke(DelegateMethods.INVERT); return boolean.class; }
/** * Initializes a field from the static context. The injected value is added to the static * context and the class constructor updated to assign the value from the context (which includes casting and * possibly unboxing). */ void initializeFieldFromStaticContext(String fieldName, String fieldType, Object injectedFieldValue) { int index = staticContext.store(injectedFieldValue); // Although it feels nicer to do the loadThis() later and then swap(), that breaks // on primitive longs and doubles, so its just easier to do the loadThis() first // so its at the right place on the stack for the putField(). constructorBuilder.loadThis(); constructorBuilder.loadArgument(0).loadConstant(index); constructorBuilder.invoke(STATIC_CONTEXT_GET_METHOD); constructorBuilder.castOrUnbox(fieldType); constructorBuilder.putField(className, fieldName, fieldType); }
private void addReturnValueSetter() { InstructionBuilder builder = newMethod("setReturnValue", MethodInvocation.class, Object.class); if (isVoid) { builder.throwException(IllegalArgumentException.class, String .format("Method %s of class %s is void, setting a return value is not allowed.", description, plasticClass.className)); } else { builder.loadThis().loadArgument(0); builder.castOrUnbox(description.returnType); builder.putField(invocationClassName, RETURN_VALUE, description.returnType); builder.loadThis().invoke(AbstractMethodInvocation.class, void.class, "clearCheckedException"); builder.loadThis().returnResult(); } }
public void doBuild(InstructionBuilder builder) { if (!reverse && !isRoot) { addSuperCall(builder); builder.loadArgument(1).invoke(Event.class, boolean.class, "isAborted"); builder.when(Condition.NON_ZERO, JUST_RETURN); } for (PlasticMethod invokedMethod : orderedMethods) { invokeMethod(builder, invokedMethod); } if (reverse && !isRoot) { addSuperCall(builder); } builder.returnDefaultValue(); } });
private void addReturnValueSetter() { InstructionBuilder builder = newMethod("setReturnValue", MethodInvocation.class, Object.class); if (isVoid) { builder.throwException(IllegalArgumentException.class, String .format("Method %s of class %s is void, setting a return value is not allowed.", description, plasticClass.className)); } else { builder.loadThis().loadArgument(0); builder.castOrUnbox(description.returnType); builder.putField(invocationClassName, RETURN_VALUE, description.returnType); builder.loadThis().invoke(AbstractMethodInvocation.class, void.class, "clearCheckedException"); builder.loadThis().returnResult(); } }
@Override public void doBuild(InstructionBuilder builder) { builder.loadThis().getField(filterField); int argumentIndex = 0; for (int i = 0; i < fms.getParameterTypes().length; i++) { if (i == position) { builder.loadThis().getField(nextField); } else { builder.loadArgument(argumentIndex++); } } builder.invoke(fms.getMethod()).returnResult(); } });
@Override public void doBuild(InstructionBuilder builder) { builder.loadThis().getField(filterField); int argumentIndex = 0; for (int i = 0; i < fms.getParameterTypes().length; i++) { if (i == position) { builder.loadThis().getField(nextField); } else { builder.loadArgument(argumentIndex++); } } builder.invoke(fms.getMethod()).returnResult(); } });
private void replaceFieldWriteAccess(String conduitFieldName) { ensureNotPublic(); String setAccessName = plasticClass.makeUnique(plasticClass.methodNames, "conduit_set_" + node.name); setAccess = new MethodNode(accessForMethod(), setAccessName, "(" + node.desc + ")V", null, null); InstructionBuilder builder = plasticClass.newBuilder(setAccess); pushFieldConduitOntoStack(conduitFieldName, builder); builder.loadThis(); plasticClass.pushInstanceContextFieldOntoStack(builder); // Take the value passed to this method and push it onto the stack. builder.loadArgument(0); builder.boxPrimitive(typeName); builder.invoke(FieldConduit.class, void.class, "set", Object.class, InstanceContext.class, Object.class); if (isWriteBehindEnabled()) { builder.loadThis().loadArgument(0).putField(plasticClass.className, node.name, typeName); } builder.returnResult(); plasticClass.addMethod(setAccess); plasticClass.redirectFieldWrite(node.name, isPrivate(), setAccess); }
private void replaceFieldWriteAccess(String conduitFieldName) { ensureNotPublic(); String setAccessName = plasticClass.makeUnique(plasticClass.methodNames, "conduit_set_" + node.name); setAccess = new MethodNode(accessForMethod(), setAccessName, "(" + node.desc + ")V", null, null); InstructionBuilder builder = plasticClass.newBuilder(setAccess); pushFieldConduitOntoStack(conduitFieldName, builder); builder.loadThis(); plasticClass.pushInstanceContextFieldOntoStack(builder); // Take the value passed to this method and push it onto the stack. builder.loadArgument(0); builder.boxPrimitive(typeName); builder.invoke(FieldConduit.class, void.class, "set", Object.class, InstanceContext.class, Object.class); if (isWriteBehindEnabled()) { builder.loadThis().loadArgument(0).putField(plasticClass.className, node.name, typeName); } builder.returnResult(); plasticClass.addMethod(setAccess); plasticClass.redirectFieldWrite(node.name, isPrivate(), setAccess); }