private static <T> void generateDeserialize(ClassDefinition definition, Class<T> clazz, List<StateField> fields) { Parameter block = arg("block", Block.class); Parameter index = arg("index", int.class); Parameter state = arg("state", Object.class); MethodDefinition method = definition.declareMethod(a(PUBLIC), "deserialize", type(void.class), block, index, state); BytecodeBlock deserializerBody = method.getBody(); if (fields.size() == 1) { Method setter = getSetter(clazz, fields.get(0)); Method blockGetter = getBlockGetter(setter.getParameterTypes()[0]); deserializerBody.append(state.cast(setter.getDeclaringClass()).invoke(setter, invokeStatic(blockGetter, block, index))); } else { Variable slice = method.getScope().declareVariable(Slice.class, "slice"); deserializerBody.append(slice.set(block.invoke("getSlice", Slice.class, index, constantInt(0), block.invoke("getLength", int.class, index)))); for (StateField field : fields) { Method setter = getSetter(clazz, field); Method getter = getSliceGetter(setter.getParameterTypes()[0]); int offset = offsetOfField(field, fields); deserializerBody.append(state.cast(setter.getDeclaringClass()).invoke(setter, invokeStatic(getter, slice, constantInt(offset)))); } } deserializerBody.ret(); }
private static <T> void generateSerialize(ClassDefinition definition, Class<T> clazz, List<StateField> fields) { Parameter state = arg("state", Object.class); Parameter out = arg("out", BlockBuilder.class); MethodDefinition method = definition.declareMethod(a(PUBLIC), "serialize", type(void.class), state, out); BytecodeBlock serializerBody = method.getBody(); if (fields.size() == 1) { Method getter = getGetter(clazz, fields.get(0)); Method append = getBlockBuilderAppend(getter.getReturnType()); serializerBody.append(invokeStatic(append, out, state.cast(getter.getDeclaringClass()).invoke(getter))); } else { Variable slice = method.getScope().declareVariable(Slice.class, "slice"); BytecodeExpression size = constantInt(serializedSizeOf(clazz)); serializerBody.append(slice.set(invokeStatic(Slices.class, "allocate", Slice.class, size))); for (StateField field : fields) { Method getter = getGetter(clazz, field); Method sliceSetter = getSliceSetter(getter.getReturnType()); serializerBody.append(invokeStatic(sliceSetter, slice, constantInt(offsetOfField(field, fields)), state.cast(getter.getDeclaringClass()).invoke(getter))); } serializerBody.append(out.invoke("writeBytes", BlockBuilder.class, slice, constantInt(0), size) .invoke("closeEntry", BlockBuilder.class) .pop()); } serializerBody.ret(); }