View | Details | Raw Unified | Return to bug 91417 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/aspectj/weaver/WeaverStateInfo.java (-26 / +312 lines)
Lines 30-35 Link Here
30
import org.aspectj.bridge.IMessage;
30
import org.aspectj.bridge.IMessage;
31
import org.aspectj.weaver.bcel.BcelTypeMunger;
31
import org.aspectj.weaver.bcel.BcelTypeMunger;
32
32
33
import java.io.ByteArrayInputStream; // ajh02: added
34
import java.io.ByteArrayOutputStream; // ajh02: added
33
35
34
/**
36
/**
35
 * WeaverStateInfo represents how a type was processed.  It is used by the weaver to determine how a type 
37
 * WeaverStateInfo represents how a type was processed.  It is used by the weaver to determine how a type 
Lines 60-65 Link Here
60
	private static boolean reweavableDefault = false;
62
	private static boolean reweavableDefault = false;
61
	private static boolean reweavableCompressedModeDefault = false;
63
	private static boolean reweavableCompressedModeDefault = false;
62
	
64
	
65
	private static byte key[] = { // ajh02: added
66
		// could be longer if it's not going in the file written to disk
67
		// (which I'm pretty sure it doesn't have to)
68
        -51, 34, 105, 56, -34, 65, 45, 78
69
    };
70
	private boolean unwovenClassFileDataIsDiff; // ajh02: added
71
	
63
	public WeaverStateInfo() {
72
	public WeaverStateInfo() {
64
		this(new ArrayList(), false,reweavableDefault,reweavableCompressedModeDefault);
73
		this(new ArrayList(), false,reweavableDefault,reweavableCompressedModeDefault);
65
	}
74
	}
Lines 71-76 Link Here
71
		this.reweavableCompressedMode = reweavableCompressedMode;
80
		this.reweavableCompressedMode = reweavableCompressedMode;
72
		this.aspectsAffectingType= new HashSet();
81
		this.aspectsAffectingType= new HashSet();
73
		this.unwovenClassFile = null;
82
		this.unwovenClassFile = null;
83
		unwovenClassFileDataIsDiff = false; // ajh02: line added
74
	}
84
	}
75
	
85
	
76
	public static void setReweavableModeDefaults(boolean mode, boolean compress) {
86
	public static void setReweavableModeDefaults(boolean mode, boolean compress) {
Lines 85-90 Link Here
85
	private static final byte REWEAVABLE_COMPRESSION_BIT = 1<<5;
95
	private static final byte REWEAVABLE_COMPRESSION_BIT = 1<<5;
86
	
96
	
87
	public static final WeaverStateInfo read(VersionedDataInputStream s, ISourceContext context) throws IOException {
97
	public static final WeaverStateInfo read(VersionedDataInputStream s, ISourceContext context) throws IOException {
98
		System.err.println("read called");
88
		byte b = s.readByte();
99
		byte b = s.readByte();
89
		
100
		
90
		boolean isReweavable = ((b&REWEAVABLE_BIT)!=0);
101
		boolean isReweavable = ((b&REWEAVABLE_BIT)!=0);
Lines 130-137 Link Here
130
	} 
141
	} 
131
142
132
	public void write(DataOutputStream s) throws IOException {
143
	public void write(DataOutputStream s) throws IOException {
144
		System.err.println("write called");
133
		if (oldStyle) throw new RuntimeException("shouldn't be writing this");
145
		if (oldStyle) throw new RuntimeException("shouldn't be writing this");
134
		
146
		
147
		if (reweavable && reweavableCompressedMode){
148
			s.write(key); // ajh02: 3 lines added
149
		}
150
		
135
		byte weaverStateInfoKind = EXTENDED;
151
		byte weaverStateInfoKind = EXTENDED;
136
		if (reweavable) weaverStateInfoKind |= REWEAVABLE_BIT;
152
		if (reweavable) weaverStateInfoKind |= REWEAVABLE_BIT;
137
		if (reweavableCompressedMode) weaverStateInfoKind |= REWEAVABLE_COMPRESSION_BIT;
153
		if (reweavableCompressedMode) weaverStateInfoKind |= REWEAVABLE_COMPRESSION_BIT;
Lines 176-185 Link Here
176
	public boolean isOldStyle() {
192
	public boolean isOldStyle() {
177
		return oldStyle;
193
		return oldStyle;
178
	}
194
	}
179
195
	
180
	public byte[] getUnwovenClassFileData() {
196
	public byte[] getUnwovenClassFileData(byte wovenClassFile[]) {
181
		return unwovenClassFile;
197
		// ajh02: method added
182
	}
198
		System.err.println("getUnwovenClassFileData called");
199
        if(!unwovenClassFileDataIsDiff){
200
            return unwovenClassFile;
201
        } else {
202
        	
203
        	// to apply the diff we use a version of wovenClassFile
204
			// up to but not including the length of the WeaverStateInfo...
205
        	// BUT actually it shouldn't matter if we give it a bit too much!
206
        	// so we can actually just give it the whole wovenClassFile here!!!!! :D
207
        	// so we don't need to do any horrible fiddling or serializing keys
208
        	// to find where the length of the weaverStateInfo was serialized :)
209
        	// DUDE! sweet!
210
        	
211
        	unwovenClassFile = applyDiff(wovenClassFile, unwovenClassFile);
212
        	unwovenClassFileDataIsDiff = false;
213
        	
214
//            int endOfKey = findEndOfKey(wovenClassFile);
215
//            int positionOfnewLength = endOfKey - key.length - 9;
216
//            int newLength = readInt(wovenClassFile, positionOfnewLength);
217
//            int oldLength = readInt(wovenClassFile, positionOfnewLength + 5);
218
//            byte oldLengthAndB[] = {
219
//                wovenClassFile[positionOfnewLength + 5], wovenClassFile[positionOfnewLength + 6], wovenClassFile[positionOfnewLength + 7], wovenClassFile[positionOfnewLength + 8], wovenClassFile[positionOfnewLength + 4]
220
//            };
221
//            byte withoutZippedDiff[] = deleteInArray(wovenClassFile, positionOfnewLength + 8 + oldLength, positionOfnewLength + 4 + newLength);
222
//            withoutZippedDiff = deleteInArray(withoutZippedDiff, positionOfnewLength, positionOfnewLength + 9);
223
//            withoutZippedDiff = insertArray(oldLengthAndB, withoutZippedDiff, positionOfnewLength);
224
//            unwovenClassFile = applyDiff(withoutZippedDiff, unwovenClassFile);
225
//            unwovenClassFileDataIsDiff = false;
226
            return unwovenClassFile;
227
        }
228
    }
183
229
184
	public void setUnwovenClassFileData(byte[] data) {
230
	public void setUnwovenClassFileData(byte[] data) {
185
		unwovenClassFile = data;
231
		unwovenClassFile = data;
Lines 205-214 Link Here
205
	}
251
	}
206
252
207
253
208
    ////
209
    
254
    
255
	// ajh02: a load of methods in this class should be made non-static on their wsi's, shouldn't they
256
	// because it's just silly making it static then always giving it a wsi that can't be null anyway
210
	private static void readAnyReweavableData(WeaverStateInfo wsi,DataInputStream s) throws IOException {
257
	private static void readAnyReweavableData(WeaverStateInfo wsi,DataInputStream s) throws IOException {
211
212
		if (wsi.isReweavable()) {		
258
		if (wsi.isReweavable()) {		
213
			// Load list of aspects that need to exist in the world for reweaving to be 'legal'
259
			// Load list of aspects that need to exist in the world for reweaving to be 'legal'
214
			int numberAspectsAffectingType = s.readShort();
260
			int numberAspectsAffectingType = s.readShort();
Lines 224-254 Link Here
224
				if (bytesread!=unwovenClassFileSize) 
270
				if (bytesread!=unwovenClassFileSize) 
225
				  throw new IOException("ERROR whilst reading reweavable data, expected "+
271
				  throw new IOException("ERROR whilst reading reweavable data, expected "+
226
				                        unwovenClassFileSize+" bytes, only found "+bytesread);
272
				                        unwovenClassFileSize+" bytes, only found "+bytesread);
273
				wsi.unwovenClassFileDataIsDiff = false;
227
			} else {
274
			} else {
228
				// Decompress it
275
				// Decompress it
276
//				classData = new byte[unwovenClassFileSize];
277
//						
278
//				ZipInputStream zis = new ZipInputStream(s);
279
//				ZipEntry zen = zis.getNextEntry();
280
//				int current = 0; 
281
//				int bytesToGo=unwovenClassFileSize;
282
//				while (bytesToGo>0) {
283
//					int amount = zis.read(classData,current,bytesToGo);
284
//					current+=amount;
285
//					bytesToGo-=amount;
286
//				}
287
//				zis.closeEntry();
288
//				if (bytesToGo!=0) 
289
//				  throw new IOException("ERROR whilst reading compressed reweavable data, expected "+
290
//				                        unwovenClassFileSize+" bytes, only found "+current);
291
				
229
				classData = new byte[unwovenClassFileSize];
292
				classData = new byte[unwovenClassFileSize];
230
						
293
				int bytesread = s.read(classData);
231
				ZipInputStream zis = new ZipInputStream(s);
294
				if (bytesread!=unwovenClassFileSize) 
232
				ZipEntry zen = zis.getNextEntry();
295
				  throw new IOException("ERROR whilst reading reweavable data, expected "+
233
				int current = 0; 
296
				                        unwovenClassFileSize+" bytes, only found "+bytesread);
234
				int bytesToGo=unwovenClassFileSize;
297
				// but remember it's a diff of the unwoven classFile!
235
				while (bytesToGo>0) {
298
				wsi.unwovenClassFileDataIsDiff = true;
236
					int amount = zis.read(classData,current,bytesToGo);
237
					current+=amount;
238
					bytesToGo-=amount;
239
				}
240
				zis.closeEntry();
241
				if (bytesToGo!=0) 
242
				  throw new IOException("ERROR whilst reading compressed reweavable data, expected "+
243
				                        unwovenClassFileSize+" bytes, only found "+current);
244
			}
299
			}
245
			wsi.setUnwovenClassFileData(classData);
300
			wsi.setUnwovenClassFileData(classData);
246
		}
301
		}
247
	}
302
	}
248
303
304
	public byte[] insertAnyReweavableData(byte wovenClassFile[]) {
305
		// now that we have the whole wovenClassFile,
306
		//we can make the diff with it and write it over where we previously left the
307
		// key stub
308
		System.err.println("insertAnyReweavableData called");
309
		//return wovenClassFile;
310
		
311
		if (isReweavable() && reweavableCompressedMode){
312
			ByteArrayOutputStream arrayStream = new ByteArrayOutputStream();
313
			DataOutputStream s = new DataOutputStream(arrayStream);
314
			
315
			int endOfKey = findEndOfKey(wovenClassFile);
316
			int startOfKey = endOfKey - key.length;
317
			int oldLengthLocation = startOfKey -4;
318
			int oldLength = readInt(wovenClassFile, oldLengthLocation);
319
			wovenClassFile = deleteInArray(wovenClassFile,startOfKey,endOfKey); // remove the key
320
			
321
			byte [] wovenClassFileToDiffWith = new byte [oldLengthLocation];
322
			System.arraycopy(wovenClassFile,0,wovenClassFileToDiffWith,0,oldLengthLocation);
323
			
324
			// to make the diff we use a version of wovenClassFile
325
			// up to but not including the length of the WeaverStateInfo
326
			
327
			byte [] diff = generateDiff(wovenClassFileToDiffWith, unwovenClassFile);
328
			try { // add the length of the diff to the front of the diff
329
				s.writeInt(diff.length);
330
				s.write(diff);
331
			} catch(IOException e){}
332
			diff = arrayStream.toByteArray();
333
			// we have to swap the oldLength for the new one,
334
			// and add the diff (can use the oldLength to work out where it goes :)
335
			
336
			int newLength = oldLength - key.length + diff.length;
337
			byte newLengthBytes[] = serializeInt(newLength);
338
			
339
			// swap in the serialized newLength for the oldOne:
340
			wovenClassFile[oldLengthLocation] = newLengthBytes[0];
341
			wovenClassFile[oldLengthLocation + 1] = newLengthBytes[1];
342
			wovenClassFile[oldLengthLocation + 2] = newLengthBytes[2];
343
			wovenClassFile[oldLengthLocation + 3] = newLengthBytes[3];
344
			
345
			// add the diff
346
			wovenClassFile = insertArray(diff, wovenClassFile, oldLengthLocation + 4 + oldLength - key.length);
347
			
348
			
349
		}
350
		return wovenClassFile;
351
		
352
		// ajh02: method added
353
//        ByteArrayOutputStream arrayStream = new ByteArrayOutputStream();
354
//        DataOutputStream s = new DataOutputStream(arrayStream);
355
//        if(isReweavable()){
356
//            try {
357
//                if(!reweavableCompressedMode) {
358
//                    s.writeInt(unwovenClassFile.length);
359
//                    s.write(unwovenClassFile);
360
//                } else {
361
//                    byte diff[] = generateDiff(wovenClassFile, unwovenClassFile);
362
//                    s.writeInt(diff.length);
363
//                    s.write(diff);
364
//                }
365
//            }
366
//            catch(IOException e) {
367
//            	// ajh02: hmm do something here?
368
//            	// can this ever happen?
369
//            }
370
//            byte zippedDiff[] = arrayStream.toByteArray();
371
//            int endOfKey = findEndOfKey(wovenClassFile);
372
//            int oldLengthLocation = endOfKey - key.length - 5;
373
//            int oldLength = readInt(wovenClassFile, oldLengthLocation);
374
//            int newLength = oldLength + 4 + zippedDiff.length;
375
//            ByteArrayOutputStream bos = new ByteArrayOutputStream(4);
376
//            DataOutputStream dos = new DataOutputStream(bos);
377
//            try {
378
//                dos.writeInt(newLength);
379
//            }
380
//            catch(IOException e) {
381
//            }
382
//            byte newLengthBytes[] = bos.toByteArray();
383
//            byte oldLengthBytes[] = {
384
//                wovenClassFile[oldLengthLocation], wovenClassFile[oldLengthLocation + 1], wovenClassFile[oldLengthLocation + 2], wovenClassFile[oldLengthLocation + 3]
385
//            };
386
//            wovenClassFile[oldLengthLocation] = newLengthBytes[0];
387
//            wovenClassFile[oldLengthLocation + 1] = newLengthBytes[1];
388
//            wovenClassFile[oldLengthLocation + 2] = newLengthBytes[2];
389
//            wovenClassFile[oldLengthLocation + 3] = newLengthBytes[3];
390
//            wovenClassFile = insertArray(oldLengthBytes, wovenClassFile, oldLengthLocation + 5);
391
//            return insertArray(zippedDiff, wovenClassFile, oldLengthLocation + 8 + oldLength);
392
//        } else {
393
//            return wovenClassFile;
394
//        }
395
    }
396
	
397
	private static final int findEndOfKey(byte lookIn[]){
398
		// looks through the classfile backwards (as the attributes are all near the end)
399
        for(int i = lookIn.length - 1; i > 0; i--)
400
            if(endOfKeyHere(lookIn, i)){
401
                return i + 1;
402
            }
403
        throw new RuntimeException("key not found in wovenClassFile");
404
    }
405
	private static final boolean endOfKeyHere(byte lookIn[], int i){
406
        for(int j = 0; j < key.length; j++)
407
            if(key[key.length - 1 - j] != lookIn[i - j]){
408
                return false;
409
            }
410
        return true;
411
    }
412
	private static final byte[] insertArray(byte toInsert[], byte original[], int offset){
413
        byte result[] = new byte[original.length + toInsert.length];
414
        System.arraycopy(original, 0, result, 0, offset);
415
        System.arraycopy(toInsert, 0, result, offset, toInsert.length);
416
        System.arraycopy(original, offset, result, offset + toInsert.length, original.length - offset);
417
        return result;
418
    }
419
	private static final int readInt(byte [] a, int offset){
420
        ByteArrayInputStream b = new ByteArrayInputStream(a, offset, 4);
421
        DataInputStream d = new DataInputStream(b);
422
        int length = -1;
423
        try{
424
            length = d.readInt();
425
        }
426
        catch(IOException e) {
427
        	// ajh02: can this ever happen?
428
        }
429
        return length;
430
    }
431
	private static final int readUnsignedShort(byte a[], int offset){
432
        ByteArrayInputStream b = new ByteArrayInputStream(a, offset, 4);
433
        DataInputStream d = new DataInputStream(b);
434
        int length = -1;
435
        try{
436
            length = d.readUnsignedShort();
437
        }
438
        catch(IOException e) {
439
        	// ajh02: can this ever happen?
440
        }
441
        return length;
442
    }
443
	private static final byte[] deleteInArray(byte a[], int start, int end){
444
		int lengthToDelete = end - start;
445
        byte result[] = new byte[a.length - lengthToDelete]; // make a new array
446
        System.arraycopy(a, 0, result, 0, start); // copy in the bit before the deleted bit
447
        System.arraycopy(a, end, result, start, a.length - end); // copy in the bit after the deleted bit
448
        return result;
449
    }
450
	
451
	// classfiles consist of: 
452
	//   8 bytes: magic number and minor and major versions,
453
	//   2 bytes: its constant pool count
454
	//   n bytes: the rest of the class file
455
	//
456
	// weaving a classfile never changes the classfile's first 8 bytes,
457
	// and usually there's a load of bytes 10 bytes in that weaving leaves unchanged
458
	//
459
	// so the diff consists of:
460
	//  2 bytes: its constant pool count
461
	//  4 bytes: the number of bytes the woven and unWoven class files have in common 10 bytes in
462
	//  n bytes: the unWoven class file after the bit it has in common with the woven one
463
	
464
	byte [] applyDiff(byte [] wovenClassFile, byte [] diff){
465
		
466
		int lengthInCommon = readInt(diff,2);
467
		byte [] unWovenClassFile = new byte [4 + diff.length + lengthInCommon];
468
		
469
		// the magic number and classfile version cannot be changed by weaving
470
		System.arraycopy(wovenClassFile,0,unWovenClassFile,0,8);
471
		
472
		// copy across the constant pool count
473
		unWovenClassFile[8] = diff[0];
474
		unWovenClassFile[9] = diff[1];
475
		
476
		// copy in the stuff they have in common
477
		System.arraycopy(wovenClassFile,10,unWovenClassFile,10,lengthInCommon);
478
		
479
		// now copy the rest of the diff in verbatim
480
		System.arraycopy(diff,6,unWovenClassFile,10+lengthInCommon,diff.length-6);
481
		
482
		return unWovenClassFile;
483
	}
484
	
485
	byte [] generateDiff(byte [] wovenClassFile, byte [] unWovenClassFile){
486
		
487
		// find how long the bit 10 bytes in that they have in common is
488
		int lookingAt = 10;
489
		int shorterLength
490
			=(wovenClassFile.length < unWovenClassFile.length)? wovenClassFile.length:unWovenClassFile.length;
491
		while (lookingAt < shorterLength && (wovenClassFile[lookingAt] == unWovenClassFile[lookingAt])){
492
			lookingAt++;
493
		}
494
		int lengthInCommon = lookingAt - 10;
495
		byte [] diff = new byte [unWovenClassFile.length - 4 - lengthInCommon];
496
		
497
		// first 2 bytes of the diff are the constant pool count
498
		diff[0] = unWovenClassFile[8];
499
		diff[1] = unWovenClassFile[9];
500
		
501
		// then 4 bytes saying how long they have in common after the constant pool count
502
		byte [] lengthInCommonBytes = serializeInt(lengthInCommon);
503
		diff[2] = lengthInCommonBytes[0];
504
		diff[3] = lengthInCommonBytes[1];
505
		diff[4] = lengthInCommonBytes[2];
506
		diff[5] = lengthInCommonBytes[3];
507
		
508
		// then we just dump the rest of the unWovenClassFile verbatim
509
		System.arraycopy(unWovenClassFile,10+lengthInCommon,diff,6,diff.length-6);
510
		
511
		System.err.println("unwoven class file was: " + unWovenClassFile.length);
512
		System.err.println("diff is: " + diff.length);
513
		
514
		return diff;
515
	}
516
	
517
	private byte [] serializeInt(int i){
518
		ByteArrayOutputStream bos = new ByteArrayOutputStream(4);
519
		DataOutputStream dos = new DataOutputStream(bos);
520
		try {
521
			dos.writeInt(i);
522
		} catch(IOException e) {}
523
		return bos.toByteArray();
524
	}
525
526
	
249
527
250
528
251
	private static void writeAnyReweavableData(WeaverStateInfo wsi,DataOutputStream s) throws IOException {
529
	private static void writeAnyReweavableData(WeaverStateInfo wsi,DataOutputStream s) throws IOException {
530
		System.err.println("writeAnyReweavableData called");
252
		if (wsi.isReweavable()) {
531
		if (wsi.isReweavable()) {
253
			// Write out list of aspects that must exist next time we try and weave this class
532
			// Write out list of aspects that must exist next time we try and weave this class
254
			s.writeShort(wsi.aspectsAffectingType.size());
533
			s.writeShort(wsi.aspectsAffectingType.size());
Lines 259-274 Link Here
259
				}
538
				}
260
			}
539
			}
261
			byte[] data = wsi.unwovenClassFile;
540
			byte[] data = wsi.unwovenClassFile;
262
			s.writeInt(data.length);
541
			
263
			// Do we need to compress the data?
542
			// Do we need to compress the data?
264
			if (!wsi.reweavableCompressedMode) {
543
			if (!wsi.reweavableCompressedMode) {
544
				s.writeInt(data.length);
265
				s.write(wsi.unwovenClassFile);
545
				s.write(wsi.unwovenClassFile);
266
			} else {
546
			} else {
267
				ZipOutputStream zos = new ZipOutputStream(s);
547
				
268
				ZipEntry ze = new ZipEntry("data");
548
	            //s.write(key); // ajh02: line added
269
				zos.putNextEntry(ze);
549
	            // put the key here as a marker for where we have to come back and
270
				zos.write(wsi.unwovenClassFile,0,wsi.unwovenClassFile.length);
550
	            // fill in later
271
				zos.closeEntry();
551
552
				
553
				//ZipOutputStream zos = new ZipOutputStream(s);
554
				//ZipEntry ze = new ZipEntry("data");
555
				//zos.putNextEntry(ze);
556
				//zos.write(wsi.unwovenClassFile,0,wsi.unwovenClassFile.length);
557
				//zos.closeEntry();
272
			}
558
			}
273
		}
559
		}
274
	}
560
	}
(-)src/org/aspectj/weaver/bcel/BcelClassWeaver.java (-2 / +7 lines)
Lines 1603-1609 Link Here
1603
	private void matchGetInstruction(LazyMethodGen mg, InstructionHandle ih, BcelShadow enclosingShadow, List shadowAccumulator) {
1603
	private void matchGetInstruction(LazyMethodGen mg, InstructionHandle ih, BcelShadow enclosingShadow, List shadowAccumulator) {
1604
		FieldInstruction fi = (FieldInstruction) ih.getInstruction();
1604
		FieldInstruction fi = (FieldInstruction) ih.getInstruction();
1605
		Member field = BcelWorld.makeFieldJoinPointSignature(clazz, fi);
1605
		Member field = BcelWorld.makeFieldJoinPointSignature(clazz, fi);
1606
		
1606
1607
		// synthetic fields are never join points
1607
		// synthetic fields are never join points
1608
		if (field.getName().startsWith(NameMangler.PREFIX)) return;
1608
		if (field.getName().startsWith(NameMangler.PREFIX)) return;
1609
		
1609
		
Lines 1615-1621 Link Here
1615
			// sets of synthetics aren't join points in 1.1
1615
			// sets of synthetics aren't join points in 1.1
1616
			return;
1616
			return;
1617
		} else {
1617
		} else {
1618
			match(BcelShadow.makeFieldGet(world, resolvedField, mg, ih, enclosingShadow), shadowAccumulator);
1618
			BcelShadow bs = BcelShadow.makeFieldGet(world,resolvedField,mg,ih,enclosingShadow);
1619
			String cname = fi.getClassName(cpg);
1620
			if (!resolvedField.getDeclaringType().getName().equals(cname)) {
1621
				bs.setActualTargetType(cname);
1622
			}
1623
			match(bs, shadowAccumulator);
1619
		}
1624
		}
1620
	}
1625
	}
1621
	
1626
	
(-)src/org/aspectj/weaver/bcel/BcelShadow.java (+23 lines)
Lines 133-138 Link Here
133
    private final BcelWorld world;  
133
    private final BcelWorld world;  
134
    private final LazyMethodGen enclosingMethod;
134
    private final LazyMethodGen enclosingMethod;
135
	private boolean fallsThrough;  //XXX not used anymore
135
	private boolean fallsThrough;  //XXX not used anymore
136
	
137
	// Some instructions have a target type that will vary 
138
    // from the signature (pr109728) (1.4 declaring type issue)
139
	private String actualInstructionTargetType; 
136
140
137
	// ---- initialization
141
	// ---- initialization
138
	
142
	
Lines 1221-1226 Link Here
1221
     * are true, it has a sneak peek at the code before the call to see what is on the stack.
1225
     * are true, it has a sneak peek at the code before the call to see what is on the stack.
1222
     */
