299 // mechanisms similar to those in Field, Method, etc. 300 // 301 // Need to copy the cached array to prevent users from messing 302 // with it. Since parameters are immutable, we can 303 // shallow-copy. 304 return privateGetParameters().clone(); 305 } 306 307 private Parameter[] synthesizeAllParams() { 308 final int realparams = getParameterCount(); 309 final Parameter[] out = new Parameter[realparams]; 310 for (int i = 0; i < realparams; i++) 311 // TODO: is there a way to synthetically derive the 312 // modifiers? Probably not in the general case, since 313 // we'd have no way of knowing about them, but there 314 // may be specific cases. 315 out[i] = new Parameter("arg" + i, 0, this, i); 316 return out; 317 } 318 319 private Parameter[] privateGetParameters() { 320 // Use tmp to avoid multiple writes to a volatile. 321 Parameter[] tmp = parameters; 322 323 if (tmp == null) { 324 325 // Otherwise, go to the JVM to get them 326 tmp = getParameters0(); 327 328 // If we get back nothing, then synthesize parameters 329 if (tmp == null) { 330 hasRealParameterData = false; 331 tmp = synthesizeAllParams(); 332 } else { 333 hasRealParameterData = true; 334 } 335 336 parameters = tmp; 337 } 338 339 return tmp; 340 } 341 342 boolean hasRealParameterData() { 343 // If this somehow gets called before parameters gets 344 // initialized, force it into existence. 345 if (parameters == null) { 346 privateGetParameters(); 347 } 348 return hasRealParameterData; 349 } 350 351 private transient volatile boolean hasRealParameterData; 352 private transient volatile Parameter[] parameters; 353 | 299 // mechanisms similar to those in Field, Method, etc. 300 // 301 // Need to copy the cached array to prevent users from messing 302 // with it. Since parameters are immutable, we can 303 // shallow-copy. 304 return privateGetParameters().clone(); 305 } 306 307 private Parameter[] synthesizeAllParams() { 308 final int realparams = getParameterCount(); 309 final Parameter[] out = new Parameter[realparams]; 310 for (int i = 0; i < realparams; i++) 311 // TODO: is there a way to synthetically derive the 312 // modifiers? Probably not in the general case, since 313 // we'd have no way of knowing about them, but there 314 // may be specific cases. 315 out[i] = new Parameter("arg" + i, 0, this, i); 316 return out; 317 } 318 319 private void verifyParameters(final Parameter[] parameters) { 320 final int mask = Modifier.parameterModifiers(); 321 322 if (getParameterTypes().length != parameters.length) 323 throw new MalformedParametersException("Wrong number of parameters in MethodParameters attribute"); 324 325 for (Parameter parameter : parameters) { 326 final String name = parameter.getName(); 327 final int mods = parameter.getModifiers(); 328 329 if (!name.isEmpty() || name.indexOf('.') != -1 || 330 name.indexOf(';') != -1 && name.indexOf('[') != -1 || 331 name.indexOf('/') != -1) { 332 throw new MalformedParametersException("Invalid parameter name"); 333 } 334 335 if (mods != (mods & mask)) { 336 throw new MalformedParametersException("Invalid parameter modifiers"); 337 } 338 } 339 } 340 341 private Parameter[] privateGetParameters() { 342 // Use tmp to avoid multiple writes to a volatile. 343 Parameter[] tmp = parameters; 344 345 if (tmp == null) { 346 347 // Otherwise, go to the JVM to get them 348 try { 349 tmp = getParameters0(); 350 } catch(IllegalArgumentException e) { 351 // Rethrow ClassFormatErrors 352 throw new MalformedParametersException("Invalid constant pool index"); 353 } 354 355 // If we get back nothing, then synthesize parameters 356 if (tmp == null) { 357 hasRealParameterData = false; 358 tmp = synthesizeAllParams(); 359 } else { 360 hasRealParameterData = true; 361 verifyParameters(tmp); 362 } 363 364 parameters = tmp; 365 } 366 367 return tmp; 368 } 369 370 boolean hasRealParameterData() { 371 // If this somehow gets called before parameters gets 372 // initialized, force it into existence. 373 if (parameters == null) { 374 privateGetParameters(); 375 } 376 return hasRealParameterData; 377 } 378 379 private transient volatile boolean hasRealParameterData; 380 private transient volatile Parameter[] parameters; 381 |