public void doBuild(InstructionBuilder builder) { invokeNavigateMethod(builder); builder.loadArgument(1).castOrUnbox(PlasticUtils.toTypeName(field.getType())); builder.putField(field.getDeclaringClass().getName(), field.getName(), field.getType()); builder.returnResult(); } });
String getInstanceContextFieldName() { if (instanceContextFieldName == null) { instanceContextFieldName = makeUnique(fieldNames, "instanceContext"); // TODO: We could use a protected field and only initialize // it once, in the first base class where it is needed, though that raises the possibilities // of name conflicts (a subclass might introduce a field with a conflicting name). FieldNode node = new FieldNode(ACC_PRIVATE | ACC_FINAL, instanceContextFieldName, INSTANCE_CONTEXT_DESC, null, null); classNode.fields.add(node); // Extend the constructor to store the context in a field. constructorBuilder.loadThis().loadArgument(1) .putField(className, instanceContextFieldName, InstanceContext.class); } return instanceContextFieldName; }
String getInstanceContextFieldName() { if (instanceContextFieldName == null) { instanceContextFieldName = makeUnique(fieldNames, "instanceContext"); // TODO: We could use a protected field and only initialize // it once, in the first base class where it is needed, though that raises the possibilities // of name conflicts (a subclass might introduce a field with a conflicting name). FieldNode node = new FieldNode(ACC_PRIVATE | ACC_FINAL, instanceContextFieldName, INSTANCE_CONTEXT_DESC, null, null); classNode.fields.add(node); // Extend the constructor to store the context in a field. constructorBuilder.loadThis().loadArgument(1) .putField(className, instanceContextFieldName, InstanceContext.class); } return instanceContextFieldName; }
@Override public void doBuild(InstructionBuilder builder) { builder.loadThis().loadArgument(0); builder.putField(plasticClass.className, node.name, getTypeName()); builder.returnResult(); } });
@Override public void doBuild(InstructionBuilder builder) { builder.loadThis().loadArgument(0); builder.putField(plasticClass.className, node.name, getTypeName()); builder.returnResult(); } });
/** * Adds a static setter method, allowing an external FieldAccess implementation * to directly set the value of the field. */ private MethodNode addShimSetAccessMethod() { String name = plasticClass.makeUnique(plasticClass.methodNames, "shim_set_" + node.name); // Takes two Object parameters (instance, and value) and returns void. MethodNode mn = new MethodNode(Opcodes.ACC_SYNTHETIC | Opcodes.ACC_FINAL, name, "(" + node.desc + ")V", null, null); InstructionBuilder builder = plasticClass.newBuilder(mn); builder.loadThis().loadArgument(0).putField(plasticClass.className, node.name, typeName); builder.returnResult(); plasticClass.addMethod(mn); plasticClass.fieldTransformMethods.add(mn); return mn; }
/** * Adds a static setter method, allowing an external FieldAccess implementation * to directly set the value of the field. */ private MethodNode addShimSetAccessMethod() { String name = plasticClass.makeUnique(plasticClass.methodNames, "shim_set_" + node.name); // Takes two Object parameters (instance, and value) and returns void. MethodNode mn = new MethodNode(Opcodes.ACC_SYNTHETIC | Opcodes.ACC_FINAL, name, "(" + node.desc + ")V", null, null); InstructionBuilder builder = plasticClass.newBuilder(mn); builder.loadThis().loadArgument(0).putField(plasticClass.className, node.name, typeName); builder.returnResult(); plasticClass.addMethod(mn); plasticClass.fieldTransformMethods.add(mn); return mn; }
builder.putField(invocationClassName, name, type);
/** * 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); }
/** * 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(); } }
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(); } }
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 PlasticField injectFromInstanceContext() { plasticClass.check(); verifyInitialState("inject instance context value into"); // Easiest to load this, for the putField(), early, in case the field is // wide (long or double primitive) plasticClass.constructorBuilder.loadThis(); // Add the InstanceContext to the stack plasticClass.constructorBuilder.loadArgument(1); plasticClass.constructorBuilder.loadConstant(typeName); plasticClass.constructorBuilder.invokeStatic(PlasticInternalUtils.class, Object.class, "getFromInstanceContext", InstanceContext.class, String.class).castOrUnbox(typeName); plasticClass.constructorBuilder.putField(plasticClass.className, node.name, typeName); makeReadOnly(); state = FieldState.INJECTED; return this; }
@Override public PlasticField injectFromInstanceContext() { plasticClass.check(); verifyInitialState("inject instance context value into"); // Easiest to load this, for the putField(), early, in case the field is // wide (long or double primitive) plasticClass.constructorBuilder.loadThis(); // Add the InstanceContext to the stack plasticClass.constructorBuilder.loadArgument(1); plasticClass.constructorBuilder.loadConstant(typeName); plasticClass.constructorBuilder.invokeStatic(PlasticInternalUtils.class, Object.class, "getFromInstanceContext", InstanceContext.class, String.class).castOrUnbox(typeName); plasticClass.constructorBuilder.putField(plasticClass.className, node.name, typeName); makeReadOnly(); state = FieldState.INJECTED; return this; }
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); }
builder.putField(plasticClass.className, node.name, typeName);
builder.putField(plasticClass.className, node.name, typeName);