1 11 package org.eclipse.jdt.internal.eval; 12 13 import org.eclipse.jdt.internal.compiler.codegen.CodeStream; 14 import org.eclipse.jdt.internal.compiler.codegen.ConstantPool; 15 import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; 16 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; 17 import org.eclipse.jdt.internal.compiler.lookup.InvocationSite; 18 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; 19 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; 20 import org.eclipse.jdt.internal.compiler.lookup.Scope; 21 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; 22 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; 23 24 public class CodeSnippetCodeStream extends CodeStream { 25 static InvocationSite NO_INVOCATION_SITE = 26 new InvocationSite(){ 27 public TypeBinding[] genericTypeArguments() { return null; } 28 public boolean isSuperAccess(){ return false; } 29 public boolean isTypeAccess() { return false; } 30 public void setActualReceiverType(ReferenceBinding receiverType) {} 31 public void setDepth(int depth) {} 32 public void setFieldIndex(int depth){} 33 public int sourceStart() { return 0; } 34 public int sourceEnd() { return 0; } 35 }; 36 40 public CodeSnippetCodeStream(org.eclipse.jdt.internal.compiler.ClassFile classFile) { 41 super(classFile, JDK1_4); 42 } 43 protected void checkcast(int baseId) { 44 this.countLabels = 0; 45 if (classFileOffset + 2 >= bCodeStream.length) { 46 resizeByteArray(); 47 } 48 this.position++; 49 this.bCodeStream[this.classFileOffset++] = OPC_checkcast; 50 switch (baseId) { 51 case T_byte : 52 writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangByteConstantPoolName)); 53 break; 54 case T_short : 55 writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangShortConstantPoolName)); 56 break; 57 case T_char : 58 writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangCharacterConstantPoolName)); 59 break; 60 case T_int : 61 writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangIntegerConstantPoolName)); 62 break; 63 case T_long : 64 writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangLongConstantPoolName)); 65 break; 66 case T_float : 67 writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangFloatConstantPoolName)); 68 break; 69 case T_double : 70 writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangDoubleConstantPoolName)); 71 break; 72 case T_boolean : 73 writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangBooleanConstantPoolName)); 74 } 75 } 76 public void generateEmulatedAccessForMethod(Scope scope, MethodBinding methodBinding) { 77 CodeSnippetCodeStream localCodeStream = this; 78 localCodeStream.generateEmulationForMethod(scope, methodBinding); 79 localCodeStream.invokeJavaLangReflectMethodInvoke(); 80 } 81 public void generateEmulatedReadAccessForField(FieldBinding fieldBinding) { 82 CodeSnippetCodeStream localCodeStream = this; 83 localCodeStream.generateEmulationForField(fieldBinding); 84 this.swap(); 86 localCodeStream.invokeJavaLangReflectFieldGetter(fieldBinding.type.id); 87 if (!fieldBinding.type.isBaseType()) { 88 this.checkcast(fieldBinding.type); 89 } 90 } 91 public void generateEmulatedWriteAccessForField(FieldBinding fieldBinding) { 92 CodeSnippetCodeStream localCodeStream = this; 93 localCodeStream.invokeJavaLangReflectFieldSetter(fieldBinding.type.id); 94 } 95 public void generateEmulationForConstructor(Scope scope, MethodBinding methodBinding) { 96 CodeSnippetCodeStream localCodeStream = this; 98 this.ldc(String.valueOf(methodBinding.declaringClass.constantPoolName()).replace('/', '.')); 99 this.invokeClassForName(); 100 int paramLength = methodBinding.parameters.length; 101 this.generateInlinedValue(paramLength); 102 this.newArray(scope.createArrayType(scope.getType(TypeConstants.JAVA_LANG_CLASS, 3), 1)); 103 if (paramLength > 0) { 104 this.dup(); 105 for (int i = 0; i < paramLength; i++) { 106 this.generateInlinedValue(i); 107 TypeBinding parameter = methodBinding.parameters[i]; 108 if (parameter.isBaseType()) { 109 this.getTYPE(parameter.id); 110 } else if (parameter.isArrayType()) { 111 ArrayBinding array = (ArrayBinding)parameter; 112 if (array.leafComponentType.isBaseType()) { 113 this.getTYPE(array.leafComponentType.id); 114 } else { 115 this.ldc(String.valueOf(array.leafComponentType.constantPoolName()).replace('/', '.')); 116 this.invokeClassForName(); 117 } 118 int dimensions = array.dimensions; 119 this.generateInlinedValue(dimensions); 120 this.newarray(T_int); 121 this.invokeArrayNewInstance(); 122 this.invokeObjectGetClass(); 123 } else { 124 this.ldc(String.valueOf(methodBinding.declaringClass.constantPoolName()).replace('/', '.')); 126 this.invokeClassForName(); 127 } 128 this.aastore(); 129 if (i < paramLength - 1) { 130 this.dup(); 131 } 132 } 133 } 134 localCodeStream.invokeClassGetDeclaredConstructor(); 135 this.dup(); 136 this.iconst_1(); 137 localCodeStream.invokeAccessibleObjectSetAccessible(); 138 } 139 public void generateEmulationForField(FieldBinding fieldBinding) { 140 CodeSnippetCodeStream localCodeStream = this; 142 this.ldc(String.valueOf(fieldBinding.declaringClass.constantPoolName()).replace('/', '.')); 143 this.invokeClassForName(); 144 this.ldc(String.valueOf(fieldBinding.name)); 145 localCodeStream.invokeClassGetDeclaredField(); 146 this.dup(); 147 this.iconst_1(); 148 localCodeStream.invokeAccessibleObjectSetAccessible(); 149 } 150 public void generateEmulationForMethod(Scope scope, MethodBinding methodBinding) { 151 CodeSnippetCodeStream localCodeStream = this; 153 this.ldc(String.valueOf(methodBinding.declaringClass.constantPoolName()).replace('/', '.')); 154 this.invokeClassForName(); 155 this.ldc(String.valueOf(methodBinding.selector)); 156 int paramLength = methodBinding.parameters.length; 157 this.generateInlinedValue(paramLength); 158 this.newArray(scope.createArrayType(scope.getType(TypeConstants.JAVA_LANG_CLASS, 3), 1)); 159 if (paramLength > 0) { 160 this.dup(); 161 for (int i = 0; i < paramLength; i++) { 162 this.generateInlinedValue(i); 163 TypeBinding parameter = methodBinding.parameters[i]; 164 if (parameter.isBaseType()) { 165 this.getTYPE(parameter.id); 166 } else if (parameter.isArrayType()) { 167 ArrayBinding array = (ArrayBinding)parameter; 168 if (array.leafComponentType.isBaseType()) { 169 this.getTYPE(array.leafComponentType.id); 170 } else { 171 this.ldc(String.valueOf(array.leafComponentType.constantPoolName()).replace('/', '.')); 172 this.invokeClassForName(); 173 } 174 int dimensions = array.dimensions; 175 this.generateInlinedValue(dimensions); 176 this.newarray(T_int); 177 this.invokeArrayNewInstance(); 178 this.invokeObjectGetClass(); 179 } else { 180 this.ldc(String.valueOf(methodBinding.declaringClass.constantPoolName()).replace('/', '.')); 182 this.invokeClassForName(); 183 } 184 this.aastore(); 185 if (i < paramLength - 1) { 186 this.dup(); 187 } 188 } 189 } 190 localCodeStream.invokeClassGetDeclaredMethod(); 191 this.dup(); 192 this.iconst_1(); 193 localCodeStream.invokeAccessibleObjectSetAccessible(); 194 } 195 public void generateObjectWrapperForType(TypeBinding valueType) { 196 197 200 TypeBinding wrapperType = this.methodDeclaration.scope.boxing(valueType); 201 new_(wrapperType); 202 if (valueType.id == T_long || valueType.id == T_double) { 203 dup_x2(); 204 dup_x2(); 205 pop(); 206 } else { 207 dup_x1(); 208 swap(); 209 } 210 MethodBinding methodBinding = this.methodDeclaration.scope.getMethod( 211 wrapperType, 212 ConstantPool.Init, 213 new TypeBinding[] {valueType}, 214 NO_INVOCATION_SITE); 215 invokespecial(methodBinding); 216 } 217 public void getBaseTypeValue(int baseTypeID) { 218 switch (baseTypeID) { 219 case T_byte : 220 this.invoke( 222 OPC_invokevirtual, 223 0, 1, ConstantPool.JavaLangByteConstantPoolName, 226 ConstantPool.BYTEVALUE_BYTE_METHOD_NAME, 227 ConstantPool.BYTEVALUE_BYTE_METHOD_SIGNATURE); 228 break; 229 case T_short : 230 this.invoke( 232 OPC_invokevirtual, 233 0, 1, ConstantPool.JavaLangShortConstantPoolName, 236 ConstantPool.SHORTVALUE_SHORT_METHOD_NAME, 237 ConstantPool.SHORTVALUE_SHORT_METHOD_SIGNATURE); 238 break; 239 case T_char : 240 this.invoke( 242 OPC_invokevirtual, 243 0, 1, ConstantPool.JavaLangCharacterConstantPoolName, 246 ConstantPool.CHARVALUE_CHARACTER_METHOD_NAME, 247 ConstantPool.CHARVALUE_CHARACTER_METHOD_SIGNATURE); 248 break; 249 case T_int : 250 this.invoke( 252 OPC_invokevirtual, 253 0, 1, ConstantPool.JavaLangIntegerConstantPoolName, 256 ConstantPool.INTVALUE_INTEGER_METHOD_NAME, 257 ConstantPool.INTVALUE_INTEGER_METHOD_SIGNATURE); 258 break; 259 case T_long : 260 this.invoke( 262 OPC_invokevirtual, 263 0, 2, ConstantPool.JavaLangLongConstantPoolName, 266 ConstantPool.LONGVALUE_LONG_METHOD_NAME, 267 ConstantPool.LONGVALUE_LONG_METHOD_SIGNATURE); 268 break; 269 case T_float : 270 this.invoke( 272 OPC_invokevirtual, 273 0, 1, ConstantPool.JavaLangFloatConstantPoolName, 276 ConstantPool.FLOATVALUE_FLOAT_METHOD_NAME, 277 ConstantPool.FLOATVALUE_FLOAT_METHOD_SIGNATURE); 278 break; 279 case T_double : 280 this.invoke( 282 OPC_invokevirtual, 283 0, 2, ConstantPool.JavaLangDoubleConstantPoolName, 286 ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_NAME, 287 ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE); 288 break; 289 case T_boolean : 290 this.invoke( 292 OPC_invokevirtual, 293 0, 1, ConstantPool.JavaLangBooleanConstantPoolName, 296 ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_NAME, 297 ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE); 298 } 299 } 300 protected void invokeAccessibleObjectSetAccessible() { 301 this.invoke( 303 OPC_invokevirtual, 304 1, 0, ConstantPool.JAVALANGREFLECTACCESSIBLEOBJECT_CONSTANTPOOLNAME, 307 ConstantPool.SETACCESSIBLE_NAME, 308 ConstantPool.SETACCESSIBLE_SIGNATURE); 309 } 310 protected void invokeArrayNewInstance() { 311 this.invoke( 313 OPC_invokestatic, 314 2, 1, ConstantPool.JAVALANGREFLECTARRAY_CONSTANTPOOLNAME, 317 ConstantPool.NewInstance, 318 ConstantPool.NewInstanceSignature); 319 } 320 protected void invokeClassGetDeclaredConstructor() { 321 this.invoke( 323 OPC_invokevirtual, 324 1, 1, ConstantPool.JavaLangClassConstantPoolName, 327 ConstantPool.GETDECLAREDCONSTRUCTOR_NAME, 328 ConstantPool.GETDECLAREDCONSTRUCTOR_SIGNATURE); 329 } 330 protected void invokeClassGetDeclaredField() { 331 this.invoke( 333 OPC_invokevirtual, 334 1, 1, ConstantPool.JavaLangClassConstantPoolName, 337 ConstantPool.GETDECLAREDFIELD_NAME, 338 ConstantPool.GETDECLAREDFIELD_SIGNATURE); 339 } 340 protected void invokeClassGetDeclaredMethod() { 341 this.invoke( 343 OPC_invokevirtual, 344 2, 1, ConstantPool.JavaLangClassConstantPoolName, 347 ConstantPool.GETDECLAREDMETHOD_NAME, 348 ConstantPool.GETDECLAREDMETHOD_SIGNATURE); 349 } 350 protected void invokeJavaLangReflectConstructorNewInstance() { 351 this.invoke( 353 OPC_invokevirtual, 354 1, 1, ConstantPool.JavaLangReflectConstructor, 357 ConstantPool.NewInstance, 358 ConstantPool.JavaLangReflectConstructorNewInstanceSignature); 359 } 360 protected void invokeJavaLangReflectFieldGetter(int typeID) { 361 int returnTypeSize = 1; 362 char[] signature = null; 363 char[] selector = null; 364 switch (typeID) { 365 case T_int : 366 selector = ConstantPool.GET_INT_METHOD_NAME; 367 signature = ConstantPool.GET_INT_METHOD_SIGNATURE; 368 break; 369 case T_byte : 370 selector = ConstantPool.GET_BYTE_METHOD_NAME; 371 signature = ConstantPool.GET_BYTE_METHOD_SIGNATURE; 372 break; 373 case T_short : 374 selector = ConstantPool.GET_SHORT_METHOD_NAME; 375 signature = ConstantPool.GET_SHORT_METHOD_SIGNATURE; 376 break; 377 case T_long : 378 selector = ConstantPool.GET_LONG_METHOD_NAME; 379 signature = ConstantPool.GET_LONG_METHOD_SIGNATURE; 380 returnTypeSize = 2; 381 break; 382 case T_float : 383 selector = ConstantPool.GET_FLOAT_METHOD_NAME; 384 signature = ConstantPool.GET_FLOAT_METHOD_SIGNATURE; 385 break; 386 case T_double : 387 selector = ConstantPool.GET_DOUBLE_METHOD_NAME; 388 signature = ConstantPool.GET_DOUBLE_METHOD_SIGNATURE; 389 returnTypeSize = 2; 390 break; 391 case T_char : 392 selector = ConstantPool.GET_CHAR_METHOD_NAME; 393 signature = ConstantPool.GET_CHAR_METHOD_SIGNATURE; 394 break; 395 case T_boolean : 396 selector = ConstantPool.GET_BOOLEAN_METHOD_NAME; 397 signature = ConstantPool.GET_BOOLEAN_METHOD_SIGNATURE; 398 break; 399 default : 400 selector = ConstantPool.GET_OBJECT_METHOD_NAME; 401 signature = ConstantPool.GET_OBJECT_METHOD_SIGNATURE; 402 break; 403 } 404 this.invoke( 405 OPC_invokevirtual, 406 1, returnTypeSize, ConstantPool.JAVALANGREFLECTFIELD_CONSTANTPOOLNAME, 409 selector, 410 signature); 411 } 412 protected void invokeJavaLangReflectFieldSetter(int typeID) { 413 int argCount = 2; 414 char[] signature = null; 415 char[] selector = null; 416 switch (typeID) { 417 case T_int : 418 selector = ConstantPool.SET_INT_METHOD_NAME; 419 signature = ConstantPool.SET_INT_METHOD_SIGNATURE; 420 break; 421 case T_byte : 422 selector = ConstantPool.SET_BYTE_METHOD_NAME; 423 signature = ConstantPool.SET_BYTE_METHOD_SIGNATURE; 424 break; 425 case T_short : 426 selector = ConstantPool.SET_SHORT_METHOD_NAME; 427 signature = ConstantPool.SET_SHORT_METHOD_SIGNATURE; 428 break; 429 case T_long : 430 selector = ConstantPool.SET_LONG_METHOD_NAME; 431 signature = ConstantPool.SET_LONG_METHOD_SIGNATURE; 432 argCount = 3; 433 break; 434 case T_float : 435 selector = ConstantPool.SET_FLOAT_METHOD_NAME; 436 signature = ConstantPool.SET_FLOAT_METHOD_SIGNATURE; 437 break; 438 case T_double : 439 selector = ConstantPool.SET_DOUBLE_METHOD_NAME; 440 signature = ConstantPool.SET_DOUBLE_METHOD_SIGNATURE; 441 argCount = 3; 442 break; 443 case T_char : 444 selector = ConstantPool.SET_CHAR_METHOD_NAME; 445 signature = ConstantPool.SET_CHAR_METHOD_SIGNATURE; 446 break; 447 case T_boolean : 448 selector = ConstantPool.SET_BOOLEAN_METHOD_NAME; 449 signature = ConstantPool.SET_BOOLEAN_METHOD_SIGNATURE; 450 break; 451 default : 452 selector = ConstantPool.SET_OBJECT_METHOD_NAME; 453 signature = ConstantPool.SET_OBJECT_METHOD_SIGNATURE; 454 break; 455 } 456 this.invoke( 457 OPC_invokevirtual, 458 argCount, 0, ConstantPool.JAVALANGREFLECTFIELD_CONSTANTPOOLNAME, 461 selector, 462 signature); 463 } 464 protected void invokeJavaLangReflectMethodInvoke() { 465 this.invoke( 467 OPC_invokevirtual, 468 2, 1, ConstantPool.JAVALANGREFLECTMETHOD_CONSTANTPOOLNAME, 471 ConstantPool.INVOKE_METHOD_METHOD_NAME, 472 ConstantPool.INVOKE_METHOD_METHOD_SIGNATURE); 473 } 474 private final void resizeByteArray() { 475 int length = bCodeStream.length; 476 int requiredSize = length + length; 477 if (classFileOffset > requiredSize) { 478 requiredSize = classFileOffset + length; 480 } 481 System.arraycopy(bCodeStream, 0, bCodeStream = new byte[requiredSize], 0, length); 482 } 483 } 484 | Popular Tags |