1226
     */
1223
    public UnresolvedType ensureTargetTypeIsCorrect(UnresolvedType tx) {
1227
    public UnresolvedType ensureTargetTypeIsCorrect(UnresolvedType tx) {
1228
    	
1229
    	
1224
    	if (tx.equals(ResolvedType.OBJECT) && getKind() == MethodCall && 
1230
    	if (tx.equals(ResolvedType.OBJECT) && getKind() == MethodCall && 
1225
    	    getSignature().getReturnType().equals(ResolvedType.OBJECT) && 
1231
    	    getSignature().getReturnType().equals(ResolvedType.OBJECT) && 
1226
			getSignature().getArity()==0 && 
1232
			getSignature().getArity()==0 && 
Lines 2938-2943 Link Here
2938
        if (targetVar != null && targetVar != thisVar) {
2944
        if (targetVar != null && targetVar != thisVar) {
2939
            UnresolvedType targetType = getTargetType();
2945
            UnresolvedType targetType = getTargetType();
2940
            targetType = ensureTargetTypeIsCorrect(targetType);
2946
            targetType = ensureTargetTypeIsCorrect(targetType);
2947
            // see pr109728 - this fixes the case when the declaring class is sometype 'X' but the getfield
2948
            // in the bytecode refers to a subtype of 'X'.  This makes sure we use the type originally
2949
            // mentioned in the fieldget instruction as the method parameter and *not* the type upon which the
2950
            // field is declared because when the instructions are extracted into the new around body,
2951
            // they will still refer to the subtype.
2952
            if (getKind()==FieldGet && getActualTargetType()!=null && 
2953
            	!getActualTargetType().equals(targetType.getName())) {
2954
        		targetType =  UnresolvedType.forName(getActualTargetType()).resolve(world);
2955
        	}
2941
            ResolvedMember resolvedMember = getSignature().resolve(world);
2956
            ResolvedMember resolvedMember = getSignature().resolve(world);
2942
            
2957
            
2943
            if (resolvedMember != null && Modifier.isProtected(resolvedMember.getModifiers()) && 
2958
            if (resolvedMember != null && Modifier.isProtected(resolvedMember.getModifiers()) && 
Lines 3072-3075 Link Here
3072
	public boolean isFallsThrough() {
3087
	public boolean isFallsThrough() {
3073
		return !terminatesWithReturn(); //fallsThrough;
3088
		return !terminatesWithReturn(); //fallsThrough;
3074
	}
3089
	}
3090
3091
	public void setActualTargetType(String className) {
3092
		this.actualInstructionTargetType = className;
3093
	}
3094
	
3095
	public String getActualTargetType() {
3096
		return actualInstructionTargetType;
3097
	}
3075
}
3098
}
(-)src/org/aspectj/weaver/bcel/BcelWeaver.java (-2 / +3 lines)
Lines 1146-1152 Link Here
1146
					}		
1146
					}		
1147
				}
1147
				}
1148
			}
1148
			}
