Java源码示例:net.bytebuddy.implementation.bytecode.constant.IntegerConstant
示例1
/**
* {@inheritDoc}
*/
public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext) {
Size size = IntegerConstant.forValue(stackManipulations.size()).apply(methodVisitor, implementationContext);
// The array's construction does not alter the stack's size.
size = size.aggregate(arrayCreator.apply(methodVisitor, implementationContext));
int index = 0;
for (StackManipulation stackManipulation : stackManipulations) {
methodVisitor.visitInsn(Opcodes.DUP);
size = size.aggregate(StackSize.SINGLE.toIncreasingSize());
size = size.aggregate(IntegerConstant.forValue(index++).apply(methodVisitor, implementationContext));
size = size.aggregate(stackManipulation.apply(methodVisitor, implementationContext));
methodVisitor.visitInsn(arrayCreator.getStorageOpcode());
size = size.aggregate(sizeDecrease);
}
return size;
}
示例2
/**
* {@inheritDoc}
*/
public Size apply(MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) {
if (instrumentedMethod.isStatic()) {
throw new IllegalStateException("Hash code method must not be static: " + instrumentedMethod);
} else if (!instrumentedMethod.getReturnType().represents(int.class)) {
throw new IllegalStateException("Hash code method does not return primitive integer: " + instrumentedMethod);
}
List<StackManipulation> stackManipulations = new ArrayList<StackManipulation>(2 + fieldDescriptions.size() * 8);
stackManipulations.add(initialValue);
int padding = 0;
for (FieldDescription.InDefinedShape fieldDescription : fieldDescriptions) {
stackManipulations.add(IntegerConstant.forValue(multiplier));
stackManipulations.add(Multiplication.INTEGER);
stackManipulations.add(MethodVariableAccess.loadThis());
stackManipulations.add(FieldAccess.forField(fieldDescription).read());
NullValueGuard nullValueGuard = fieldDescription.getType().isPrimitive() || fieldDescription.getType().isArray() || nonNullable.matches(fieldDescription)
? NullValueGuard.NoOp.INSTANCE
: new NullValueGuard.UsingJump(instrumentedMethod);
stackManipulations.add(nullValueGuard.before());
stackManipulations.add(ValueTransformer.of(fieldDescription.getType()));
stackManipulations.add(Addition.INTEGER);
stackManipulations.add(nullValueGuard.after());
padding = Math.max(padding, nullValueGuard.getRequiredVariablePadding());
}
stackManipulations.add(MethodReturn.INTEGER);
return new Size(new StackManipulation.Compound(stackManipulations).apply(methodVisitor, implementationContext).getMaximalSize(), instrumentedMethod.getStackSize() + padding);
}
示例3
/**
* {@inheritDoc}
*/
public Size apply(MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) {
if (instrumentedMethod.isStatic()) {
throw new IllegalStateException("Hash code method must not be static: " + instrumentedMethod);
} else if (instrumentedMethod.getParameters().size() != 1 || instrumentedMethod.getParameters().getOnly().getType().isPrimitive()) {
throw new IllegalStateException();
} else if (!instrumentedMethod.getReturnType().represents(boolean.class)) {
throw new IllegalStateException("Hash code method does not return primitive boolean: " + instrumentedMethod);
}
List<StackManipulation> stackManipulations = new ArrayList<StackManipulation>(3 + fieldDescriptions.size() * 8);
stackManipulations.add(baseline);
int padding = 0;
for (FieldDescription.InDefinedShape fieldDescription : fieldDescriptions) {
stackManipulations.add(MethodVariableAccess.loadThis());
stackManipulations.add(FieldAccess.forField(fieldDescription).read());
stackManipulations.add(MethodVariableAccess.REFERENCE.loadFrom(1));
stackManipulations.add(TypeCasting.to(instrumentedType));
stackManipulations.add(FieldAccess.forField(fieldDescription).read());
NullValueGuard nullValueGuard = fieldDescription.getType().isPrimitive() || fieldDescription.getType().isArray() || nonNullable.matches(fieldDescription)
? NullValueGuard.NoOp.INSTANCE
: new NullValueGuard.UsingJump(instrumentedMethod);
stackManipulations.add(nullValueGuard.before());
stackManipulations.add(ValueComparator.of(fieldDescription.getType()));
stackManipulations.add(nullValueGuard.after());
padding = Math.max(padding, nullValueGuard.getRequiredVariablePadding());
}
stackManipulations.add(IntegerConstant.forValue(true));
stackManipulations.add(MethodReturn.INTEGER);
return new Size(new StackManipulation.Compound(stackManipulations).apply(methodVisitor, implementationContext).getMaximalSize(), instrumentedMethod.getStackSize() + padding);
}
示例4
/**
* {@inheritDoc}
*/
public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext, MethodDescription instrumentedMethod) {
try {
return new ByteCodeAppender.Simple(new StackManipulation.Compound(
MethodInvocation.invoke(new MethodDescription.ForLoadedMethod(ClassLoader.class.getMethod("getSystemClassLoader"))),
new TextConstant(Nexus.class.getName()),
MethodInvocation.invoke(new MethodDescription.ForLoadedMethod(ClassLoader.class.getMethod("loadClass", String.class))),
new TextConstant("initialize"),
ArrayFactory.forType(TypeDescription.Generic.CLASS)
.withValues(Arrays.asList(
ClassConstant.of(TypeDescription.CLASS),
ClassConstant.of(TypeDescription.ForLoadedType.of(int.class)))),
MethodInvocation.invoke(new MethodDescription.ForLoadedMethod(Class.class.getMethod("getMethod", String.class, Class[].class))),
NullConstant.INSTANCE,
ArrayFactory.forType(TypeDescription.Generic.OBJECT)
.withValues(Arrays.asList(
ClassConstant.of(instrumentedMethod.getDeclaringType().asErasure()),
new StackManipulation.Compound(
IntegerConstant.forValue(identification),
MethodInvocation.invoke(new MethodDescription.ForLoadedMethod(Integer.class.getMethod("valueOf", int.class)))))),
MethodInvocation.invoke(new MethodDescription.ForLoadedMethod(Method.class.getMethod("invoke", Object.class, Object[].class))),
Removal.SINGLE
)).apply(methodVisitor, implementationContext, instrumentedMethod);
} catch (NoSuchMethodException exception) {
throw new IllegalStateException("Cannot locate method", exception);
}
}
示例5
public Size apply(MethodVisitor methodVisitor,
Implementation.Context implementationContext,
MethodDescription instrumentedMethod) {
if (!instrumentedMethod.getReturnType().asErasure().represents(int.class)) {
throw new IllegalArgumentException(instrumentedMethod + " must return int");
}
StackManipulation.Size operandStackSize = new StackManipulation.Compound(
IntegerConstant.forValue(10),
IntegerConstant.forValue(50),
IntegerSum.INSTANCE,
MethodReturn.INTEGER
).apply(methodVisitor, implementationContext);
return new Size(operandStackSize.getMaximalSize(), instrumentedMethod.getStackSize());
}
示例6
@Test
public void testForEach() throws Exception {
StackManipulation stackManipulation = mock(StackManipulation.class);
assertThat(ArrayAccess.REFERENCE.forEach(Collections.singletonList(stackManipulation)),
hasPrototype((StackManipulation) new StackManipulation.Compound(new StackManipulation.Compound(Duplication.SINGLE,
IntegerConstant.forValue(0),
ArrayAccess.REFERENCE.new Loader(),
stackManipulation))));
}
示例7
/**
* Retrurns a {@link StackManipulation} that checks whether the value in the message is a default
* value, and if so jumps to after serialization to skip the serialization of the default value.
* e.g.,
*
* <pre>{code
* if (message.getFoo() != field.getDefaultValue) {
* ...
* }
* // afterSerializeField
* }</pre>
*/
private static StackManipulation checkDefaultValue(
ProtoFieldInfo info,
LocalVariables<LocalVariable> locals,
StackManipulation getValue,
StackManipulation getDefaultInstance,
Label afterSerializeField) {
if (info.isInOneof()) {
// For one-ofs, we can just check the set field number directly.
return new StackManipulation.Compound(
locals.load(LocalVariable.message),
CodeGenUtil.invoke(info.oneOfCaseMethod()),
EnumLite_getNumber,
IntegerConstant.forValue(info.descriptor().getNumber()),
new IfIntsNotEqual(afterSerializeField));
} else if (!info.isRepeated()) {
switch (info.valueJavaType()) {
case INT:
return checkPrimitiveDefault(
getValue,
IntegerConstant.forValue((int) info.descriptor().getDefaultValue()),
int.class,
afterSerializeField);
case LONG:
return checkPrimitiveDefault(
getValue,
LongConstant.forValue((long) info.descriptor().getDefaultValue()),
long.class,
afterSerializeField);
case FLOAT:
return checkPrimitiveDefault(
getValue,
FloatConstant.forValue((float) info.descriptor().getDefaultValue()),
float.class,
afterSerializeField);
case DOUBLE:
return checkPrimitiveDefault(
getValue,
DoubleConstant.forValue((double) info.descriptor().getDefaultValue()),
double.class,
afterSerializeField);
case BOOLEAN:
return checkPrimitiveDefault(
getValue,
IntegerConstant.forValue((boolean) info.descriptor().getDefaultValue()),
boolean.class,
afterSerializeField);
case ENUM:
return checkPrimitiveDefault(
getValue,
IntegerConstant.forValue(
((EnumValueDescriptor) info.descriptor().getDefaultValue()).getNumber()),
int.class,
afterSerializeField);
case STRING:
return new StackManipulation.Compound(
getValue,
new TextConstant((String) info.descriptor().getDefaultValue()),
Object_equals,
new IfEqual(Object.class, afterSerializeField));
case BYTE_STRING:
// We'll use the default instance to get the default value for types that can't be
// loaded into the constant pool. Since it's a constant, the somewhat indirect reference
// should get inlined and be the same as a class constant.
return new StackManipulation.Compound(
getValue,
getDefaultInstance,
invoke(info.getValueMethod()),
Object_equals,
new IfEqual(Object.class, afterSerializeField));
case MESSAGE:
return new StackManipulation.Compound(
locals.load(LocalVariable.message),
invoke(info.hasValueMethod()),
new IfFalse(afterSerializeField));
default:
throw new IllegalStateException("Unknown JavaType: " + info.valueJavaType());
}
} else {
return new StackManipulation.Compound(
locals.load(LocalVariable.message),
CodeGenUtil.invoke(info.repeatedValueCountMethod()),
new IfFalse(afterSerializeField));
}
}
示例8
/**
* Returns the {@link StackManipulation} for setting the value of a normal repeated field.
*
* <p>Roughly equivalent to:
*
* <pre>{@code
* ParseSupport.parseArrayStart(parser);
* while (!ParseSupport.checkArrayEnd(parser)) {
* builder.addFoo(readValue());
* }
* }</pre>
*/
private StackManipulation setRepeatedFieldValue(
ProtoFieldInfo info,
Label beforeReadField,
LocalVariables<LocalVariable> locals,
Map<String, FieldDescription> fieldsByName,
StackManipulation setSingleValue) {
Label arrayStart = new Label();
StackManipulation.Compound beforeRead =
new StackManipulation.Compound(
locals.load(LocalVariable.parser),
ParseSupport_parseArrayStart,
new SetJumpTargetLabel(arrayStart),
locals.load(LocalVariable.parser),
ParseSupport_throwIfRepeatedNull,
locals.load(LocalVariable.parser),
ParseSupport_checkArrayEnd,
new IfTrue(beforeReadField));
Label afterSet = new Label();
StackManipulation.Compound setValueAndPrepareForNext =
new StackManipulation.Compound(
setSingleValue,
Removal.SINGLE,
new SetJumpTargetLabel(afterSet),
locals.load(LocalVariable.parser),
Parser_nextValue,
Removal.SINGLE,
new Goto(arrayStart));
if (info.valueType() == Type.ENUM) {
// We special-case enum since we may need to skip unknown values.
return new StackManipulation.Compound(
beforeRead,
locals.load(LocalVariable.parser),
readValue(info, fieldsByName, locals),
locals.store(LocalVariable.intvalue),
locals.load(LocalVariable.intvalue),
IntegerConstant.forValue(-1),
new IfEqual(int.class, afterSet),
locals.load(LocalVariable.builder),
locals.load(LocalVariable.intvalue),
setValueAndPrepareForNext);
} else {
return new StackManipulation.Compound(
beforeRead,
locals.load(LocalVariable.builder),
locals.load(LocalVariable.parser),
readValue(info, fieldsByName, locals),
setValueAndPrepareForNext);
}
}
示例9
/**
* Returns the {@link StackManipulation} for setting the value of a map field.
*
* <p>Roughly equivalent to:
*
* <pre>{@code
* ParseSupport.parseObjectStart(parser);
* while (!ParseSupport.checkObjectEnd(parser.currentToken())) {
* builder.putFoo(readKey(), readValue());
* }
* }</pre>
*/
private StackManipulation setMapFieldValue(
ProtoFieldInfo info,
Label beforeReadField,
LocalVariables<LocalVariable> locals,
Map<String, FieldDescription> fieldsByName) {
final StackManipulation setConcreteValue = invoke(info.setValueMethod());
final StackManipulation setMapEntry;
if (info.valueJavaType() == JavaType.MESSAGE) {
setMapEntry =
new StackManipulation.Compound(
TypeCasting.to(new ForLoadedType(info.javaClass())), setConcreteValue);
} else {
setMapEntry = setConcreteValue;
}
Label mapStart = new Label();
Label afterSet = new Label();
StackManipulation.Compound beforeReadKey =
new StackManipulation.Compound(
locals.load(LocalVariable.parser),
ParseSupport_parseObjectStart,
new SetJumpTargetLabel(mapStart),
locals.load(LocalVariable.parser),
Parser_currentToken,
ParseSupport_checkObjectEnd,
new IfTrue(beforeReadField));
StackManipulation.Compound setValueAndPrepareForNext =
new StackManipulation.Compound(
setMapEntry,
Removal.SINGLE,
new SetJumpTargetLabel(afterSet),
locals.load(LocalVariable.parser),
Parser_nextToken,
Removal.SINGLE,
new Goto(mapStart));
if (info.valueType() == Type.ENUM) {
// We special-case enum since we may need to skip unknown values.
final LocalVariable keyVar;
switch (info.mapKeyField().valueJavaType()) {
case INT:
keyVar = LocalVariable.intMapKey;
break;
case LONG:
keyVar = LocalVariable.longMapKey;
break;
case BOOLEAN:
keyVar = LocalVariable.boolMapKey;
break;
case STRING:
keyVar = LocalVariable.stringMapKey;
break;
default:
throw new IllegalArgumentException("Invalid map key type");
}
return new StackManipulation.Compound(
beforeReadKey,
locals.load(LocalVariable.parser),
readValue(info.mapKeyField(), fieldsByName, locals),
locals.store(keyVar),
locals.load(LocalVariable.parser),
Parser_nextToken,
Removal.SINGLE,
locals.load(LocalVariable.parser),
readValue(info, fieldsByName, locals),
locals.store(LocalVariable.intvalue),
locals.load(LocalVariable.intvalue),
IntegerConstant.forValue(-1),
new IfEqual(int.class, afterSet),
locals.load(LocalVariable.builder),
locals.load(keyVar),
locals.load(LocalVariable.intvalue),
setValueAndPrepareForNext);
} else {
return new StackManipulation.Compound(
beforeReadKey,
locals.load(LocalVariable.builder),
locals.load(LocalVariable.parser),
readValue(info.mapKeyField(), fieldsByName, locals),
locals.load(LocalVariable.parser),
Parser_nextToken,
Removal.SINGLE,
locals.load(LocalVariable.parser),
readValue(info, fieldsByName, locals),
setValueAndPrepareForNext);
}
}
示例10
/**
* Returns the {@link StackManipulation} for reading the JSON encoded value for the field. Just
* dispatches to {@link ParseSupport} based on the field type.
*/
private StackManipulation readValue(
ProtoFieldInfo field,
Map<String, FieldDescription> fieldsByName,
LocalVariables<LocalVariable> locals) {
switch (field.valueType()) {
case INT32:
case SINT32:
case SFIXED32:
return ParseSupport_parseInt32;
case INT64:
case SINT64:
case SFIXED64:
return ParseSupport_parseInt64;
case BOOL:
return ParseSupport_parseBool;
case FLOAT:
return ParseSupport_parseFloat;
case DOUBLE:
return ParseSupport_parseDouble;
case UINT32:
case FIXED32:
return ParseSupport_parseUint32;
case UINT64:
case FIXED64:
return ParseSupport_parseUint64;
case STRING:
return ParseSupport_parseString;
case BYTES:
return ParseSupport_parseBytes;
case ENUM:
return new StackManipulation.Compound(
CodeGenUtil.getEnumDescriptor(field),
IntegerConstant.forValue(ignoringUnknownFields),
ParseSupport_parseEnum);
case MESSAGE:
case GROUP:
return new StackManipulation.Compound(
FieldAccess.forField(
fieldsByName.get(
CodeGenUtil.fieldNameForNestedMarshaller(
field.valueField().descriptor().getMessageType())))
.read(),
locals.load(LocalVariable.currentDepth),
ParseSupport_parseMessage);
default:
throw new IllegalStateException("Unknown field type: " + field.valueType());
}
}
示例11
/**
* {@inheritDoc}
*/
public StackManipulation resolve(TypeDescription instrumentedType) {
return IntegerConstant.forValue(value);
}