1149
			classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData()));
1149
			//classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData())); // ajh02: line changed
1150
			classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData(classType.getJavaClass().getBytes())));
1150
		} else {
1151
		} else {
1151
			classType.resetState();
1152
			classType.resetState();
1152
		}
1153
		}
Lines 1184-1190 Link Here
1184
    public UnwovenClassFile[] getClassFilesFor(LazyClassGen clazz) {
1185
    public UnwovenClassFile[] getClassFilesFor(LazyClassGen clazz) {
1185
    	List childClasses = clazz.getChildClasses(world);
1186
    	List childClasses = clazz.getChildClasses(world);
1186
    	UnwovenClassFile[] ret = new UnwovenClassFile[1 + childClasses.size()];    	
1187
    	UnwovenClassFile[] ret = new UnwovenClassFile[1 + childClasses.size()];    	
1187
    	ret[0] = new UnwovenClassFile(clazz.getFileName(),clazz.getJavaClass(world).getBytes());
1188
    	ret[0] = new UnwovenClassFile(clazz.getFileName(),clazz.getJavaClassBytesIncludingReweavable(world));
1188
    	int index = 1;
1189
    	int index = 1;
1189
    	for (Iterator iter = childClasses.iterator(); iter.hasNext();) {
1190
    	for (Iterator iter = childClasses.iterator(); iter.hasNext();) {
1190
			UnwovenClassFile.ChildClass element = (UnwovenClassFile.ChildClass) iter.next();
1191
			UnwovenClassFile.ChildClass element = (UnwovenClassFile.ChildClass) iter.next();
(-)src/org/aspectj/weaver/bcel/LazyClassGen.java (+14 lines)
Lines 600-605 Link Here
600
        writeBack(world);
600
        writeBack(world);
601
        return myGen.getJavaClass();
601
        return myGen.getJavaClass();
602
    }
602
    }
603
    
604
    private boolean reweavableDataInserted; // ajh02: added
605
    public byte[] getJavaClassBytesIncludingReweavable(BcelWorld world){
606
    	// ajh02: method added
607
        writeBack(world);
608
        byte wovenClassFileData[] = myGen.getJavaClass().getBytes();
609
        WeaverStateInfo wsi = getOrCreateWeaverStateInfo();
610
        if(wsi != null && !reweavableDataInserted){
611
            reweavableDataInserted = true;
612
            return wsi.insertAnyReweavableData(wovenClassFileData);
613
        } else{
614
            return wovenClassFileData;
615
        }
616
    }
603
617
604
    public void addGeneratedInner(LazyClassGen newClass) {
618
    public void addGeneratedInner(LazyClassGen newClass) {
605
        classGens.add(newClass);
619
        classGens.add(newClass);

Return to bug 91417