1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.dx.rop.code; 18 19 import com.android.dx.rop.cst.Constant; 20 import com.android.dx.rop.cst.CstBaseMethodRef; 21 import com.android.dx.rop.cst.CstMethodRef; 22 import com.android.dx.rop.cst.CstType; 23 import com.android.dx.rop.type.Prototype; 24 import com.android.dx.rop.type.StdTypeList; 25 import com.android.dx.rop.type.Type; 26 import com.android.dx.rop.type.TypeBearer; 27 import com.android.dx.rop.type.TypeList; 28 29 /** 30 * Standard instances of {@link Rop}. 31 */ 32 public final class Rops { 33 /** {@code nop()} */ 34 public static final Rop NOP = 35 new Rop(RegOps.NOP, Type.VOID, StdTypeList.EMPTY, "nop"); 36 37 /** {@code r,x: int :: r = x;} */ 38 public static final Rop MOVE_INT = 39 new Rop(RegOps.MOVE, Type.INT, StdTypeList.INT, "move-int"); 40 41 /** {@code r,x: long :: r = x;} */ 42 public static final Rop MOVE_LONG = 43 new Rop(RegOps.MOVE, Type.LONG, StdTypeList.LONG, "move-long"); 44 45 /** {@code r,x: float :: r = x;} */ 46 public static final Rop MOVE_FLOAT = 47 new Rop(RegOps.MOVE, Type.FLOAT, StdTypeList.FLOAT, "move-float"); 48 49 /** {@code r,x: double :: r = x;} */ 50 public static final Rop MOVE_DOUBLE = 51 new Rop(RegOps.MOVE, Type.DOUBLE, StdTypeList.DOUBLE, "move-double"); 52 53 /** {@code r,x: Object :: r = x;} */ 54 public static final Rop MOVE_OBJECT = 55 new Rop(RegOps.MOVE, Type.OBJECT, StdTypeList.OBJECT, "move-object"); 56 57 /** 58 * {@code r,x: ReturnAddress :: r = x;} 59 * 60 * Note that this rop-form instruction has no dex-form equivilent and 61 * must be removed before the dex conversion. 62 */ 63 public static final Rop MOVE_RETURN_ADDRESS = 64 new Rop(RegOps.MOVE, Type.RETURN_ADDRESS, 65 StdTypeList.RETURN_ADDRESS, "move-return-address"); 66 67 /** {@code r,param(x): int :: r = param(x);} */ 68 public static final Rop MOVE_PARAM_INT = 69 new Rop(RegOps.MOVE_PARAM, Type.INT, StdTypeList.EMPTY, 70 "move-param-int"); 71 72 /** {@code r,param(x): long :: r = param(x);} */ 73 public static final Rop MOVE_PARAM_LONG = 74 new Rop(RegOps.MOVE_PARAM, Type.LONG, StdTypeList.EMPTY, 75 "move-param-long"); 76 77 /** {@code r,param(x): float :: r = param(x);} */ 78 public static final Rop MOVE_PARAM_FLOAT = 79 new Rop(RegOps.MOVE_PARAM, Type.FLOAT, StdTypeList.EMPTY, 80 "move-param-float"); 81 82 /** {@code r,param(x): double :: r = param(x);} */ 83 public static final Rop MOVE_PARAM_DOUBLE = 84 new Rop(RegOps.MOVE_PARAM, Type.DOUBLE, StdTypeList.EMPTY, 85 "move-param-double"); 86 87 /** {@code r,param(x): Object :: r = param(x);} */ 88 public static final Rop MOVE_PARAM_OBJECT = 89 new Rop(RegOps.MOVE_PARAM, Type.OBJECT, StdTypeList.EMPTY, 90 "move-param-object"); 91 92 /** {@code r, literal: int :: r = literal;} */ 93 public static final Rop CONST_INT = 94 new Rop(RegOps.CONST, Type.INT, StdTypeList.EMPTY, "const-int"); 95 96 /** {@code r, literal: long :: r = literal;} */ 97 public static final Rop CONST_LONG = 98 new Rop(RegOps.CONST, Type.LONG, StdTypeList.EMPTY, "const-long"); 99 100 /** {@code r, literal: float :: r = literal;} */ 101 public static final Rop CONST_FLOAT = 102 new Rop(RegOps.CONST, Type.FLOAT, StdTypeList.EMPTY, "const-float"); 103 104 /** {@code r, literal: double :: r = literal;} */ 105 public static final Rop CONST_DOUBLE = 106 new Rop(RegOps.CONST, Type.DOUBLE, StdTypeList.EMPTY, "const-double"); 107 108 /** {@code r, literal: Object :: r = literal;} */ 109 public static final Rop CONST_OBJECT = 110 new Rop(RegOps.CONST, Type.OBJECT, StdTypeList.EMPTY, 111 Exceptions.LIST_Error, "const-object"); 112 113 /** {@code r, literal: Object :: r = literal;} */ 114 public static final Rop CONST_OBJECT_NOTHROW = 115 new Rop(RegOps.CONST, Type.OBJECT, StdTypeList.EMPTY, 116 "const-object-nothrow"); 117 118 /** {@code goto label} */ 119 public static final Rop GOTO = 120 new Rop(RegOps.GOTO, Type.VOID, StdTypeList.EMPTY, Rop.BRANCH_GOTO, 121 "goto"); 122 123 /** {@code x: int :: if (x == 0) goto label} */ 124 public static final Rop IF_EQZ_INT = 125 new Rop(RegOps.IF_EQ, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF, 126 "if-eqz-int"); 127 128 /** {@code x: int :: if (x != 0) goto label} */ 129 public static final Rop IF_NEZ_INT = 130 new Rop(RegOps.IF_NE, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF, 131 "if-nez-int"); 132 133 /** {@code x: int :: if (x < 0) goto label} */ 134 public static final Rop IF_LTZ_INT = 135 new Rop(RegOps.IF_LT, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF, 136 "if-ltz-int"); 137 138 /** {@code x: int :: if (x >= 0) goto label} */ 139 public static final Rop IF_GEZ_INT = 140 new Rop(RegOps.IF_GE, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF, 141 "if-gez-int"); 142 143 /** {@code x: int :: if (x <= 0) goto label} */ 144 public static final Rop IF_LEZ_INT = 145 new Rop(RegOps.IF_LE, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF, 146 "if-lez-int"); 147 148 /** {@code x: int :: if (x > 0) goto label} */ 149 public static final Rop IF_GTZ_INT = 150 new Rop(RegOps.IF_GT, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF, 151 "if-gtz-int"); 152 153 /** {@code x: Object :: if (x == null) goto label} */ 154 public static final Rop IF_EQZ_OBJECT = 155 new Rop(RegOps.IF_EQ, Type.VOID, StdTypeList.OBJECT, Rop.BRANCH_IF, 156 "if-eqz-object"); 157 158 /** {@code x: Object :: if (x != null) goto label} */ 159 public static final Rop IF_NEZ_OBJECT = 160 new Rop(RegOps.IF_NE, Type.VOID, StdTypeList.OBJECT, Rop.BRANCH_IF, 161 "if-nez-object"); 162 163 /** {@code x,y: int :: if (x == y) goto label} */ 164 public static final Rop IF_EQ_INT = 165 new Rop(RegOps.IF_EQ, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF, 166 "if-eq-int"); 167 168 /** {@code x,y: int :: if (x != y) goto label} */ 169 public static final Rop IF_NE_INT = 170 new Rop(RegOps.IF_NE, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF, 171 "if-ne-int"); 172 173 /** {@code x,y: int :: if (x < y) goto label} */ 174 public static final Rop IF_LT_INT = 175 new Rop(RegOps.IF_LT, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF, 176 "if-lt-int"); 177 178 /** {@code x,y: int :: if (x >= y) goto label} */ 179 public static final Rop IF_GE_INT = 180 new Rop(RegOps.IF_GE, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF, 181 "if-ge-int"); 182 183 /** {@code x,y: int :: if (x <= y) goto label} */ 184 public static final Rop IF_LE_INT = 185 new Rop(RegOps.IF_LE, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF, 186 "if-le-int"); 187 188 /** {@code x,y: int :: if (x > y) goto label} */ 189 public static final Rop IF_GT_INT = 190 new Rop(RegOps.IF_GT, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF, 191 "if-gt-int"); 192 193 /** {@code x,y: Object :: if (x == y) goto label} */ 194 public static final Rop IF_EQ_OBJECT = 195 new Rop(RegOps.IF_EQ, Type.VOID, StdTypeList.OBJECT_OBJECT, 196 Rop.BRANCH_IF, "if-eq-object"); 197 198 /** {@code x,y: Object :: if (x != y) goto label} */ 199 public static final Rop IF_NE_OBJECT = 200 new Rop(RegOps.IF_NE, Type.VOID, StdTypeList.OBJECT_OBJECT, 201 Rop.BRANCH_IF, "if-ne-object"); 202 203 /** {@code x: int :: goto switchtable[x]} */ 204 public static final Rop SWITCH = 205 new Rop(RegOps.SWITCH, Type.VOID, StdTypeList.INT, Rop.BRANCH_SWITCH, 206 "switch"); 207 208 /** {@code r,x,y: int :: r = x + y;} */ 209 public static final Rop ADD_INT = 210 new Rop(RegOps.ADD, Type.INT, StdTypeList.INT_INT, "add-int"); 211 212 /** {@code r,x,y: long :: r = x + y;} */ 213 public static final Rop ADD_LONG = 214 new Rop(RegOps.ADD, Type.LONG, StdTypeList.LONG_LONG, "add-long"); 215 216 /** {@code r,x,y: float :: r = x + y;} */ 217 public static final Rop ADD_FLOAT = 218 new Rop(RegOps.ADD, Type.FLOAT, StdTypeList.FLOAT_FLOAT, "add-float"); 219 220 /** {@code r,x,y: double :: r = x + y;} */ 221 public static final Rop ADD_DOUBLE = 222 new Rop(RegOps.ADD, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE, 223 Rop.BRANCH_NONE, "add-double"); 224 225 /** {@code r,x,y: int :: r = x - y;} */ 226 public static final Rop SUB_INT = 227 new Rop(RegOps.SUB, Type.INT, StdTypeList.INT_INT, "sub-int"); 228 229 /** {@code r,x,y: long :: r = x - y;} */ 230 public static final Rop SUB_LONG = 231 new Rop(RegOps.SUB, Type.LONG, StdTypeList.LONG_LONG, "sub-long"); 232 233 /** {@code r,x,y: float :: r = x - y;} */ 234 public static final Rop SUB_FLOAT = 235 new Rop(RegOps.SUB, Type.FLOAT, StdTypeList.FLOAT_FLOAT, "sub-float"); 236 237 /** {@code r,x,y: double :: r = x - y;} */ 238 public static final Rop SUB_DOUBLE = 239 new Rop(RegOps.SUB, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE, 240 Rop.BRANCH_NONE, "sub-double"); 241 242 /** {@code r,x,y: int :: r = x * y;} */ 243 public static final Rop MUL_INT = 244 new Rop(RegOps.MUL, Type.INT, StdTypeList.INT_INT, "mul-int"); 245 246 /** {@code r,x,y: long :: r = x * y;} */ 247 public static final Rop MUL_LONG = 248 new Rop(RegOps.MUL, Type.LONG, StdTypeList.LONG_LONG, "mul-long"); 249 250 /** {@code r,x,y: float :: r = x * y;} */ 251 public static final Rop MUL_FLOAT = 252 new Rop(RegOps.MUL, Type.FLOAT, StdTypeList.FLOAT_FLOAT, "mul-float"); 253 254 /** {@code r,x,y: double :: r = x * y;} */ 255 public static final Rop MUL_DOUBLE = 256 new Rop(RegOps.MUL, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE, 257 Rop.BRANCH_NONE, "mul-double"); 258 259 /** {@code r,x,y: int :: r = x / y;} */ 260 public static final Rop DIV_INT = 261 new Rop(RegOps.DIV, Type.INT, StdTypeList.INT_INT, 262 Exceptions.LIST_Error_ArithmeticException, "div-int"); 263 264 /** {@code r,x,y: long :: r = x / y;} */ 265 public static final Rop DIV_LONG = 266 new Rop(RegOps.DIV, Type.LONG, StdTypeList.LONG_LONG, 267 Exceptions.LIST_Error_ArithmeticException, "div-long"); 268 269 /** {@code r,x,y: float :: r = x / y;} */ 270 public static final Rop DIV_FLOAT = 271 new Rop(RegOps.DIV, Type.FLOAT, StdTypeList.FLOAT_FLOAT, "div-float"); 272 273 /** {@code r,x,y: double :: r = x / y;} */ 274 public static final Rop DIV_DOUBLE = 275 new Rop(RegOps.DIV, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE, 276 "div-double"); 277 278 /** {@code r,x,y: int :: r = x % y;} */ 279 public static final Rop REM_INT = 280 new Rop(RegOps.REM, Type.INT, StdTypeList.INT_INT, 281 Exceptions.LIST_Error_ArithmeticException, "rem-int"); 282 283 /** {@code r,x,y: long :: r = x % y;} */ 284 public static final Rop REM_LONG = 285 new Rop(RegOps.REM, Type.LONG, StdTypeList.LONG_LONG, 286 Exceptions.LIST_Error_ArithmeticException, "rem-long"); 287 288 /** {@code r,x,y: float :: r = x % y;} */ 289 public static final Rop REM_FLOAT = 290 new Rop(RegOps.REM, Type.FLOAT, StdTypeList.FLOAT_FLOAT, "rem-float"); 291 292 /** {@code r,x,y: double :: r = x % y;} */ 293 public static final Rop REM_DOUBLE = 294 new Rop(RegOps.REM, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE, 295 "rem-double"); 296 297 /** {@code r,x: int :: r = -x;} */ 298 public static final Rop NEG_INT = 299 new Rop(RegOps.NEG, Type.INT, StdTypeList.INT, "neg-int"); 300 301 /** {@code r,x: long :: r = -x;} */ 302 public static final Rop NEG_LONG = 303 new Rop(RegOps.NEG, Type.LONG, StdTypeList.LONG, "neg-long"); 304 305 /** {@code r,x: float :: r = -x;} */ 306 public static final Rop NEG_FLOAT = 307 new Rop(RegOps.NEG, Type.FLOAT, StdTypeList.FLOAT, "neg-float"); 308 309 /** {@code r,x: double :: r = -x;} */ 310 public static final Rop NEG_DOUBLE = 311 new Rop(RegOps.NEG, Type.DOUBLE, StdTypeList.DOUBLE, "neg-double"); 312 313 /** {@code r,x,y: int :: r = x & y;} */ 314 public static final Rop AND_INT = 315 new Rop(RegOps.AND, Type.INT, StdTypeList.INT_INT, "and-int"); 316 317 /** {@code r,x,y: long :: r = x & y;} */ 318 public static final Rop AND_LONG = 319 new Rop(RegOps.AND, Type.LONG, StdTypeList.LONG_LONG, "and-long"); 320 321 /** {@code r,x,y: int :: r = x | y;} */ 322 public static final Rop OR_INT = 323 new Rop(RegOps.OR, Type.INT, StdTypeList.INT_INT, "or-int"); 324 325 /** {@code r,x,y: long :: r = x | y;} */ 326 public static final Rop OR_LONG = 327 new Rop(RegOps.OR, Type.LONG, StdTypeList.LONG_LONG, "or-long"); 328 329 /** {@code r,x,y: int :: r = x ^ y;} */ 330 public static final Rop XOR_INT = 331 new Rop(RegOps.XOR, Type.INT, StdTypeList.INT_INT, "xor-int"); 332 333 /** {@code r,x,y: long :: r = x ^ y;} */ 334 public static final Rop XOR_LONG = 335 new Rop(RegOps.XOR, Type.LONG, StdTypeList.LONG_LONG, "xor-long"); 336 337 /** {@code r,x,y: int :: r = x << y;} */ 338 public static final Rop SHL_INT = 339 new Rop(RegOps.SHL, Type.INT, StdTypeList.INT_INT, "shl-int"); 340 341 /** {@code r,x: long; y: int :: r = x << y;} */ 342 public static final Rop SHL_LONG = 343 new Rop(RegOps.SHL, Type.LONG, StdTypeList.LONG_INT, "shl-long"); 344 345 /** {@code r,x,y: int :: r = x >> y;} */ 346 public static final Rop SHR_INT = 347 new Rop(RegOps.SHR, Type.INT, StdTypeList.INT_INT, "shr-int"); 348 349 /** {@code r,x: long; y: int :: r = x >> y;} */ 350 public static final Rop SHR_LONG = 351 new Rop(RegOps.SHR, Type.LONG, StdTypeList.LONG_INT, "shr-long"); 352 353 /** {@code r,x,y: int :: r = x >>> y;} */ 354 public static final Rop USHR_INT = 355 new Rop(RegOps.USHR, Type.INT, StdTypeList.INT_INT, "ushr-int"); 356 357 /** {@code r,x: long; y: int :: r = x >>> y;} */ 358 public static final Rop USHR_LONG = 359 new Rop(RegOps.USHR, Type.LONG, StdTypeList.LONG_INT, "ushr-long"); 360 361 /** {@code r,x: int :: r = ~x;} */ 362 public static final Rop NOT_INT = 363 new Rop(RegOps.NOT, Type.INT, StdTypeList.INT, "not-int"); 364 365 /** {@code r,x: long :: r = ~x;} */ 366 public static final Rop NOT_LONG = 367 new Rop(RegOps.NOT, Type.LONG, StdTypeList.LONG, "not-long"); 368 369 /** {@code r,x,c: int :: r = x + c;} */ 370 public static final Rop ADD_CONST_INT = 371 new Rop(RegOps.ADD, Type.INT, StdTypeList.INT, "add-const-int"); 372 373 /** {@code r,x,c: long :: r = x + c;} */ 374 public static final Rop ADD_CONST_LONG = 375 new Rop(RegOps.ADD, Type.LONG, StdTypeList.LONG, "add-const-long"); 376 377 /** {@code r,x,c: float :: r = x + c;} */ 378 public static final Rop ADD_CONST_FLOAT = 379 new Rop(RegOps.ADD, Type.FLOAT, StdTypeList.FLOAT, "add-const-float"); 380 381 /** {@code r,x,c: double :: r = x + c;} */ 382 public static final Rop ADD_CONST_DOUBLE = 383 new Rop(RegOps.ADD, Type.DOUBLE, StdTypeList.DOUBLE, 384 "add-const-double"); 385 386 /** {@code r,x,c: int :: r = x - c;} */ 387 public static final Rop SUB_CONST_INT = 388 new Rop(RegOps.SUB, Type.INT, StdTypeList.INT, "sub-const-int"); 389 390 /** {@code r,x,c: long :: r = x - c;} */ 391 public static final Rop SUB_CONST_LONG = 392 new Rop(RegOps.SUB, Type.LONG, StdTypeList.LONG, "sub-const-long"); 393 394 /** {@code r,x,c: float :: r = x - c;} */ 395 public static final Rop SUB_CONST_FLOAT = 396 new Rop(RegOps.SUB, Type.FLOAT, StdTypeList.FLOAT, "sub-const-float"); 397 398 /** {@code r,x,c: double :: r = x - c;} */ 399 public static final Rop SUB_CONST_DOUBLE = 400 new Rop(RegOps.SUB, Type.DOUBLE, StdTypeList.DOUBLE, 401 "sub-const-double"); 402 403 /** {@code r,x,c: int :: r = x * c;} */ 404 public static final Rop MUL_CONST_INT = 405 new Rop(RegOps.MUL, Type.INT, StdTypeList.INT, "mul-const-int"); 406 407 /** {@code r,x,c: long :: r = x * c;} */ 408 public static final Rop MUL_CONST_LONG = 409 new Rop(RegOps.MUL, Type.LONG, StdTypeList.LONG, "mul-const-long"); 410 411 /** {@code r,x,c: float :: r = x * c;} */ 412 public static final Rop MUL_CONST_FLOAT = 413 new Rop(RegOps.MUL, Type.FLOAT, StdTypeList.FLOAT, "mul-const-float"); 414 415 /** {@code r,x,c: double :: r = x * c;} */ 416 public static final Rop MUL_CONST_DOUBLE = 417 new Rop(RegOps.MUL, Type.DOUBLE, StdTypeList.DOUBLE, 418 "mul-const-double"); 419 420 /** {@code r,x,c: int :: r = x / c;} */ 421 public static final Rop DIV_CONST_INT = 422 new Rop(RegOps.DIV, Type.INT, StdTypeList.INT, 423 Exceptions.LIST_Error_ArithmeticException, "div-const-int"); 424 425 /** {@code r,x,c: long :: r = x / c;} */ 426 public static final Rop DIV_CONST_LONG = 427 new Rop(RegOps.DIV, Type.LONG, StdTypeList.LONG, 428 Exceptions.LIST_Error_ArithmeticException, "div-const-long"); 429 430 /** {@code r,x,c: float :: r = x / c;} */ 431 public static final Rop DIV_CONST_FLOAT = 432 new Rop(RegOps.DIV, Type.FLOAT, StdTypeList.FLOAT, "div-const-float"); 433 434 /** {@code r,x,c: double :: r = x / c;} */ 435 public static final Rop DIV_CONST_DOUBLE = 436 new Rop(RegOps.DIV, Type.DOUBLE, StdTypeList.DOUBLE, 437 "div-const-double"); 438 439 /** {@code r,x,c: int :: r = x % c;} */ 440 public static final Rop REM_CONST_INT = 441 new Rop(RegOps.REM, Type.INT, StdTypeList.INT, 442 Exceptions.LIST_Error_ArithmeticException, "rem-const-int"); 443 444 /** {@code r,x,c: long :: r = x % c;} */ 445 public static final Rop REM_CONST_LONG = 446 new Rop(RegOps.REM, Type.LONG, StdTypeList.LONG, 447 Exceptions.LIST_Error_ArithmeticException, "rem-const-long"); 448 449 /** {@code r,x,c: float :: r = x % c;} */ 450 public static final Rop REM_CONST_FLOAT = 451 new Rop(RegOps.REM, Type.FLOAT, StdTypeList.FLOAT, "rem-const-float"); 452 453 /** {@code r,x,c: double :: r = x % c;} */ 454 public static final Rop REM_CONST_DOUBLE = 455 new Rop(RegOps.REM, Type.DOUBLE, StdTypeList.DOUBLE, 456 "rem-const-double"); 457 458 /** {@code r,x,c: int :: r = x & c;} */ 459 public static final Rop AND_CONST_INT = 460 new Rop(RegOps.AND, Type.INT, StdTypeList.INT, "and-const-int"); 461 462 /** {@code r,x,c: long :: r = x & c;} */ 463 public static final Rop AND_CONST_LONG = 464 new Rop(RegOps.AND, Type.LONG, StdTypeList.LONG, "and-const-long"); 465 466 /** {@code r,x,c: int :: r = x | c;} */ 467 public static final Rop OR_CONST_INT = 468 new Rop(RegOps.OR, Type.INT, StdTypeList.INT, "or-const-int"); 469 470 /** {@code r,x,c: long :: r = x | c;} */ 471 public static final Rop OR_CONST_LONG = 472 new Rop(RegOps.OR, Type.LONG, StdTypeList.LONG, "or-const-long"); 473 474 /** {@code r,x,c: int :: r = x ^ c;} */ 475 public static final Rop XOR_CONST_INT = 476 new Rop(RegOps.XOR, Type.INT, StdTypeList.INT, "xor-const-int"); 477 478 /** {@code r,x,c: long :: r = x ^ c;} */ 479 public static final Rop XOR_CONST_LONG = 480 new Rop(RegOps.XOR, Type.LONG, StdTypeList.LONG, "xor-const-long"); 481 482 /** {@code r,x,c: int :: r = x << c;} */ 483 public static final Rop SHL_CONST_INT = 484 new Rop(RegOps.SHL, Type.INT, StdTypeList.INT, "shl-const-int"); 485 486 /** {@code r,x: long; c: int :: r = x << c;} */ 487 public static final Rop SHL_CONST_LONG = 488 new Rop(RegOps.SHL, Type.LONG, StdTypeList.INT, "shl-const-long"); 489 490 /** {@code r,x,c: int :: r = x >> c;} */ 491 public static final Rop SHR_CONST_INT = 492 new Rop(RegOps.SHR, Type.INT, StdTypeList.INT, "shr-const-int"); 493 494 /** {@code r,x: long; c: int :: r = x >> c;} */ 495 public static final Rop SHR_CONST_LONG = 496 new Rop(RegOps.SHR, Type.LONG, StdTypeList.INT, "shr-const-long"); 497 498 /** {@code r,x,c: int :: r = x >>> c;} */ 499 public static final Rop USHR_CONST_INT = 500 new Rop(RegOps.USHR, Type.INT, StdTypeList.INT, "ushr-const-int"); 501 502 /** {@code r,x: long; c: int :: r = x >>> c;} */ 503 public static final Rop USHR_CONST_LONG = 504 new Rop(RegOps.USHR, Type.LONG, StdTypeList.INT, "ushr-const-long"); 505 506 /** {@code r: int; x,y: long :: r = cmp(x, y);} */ 507 public static final Rop CMPL_LONG = 508 new Rop(RegOps.CMPL, Type.INT, StdTypeList.LONG_LONG, "cmpl-long"); 509 510 /** {@code r: int; x,y: float :: r = cmpl(x, y);} */ 511 public static final Rop CMPL_FLOAT = 512 new Rop(RegOps.CMPL, Type.INT, StdTypeList.FLOAT_FLOAT, "cmpl-float"); 513 514 /** {@code r: int; x,y: double :: r = cmpl(x, y);} */ 515 public static final Rop CMPL_DOUBLE = 516 new Rop(RegOps.CMPL, Type.INT, StdTypeList.DOUBLE_DOUBLE, 517 "cmpl-double"); 518 519 /** {@code r: int; x,y: float :: r = cmpg(x, y);} */ 520 public static final Rop CMPG_FLOAT = 521 new Rop(RegOps.CMPG, Type.INT, StdTypeList.FLOAT_FLOAT, "cmpg-float"); 522 523 /** {@code r: int; x,y: double :: r = cmpg(x, y);} */ 524 public static final Rop CMPG_DOUBLE = 525 new Rop(RegOps.CMPG, Type.INT, StdTypeList.DOUBLE_DOUBLE, 526 "cmpg-double"); 527 528 /** {@code r: int; x: long :: r = (int) x} */ 529 public static final Rop CONV_L2I = 530 new Rop(RegOps.CONV, Type.INT, StdTypeList.LONG, "conv-l2i"); 531 532 /** {@code r: int; x: float :: r = (int) x} */ 533 public static final Rop CONV_F2I = 534 new Rop(RegOps.CONV, Type.INT, StdTypeList.FLOAT, "conv-f2i"); 535 536 /** {@code r: int; x: double :: r = (int) x} */ 537 public static final Rop CONV_D2I = 538 new Rop(RegOps.CONV, Type.INT, StdTypeList.DOUBLE, "conv-d2i"); 539 540 /** {@code r: long; x: int :: r = (long) x} */ 541 public static final Rop CONV_I2L = 542 new Rop(RegOps.CONV, Type.LONG, StdTypeList.INT, "conv-i2l"); 543 544 /** {@code r: long; x: float :: r = (long) x} */ 545 public static final Rop CONV_F2L = 546 new Rop(RegOps.CONV, Type.LONG, StdTypeList.FLOAT, "conv-f2l"); 547 548 /** {@code r: long; x: double :: r = (long) x} */ 549 public static final Rop CONV_D2L = 550 new Rop(RegOps.CONV, Type.LONG, StdTypeList.DOUBLE, "conv-d2l"); 551 552 /** {@code r: float; x: int :: r = (float) x} */ 553 public static final Rop CONV_I2F = 554 new Rop(RegOps.CONV, Type.FLOAT, StdTypeList.INT, "conv-i2f"); 555 556 /** {@code r: float; x: long :: r = (float) x} */ 557 public static final Rop CONV_L2F = 558 new Rop(RegOps.CONV, Type.FLOAT, StdTypeList.LONG, "conv-l2f"); 559 560 /** {@code r: float; x: double :: r = (float) x} */ 561 public static final Rop CONV_D2F = 562 new Rop(RegOps.CONV, Type.FLOAT, StdTypeList.DOUBLE, "conv-d2f"); 563 564 /** {@code r: double; x: int :: r = (double) x} */ 565 public static final Rop CONV_I2D = 566 new Rop(RegOps.CONV, Type.DOUBLE, StdTypeList.INT, "conv-i2d"); 567 568 /** {@code r: double; x: long :: r = (double) x} */ 569 public static final Rop CONV_L2D = 570 new Rop(RegOps.CONV, Type.DOUBLE, StdTypeList.LONG, "conv-l2d"); 571 572 /** {@code r: double; x: float :: r = (double) x} */ 573 public static final Rop CONV_F2D = 574 new Rop(RegOps.CONV, Type.DOUBLE, StdTypeList.FLOAT, "conv-f2d"); 575 576 /** 577 * {@code r,x: int :: r = (x << 24) >> 24} (Java-style 578 * convert int to byte) 579 */ 580 public static final Rop TO_BYTE = 581 new Rop(RegOps.TO_BYTE, Type.INT, StdTypeList.INT, "to-byte"); 582 583 /** 584 * {@code r,x: int :: r = x & 0xffff} (Java-style 585 * convert int to char) 586 */ 587 public static final Rop TO_CHAR = 588 new Rop(RegOps.TO_CHAR, Type.INT, StdTypeList.INT, "to-char"); 589 590 /** 591 * {@code r,x: int :: r = (x << 16) >> 16} (Java-style 592 * convert int to short) 593 */ 594 public static final Rop TO_SHORT = 595 new Rop(RegOps.TO_SHORT, Type.INT, StdTypeList.INT, "to-short"); 596 597 /** {@code return void} */ 598 public static final Rop RETURN_VOID = 599 new Rop(RegOps.RETURN, Type.VOID, StdTypeList.EMPTY, Rop.BRANCH_RETURN, 600 "return-void"); 601 602 /** {@code x: int; return x} */ 603 public static final Rop RETURN_INT = 604 new Rop(RegOps.RETURN, Type.VOID, StdTypeList.INT, Rop.BRANCH_RETURN, 605 "return-int"); 606 607 /** {@code x: long; return x} */ 608 public static final Rop RETURN_LONG = 609 new Rop(RegOps.RETURN, Type.VOID, StdTypeList.LONG, Rop.BRANCH_RETURN, 610 "return-long"); 611 612 /** {@code x: float; return x} */ 613 public static final Rop RETURN_FLOAT = 614 new Rop(RegOps.RETURN, Type.VOID, StdTypeList.FLOAT, Rop.BRANCH_RETURN, 615 "return-float"); 616 617 /** {@code x: double; return x} */ 618 public static final Rop RETURN_DOUBLE = 619 new Rop(RegOps.RETURN, Type.VOID, StdTypeList.DOUBLE, 620 Rop.BRANCH_RETURN, "return-double"); 621 622 /** {@code x: Object; return x} */ 623 public static final Rop RETURN_OBJECT = 624 new Rop(RegOps.RETURN, Type.VOID, StdTypeList.OBJECT, 625 Rop.BRANCH_RETURN, "return-object"); 626 627 /** {@code T: any type; r: int; x: T[]; :: r = x.length} */ 628 public static final Rop ARRAY_LENGTH = 629 new Rop(RegOps.ARRAY_LENGTH, Type.INT, StdTypeList.OBJECT, 630 Exceptions.LIST_Error_NullPointerException, "array-length"); 631 632 /** {@code x: Throwable :: throw(x)} */ 633 public static final Rop THROW = 634 new Rop(RegOps.THROW, Type.VOID, StdTypeList.THROWABLE, 635 StdTypeList.THROWABLE, "throw"); 636 637 /** {@code x: Object :: monitorenter(x)} */ 638 public static final Rop MONITOR_ENTER = 639 new Rop(RegOps.MONITOR_ENTER, Type.VOID, StdTypeList.OBJECT, 640 Exceptions.LIST_Error_NullPointerException, "monitor-enter"); 641 642 /** {@code x: Object :: monitorexit(x)} */ 643 public static final Rop MONITOR_EXIT = 644 new Rop(RegOps.MONITOR_EXIT, Type.VOID, StdTypeList.OBJECT, 645 Exceptions.LIST_Error_Null_IllegalMonitorStateException, 646 "monitor-exit"); 647 648 /** {@code r,y: int; x: int[] :: r = x[y]} */ 649 public static final Rop AGET_INT = 650 new Rop(RegOps.AGET, Type.INT, StdTypeList.INTARR_INT, 651 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, 652 "aget-int"); 653 654 /** {@code r: long; x: long[]; y: int :: r = x[y]} */ 655 public static final Rop AGET_LONG = 656 new Rop(RegOps.AGET, Type.LONG, StdTypeList.LONGARR_INT, 657 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, 658 "aget-long"); 659 660 /** {@code r: float; x: float[]; y: int :: r = x[y]} */ 661 public static final Rop AGET_FLOAT = 662 new Rop(RegOps.AGET, Type.FLOAT, StdTypeList.FLOATARR_INT, 663 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, 664 "aget-float"); 665 666 /** {@code r: double; x: double[]; y: int :: r = x[y]} */ 667 public static final Rop AGET_DOUBLE = 668 new Rop(RegOps.AGET, Type.DOUBLE, StdTypeList.DOUBLEARR_INT, 669 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, 670 "aget-double"); 671 672 /** {@code r: Object; x: Object[]; y: int :: r = x[y]} */ 673 public static final Rop AGET_OBJECT = 674 new Rop(RegOps.AGET, Type.OBJECT, StdTypeList.OBJECTARR_INT, 675 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, 676 "aget-object"); 677 678 /** {@code r: boolean; x: boolean[]; y: int :: r = x[y]} */ 679 public static final Rop AGET_BOOLEAN = 680 new Rop(RegOps.AGET, Type.INT, StdTypeList.BOOLEANARR_INT, 681 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, 682 "aget-boolean"); 683 684 /** {@code r: byte; x: byte[]; y: int :: r = x[y]} */ 685 public static final Rop AGET_BYTE = 686 new Rop(RegOps.AGET, Type.INT, StdTypeList.BYTEARR_INT, 687 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, "aget-byte"); 688 689 /** {@code r: char; x: char[]; y: int :: r = x[y]} */ 690 public static final Rop AGET_CHAR = 691 new Rop(RegOps.AGET, Type.INT, StdTypeList.CHARARR_INT, 692 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, "aget-char"); 693 694 /** {@code r: short; x: short[]; y: int :: r = x[y]} */ 695 public static final Rop AGET_SHORT = 696 new Rop(RegOps.AGET, Type.INT, StdTypeList.SHORTARR_INT, 697 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, 698 "aget-short"); 699 700 /** {@code x,z: int; y: int[] :: y[z] = x} */ 701 public static final Rop APUT_INT = 702 new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_INTARR_INT, 703 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, "aput-int"); 704 705 /** {@code x: long; y: long[]; z: int :: y[z] = x} */ 706 public static final Rop APUT_LONG = 707 new Rop(RegOps.APUT, Type.VOID, StdTypeList.LONG_LONGARR_INT, 708 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, "aput-long"); 709 710 /** {@code x: float; y: float[]; z: int :: y[z] = x} */ 711 public static final Rop APUT_FLOAT = 712 new Rop(RegOps.APUT, Type.VOID, StdTypeList.FLOAT_FLOATARR_INT, 713 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, 714 "aput-float"); 715 716 /** {@code x: double; y: double[]; z: int :: y[z] = x} */ 717 public static final Rop APUT_DOUBLE = 718 new Rop(RegOps.APUT, Type.VOID, StdTypeList.DOUBLE_DOUBLEARR_INT, 719 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, 720 "aput-double"); 721 722 /** {@code x: Object; y: Object[]; z: int :: y[z] = x} */ 723 public static final Rop APUT_OBJECT = 724 new Rop(RegOps.APUT, Type.VOID, StdTypeList.OBJECT_OBJECTARR_INT, 725 Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore, 726 "aput-object"); 727 728 /** {@code x: boolean; y: boolean[]; z: int :: y[z] = x} */ 729 public static final Rop APUT_BOOLEAN = 730 new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_BOOLEANARR_INT, 731 Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore, 732 "aput-boolean"); 733 734 /** {@code x: byte; y: byte[]; z: int :: y[z] = x} */ 735 public static final Rop APUT_BYTE = 736 new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_BYTEARR_INT, 737 Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore, "aput-byte"); 738 739 /** {@code x: char; y: char[]; z: int :: y[z] = x} */ 740 public static final Rop APUT_CHAR = 741 new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_CHARARR_INT, 742 Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore, "aput-char"); 743 744 /** {@code x: short; y: short[]; z: int :: y[z] = x} */ 745 public static final Rop APUT_SHORT = 746 new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_SHORTARR_INT, 747 Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore, 748 "aput-short"); 749 750 /** 751 * {@code T: any non-array object type :: r = 752 * alloc(T)} (allocate heap space for an object) 753 */ 754 public static final Rop NEW_INSTANCE = 755 new Rop(RegOps.NEW_INSTANCE, Type.OBJECT, StdTypeList.EMPTY, 756 Exceptions.LIST_Error, "new-instance"); 757 758 /** {@code r: int[]; x: int :: r = new int[x]} */ 759 public static final Rop NEW_ARRAY_INT = 760 new Rop(RegOps.NEW_ARRAY, Type.INT_ARRAY, StdTypeList.INT, 761 Exceptions.LIST_Error_NegativeArraySizeException, 762 "new-array-int"); 763 764 /** {@code r: long[]; x: int :: r = new long[x]} */ 765 public static final Rop NEW_ARRAY_LONG = 766 new Rop(RegOps.NEW_ARRAY, Type.LONG_ARRAY, StdTypeList.INT, 767 Exceptions.LIST_Error_NegativeArraySizeException, 768 "new-array-long"); 769 770 /** {@code r: float[]; x: int :: r = new float[x]} */ 771 public static final Rop NEW_ARRAY_FLOAT = 772 new Rop(RegOps.NEW_ARRAY, Type.FLOAT_ARRAY, StdTypeList.INT, 773 Exceptions.LIST_Error_NegativeArraySizeException, 774 "new-array-float"); 775 776 /** {@code r: double[]; x: int :: r = new double[x]} */ 777 public static final Rop NEW_ARRAY_DOUBLE = 778 new Rop(RegOps.NEW_ARRAY, Type.DOUBLE_ARRAY, StdTypeList.INT, 779 Exceptions.LIST_Error_NegativeArraySizeException, 780 "new-array-double"); 781 782 /** {@code r: boolean[]; x: int :: r = new boolean[x]} */ 783 public static final Rop NEW_ARRAY_BOOLEAN = 784 new Rop(RegOps.NEW_ARRAY, Type.BOOLEAN_ARRAY, StdTypeList.INT, 785 Exceptions.LIST_Error_NegativeArraySizeException, 786 "new-array-boolean"); 787 788 /** {@code r: byte[]; x: int :: r = new byte[x]} */ 789 public static final Rop NEW_ARRAY_BYTE = 790 new Rop(RegOps.NEW_ARRAY, Type.BYTE_ARRAY, StdTypeList.INT, 791 Exceptions.LIST_Error_NegativeArraySizeException, 792 "new-array-byte"); 793 794 /** {@code r: char[]; x: int :: r = new char[x]} */ 795 public static final Rop NEW_ARRAY_CHAR = 796 new Rop(RegOps.NEW_ARRAY, Type.CHAR_ARRAY, StdTypeList.INT, 797 Exceptions.LIST_Error_NegativeArraySizeException, 798 "new-array-char"); 799 800 /** {@code r: short[]; x: int :: r = new short[x]} */ 801 public static final Rop NEW_ARRAY_SHORT = 802 new Rop(RegOps.NEW_ARRAY, Type.SHORT_ARRAY, StdTypeList.INT, 803 Exceptions.LIST_Error_NegativeArraySizeException, 804 "new-array-short"); 805 806 /** 807 * {@code T: any non-array object type; x: Object :: (T) x} (can 808 * throw {@code ClassCastException}) 809 */ 810 public static final Rop CHECK_CAST = 811 new Rop(RegOps.CHECK_CAST, Type.VOID, StdTypeList.OBJECT, 812 Exceptions.LIST_Error_ClassCastException, "check-cast"); 813 814 /** 815 * {@code T: any non-array object type; x: Object :: x instanceof 816 * T}. Note: This is listed as throwing {@code Error} 817 * explicitly because the op <i>can</i> throw, but there are no 818 * other predefined exceptions for it. 819 */ 820 public static final Rop INSTANCE_OF = 821 new Rop(RegOps.INSTANCE_OF, Type.INT, StdTypeList.OBJECT, 822 Exceptions.LIST_Error, "instance-of"); 823 824 /** 825 * {@code r: int; x: Object; f: instance field spec of 826 * type int :: r = x.f} 827 */ 828 public static final Rop GET_FIELD_INT = 829 new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT, 830 Exceptions.LIST_Error_NullPointerException, "get-field-int"); 831 832 /** 833 * {@code r: long; x: Object; f: instance field spec of 834 * type long :: r = x.f} 835 */ 836 public static final Rop GET_FIELD_LONG = 837 new Rop(RegOps.GET_FIELD, Type.LONG, StdTypeList.OBJECT, 838 Exceptions.LIST_Error_NullPointerException, "get-field-long"); 839 840 /** 841 * {@code r: float; x: Object; f: instance field spec of 842 * type float :: r = x.f} 843 */ 844 public static final Rop GET_FIELD_FLOAT = 845 new Rop(RegOps.GET_FIELD, Type.FLOAT, StdTypeList.OBJECT, 846 Exceptions.LIST_Error_NullPointerException, 847 "get-field-float"); 848 849 /** 850 * {@code r: double; x: Object; f: instance field spec of 851 * type double :: r = x.f} 852 */ 853 public static final Rop GET_FIELD_DOUBLE = 854 new Rop(RegOps.GET_FIELD, Type.DOUBLE, StdTypeList.OBJECT, 855 Exceptions.LIST_Error_NullPointerException, 856 "get-field-double"); 857 858 /** 859 * {@code r: Object; x: Object; f: instance field spec of 860 * type Object :: r = x.f} 861 */ 862 public static final Rop GET_FIELD_OBJECT = 863 new Rop(RegOps.GET_FIELD, Type.OBJECT, StdTypeList.OBJECT, 864 Exceptions.LIST_Error_NullPointerException, 865 "get-field-object"); 866 867 /** 868 * {@code r: boolean; x: Object; f: instance field spec of 869 * type boolean :: r = x.f} 870 */ 871 public static final Rop GET_FIELD_BOOLEAN = 872 new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT, 873 Exceptions.LIST_Error_NullPointerException, 874 "get-field-boolean"); 875 876 /** 877 * {@code r: byte; x: Object; f: instance field spec of 878 * type byte :: r = x.f} 879 */ 880 public static final Rop GET_FIELD_BYTE = 881 new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT, 882 Exceptions.LIST_Error_NullPointerException, 883 "get-field-byte"); 884 885 /** 886 * {@code r: char; x: Object; f: instance field spec of 887 * type char :: r = x.f} 888 */ 889 public static final Rop GET_FIELD_CHAR = 890 new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT, 891 Exceptions.LIST_Error_NullPointerException, 892 "get-field-char"); 893 894 /** 895 * {@code r: short; x: Object; f: instance field spec of 896 * type short :: r = x.f} 897 */ 898 public static final Rop GET_FIELD_SHORT = 899 new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT, 900 Exceptions.LIST_Error_NullPointerException, 901 "get-field-short"); 902 903 /** {@code r: int; f: static field spec of type int :: r = f} */ 904 public static final Rop GET_STATIC_INT = 905 new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY, 906 Exceptions.LIST_Error, "get-static-int"); 907 908 /** {@code r: long; f: static field spec of type long :: r = f} */ 909 public static final Rop GET_STATIC_LONG = 910 new Rop(RegOps.GET_STATIC, Type.LONG, StdTypeList.EMPTY, 911 Exceptions.LIST_Error, "get-static-long"); 912 913 /** {@code r: float; f: static field spec of type float :: r = f} */ 914 public static final Rop GET_STATIC_FLOAT = 915 new Rop(RegOps.GET_STATIC, Type.FLOAT, StdTypeList.EMPTY, 916 Exceptions.LIST_Error, "get-static-float"); 917 918 /** {@code r: double; f: static field spec of type double :: r = f} */ 919 public static final Rop GET_STATIC_DOUBLE = 920 new Rop(RegOps.GET_STATIC, Type.DOUBLE, StdTypeList.EMPTY, 921 Exceptions.LIST_Error, "get-static-double"); 922 923 /** {@code r: Object; f: static field spec of type Object :: r = f} */ 924 public static final Rop GET_STATIC_OBJECT = 925 new Rop(RegOps.GET_STATIC, Type.OBJECT, StdTypeList.EMPTY, 926 Exceptions.LIST_Error, "get-static-object"); 927 928 /** {@code r: boolean; f: static field spec of type boolean :: r = f} */ 929 public static final Rop GET_STATIC_BOOLEAN = 930 new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY, 931 Exceptions.LIST_Error, "get-field-boolean"); 932 933 /** {@code r: byte; f: static field spec of type byte :: r = f} */ 934 public static final Rop GET_STATIC_BYTE = 935 new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY, 936 Exceptions.LIST_Error, "get-field-byte"); 937 938 /** {@code r: char; f: static field spec of type char :: r = f} */ 939 public static final Rop GET_STATIC_CHAR = 940 new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY, 941 Exceptions.LIST_Error, "get-field-char"); 942 943 /** {@code r: short; f: static field spec of type short :: r = f} */ 944 public static final Rop GET_STATIC_SHORT = 945 new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY, 946 Exceptions.LIST_Error, "get-field-short"); 947 948 /** 949 * {@code x: int; y: Object; f: instance field spec of type 950 * int :: y.f = x} 951 */ 952 public static final Rop PUT_FIELD_INT = 953 new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT, 954 Exceptions.LIST_Error_NullPointerException, "put-field-int"); 955 956 /** 957 * {@code x: long; y: Object; f: instance field spec of type 958 * long :: y.f = x} 959 */ 960 public static final Rop PUT_FIELD_LONG = 961 new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.LONG_OBJECT, 962 Exceptions.LIST_Error_NullPointerException, "put-field-long"); 963 964 /** 965 * {@code x: float; y: Object; f: instance field spec of type 966 * float :: y.f = x} 967 */ 968 public static final Rop PUT_FIELD_FLOAT = 969 new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.FLOAT_OBJECT, 970 Exceptions.LIST_Error_NullPointerException, 971 "put-field-float"); 972 973 /** 974 * {@code x: double; y: Object; f: instance field spec of type 975 * double :: y.f = x} 976 */ 977 public static final Rop PUT_FIELD_DOUBLE = 978 new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.DOUBLE_OBJECT, 979 Exceptions.LIST_Error_NullPointerException, 980 "put-field-double"); 981 982 /** 983 * {@code x: Object; y: Object; f: instance field spec of type 984 * Object :: y.f = x} 985 */ 986 public static final Rop PUT_FIELD_OBJECT = 987 new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.OBJECT_OBJECT, 988 Exceptions.LIST_Error_NullPointerException, 989 "put-field-object"); 990 991 /** 992 * {@code x: int; y: Object; f: instance field spec of type 993 * boolean :: y.f = x} 994 */ 995 public static final Rop PUT_FIELD_BOOLEAN = 996 new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT, 997 Exceptions.LIST_Error_NullPointerException, 998 "put-field-boolean"); 999 1000 /** 1001 * {@code x: int; y: Object; f: instance field spec of type 1002 * byte :: y.f = x} 1003 */ 1004 public static final Rop PUT_FIELD_BYTE = 1005 new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT, 1006 Exceptions.LIST_Error_NullPointerException, 1007 "put-field-byte"); 1008 1009 /** 1010 * {@code x: int; y: Object; f: instance field spec of type 1011 * char :: y.f = x} 1012 */ 1013 public static final Rop PUT_FIELD_CHAR = 1014 new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT, 1015 Exceptions.LIST_Error_NullPointerException, 1016 "put-field-char"); 1017 1018 /** 1019 * {@code x: int; y: Object; f: instance field spec of type 1020 * short :: y.f = x} 1021 */ 1022 public static final Rop PUT_FIELD_SHORT = 1023 new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT, 1024 Exceptions.LIST_Error_NullPointerException, 1025 "put-field-short"); 1026 1027 /** {@code f: static field spec of type int; x: int :: f = x} */ 1028 public static final Rop PUT_STATIC_INT = 1029 new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT, 1030 Exceptions.LIST_Error, "put-static-int"); 1031 1032 /** {@code f: static field spec of type long; x: long :: f = x} */ 1033 public static final Rop PUT_STATIC_LONG = 1034 new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.LONG, 1035 Exceptions.LIST_Error, "put-static-long"); 1036 1037 /** {@code f: static field spec of type float; x: float :: f = x} */ 1038 public static final Rop PUT_STATIC_FLOAT = 1039 new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.FLOAT, 1040 Exceptions.LIST_Error, "put-static-float"); 1041 1042 /** {@code f: static field spec of type double; x: double :: f = x} */ 1043 public static final Rop PUT_STATIC_DOUBLE = 1044 new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.DOUBLE, 1045 Exceptions.LIST_Error, "put-static-double"); 1046 1047 /** {@code f: static field spec of type Object; x: Object :: f = x} */ 1048 public static final Rop PUT_STATIC_OBJECT = 1049 new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.OBJECT, 1050 Exceptions.LIST_Error, "put-static-object"); 1051 1052 /** 1053 * {@code f: static field spec of type boolean; x: boolean :: f = 1054 * x} 1055 */ 1056 public static final Rop PUT_STATIC_BOOLEAN = 1057 new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT, 1058 Exceptions.LIST_Error, "put-static-boolean"); 1059 1060 /** {@code f: static field spec of type byte; x: byte :: f = x} */ 1061 public static final Rop PUT_STATIC_BYTE = 1062 new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT, 1063 Exceptions.LIST_Error, "put-static-byte"); 1064 1065 /** {@code f: static field spec of type char; x: char :: f = x} */ 1066 public static final Rop PUT_STATIC_CHAR = 1067 new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT, 1068 Exceptions.LIST_Error, "put-static-char"); 1069 1070 /** {@code f: static field spec of type short; x: short :: f = x} */ 1071 public static final Rop PUT_STATIC_SHORT = 1072 new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT, 1073 Exceptions.LIST_Error, "put-static-short"); 1074 1075 /** {@code x: Int :: local variable begins in x} */ 1076 public static final Rop MARK_LOCAL_INT = 1077 new Rop (RegOps.MARK_LOCAL, Type.VOID, 1078 StdTypeList.INT, "mark-local-int"); 1079 1080 /** {@code x: Long :: local variable begins in x} */ 1081 public static final Rop MARK_LOCAL_LONG = 1082 new Rop (RegOps.MARK_LOCAL, Type.VOID, 1083 StdTypeList.LONG, "mark-local-long"); 1084 1085 /** {@code x: Float :: local variable begins in x} */ 1086 public static final Rop MARK_LOCAL_FLOAT = 1087 new Rop (RegOps.MARK_LOCAL, Type.VOID, 1088 StdTypeList.FLOAT, "mark-local-float"); 1089 1090 /** {@code x: Double :: local variable begins in x} */ 1091 public static final Rop MARK_LOCAL_DOUBLE = 1092 new Rop (RegOps.MARK_LOCAL, Type.VOID, 1093 StdTypeList.DOUBLE, "mark-local-double"); 1094 1095 /** {@code x: Object :: local variable begins in x} */ 1096 public static final Rop MARK_LOCAL_OBJECT = 1097 new Rop (RegOps.MARK_LOCAL, Type.VOID, 1098 StdTypeList.OBJECT, "mark-local-object"); 1099 1100 /** {@code T: Any primitive type; v0..vx: T :: {v0, ..., vx}} */ 1101 public static final Rop FILL_ARRAY_DATA = 1102 new Rop(RegOps.FILL_ARRAY_DATA, Type.VOID, StdTypeList.EMPTY, 1103 "fill-array-data"); 1104 1105 /** 1106 * Returns the appropriate rop for the given opcode, destination, 1107 * and sources. The result is typically, but not necessarily, a 1108 * shared instance. 1109 * 1110 * <p><b>Note:</b> This method does not do complete error checking on 1111 * its arguments, and so it may return an instance which seemed "right 1112 * enough" even though in actuality the passed arguments don't quite 1113 * match what is returned. TODO: Revisit this issue.</p> 1114 * 1115 * @param opcode the opcode 1116 * @param dest {@code non-null;} destination (result) type, or 1117 * {@link Type#VOID} if none 1118 * @param sources {@code non-null;} list of source types 1119 * @param cst {@code null-ok;} associated constant, if any 1120 * @return {@code non-null;} an appropriate instance 1121 */ ropFor(int opcode, TypeBearer dest, TypeList sources, Constant cst)1122 public static Rop ropFor(int opcode, TypeBearer dest, TypeList sources, 1123 Constant cst) { 1124 switch (opcode) { 1125 case RegOps.NOP: return NOP; 1126 case RegOps.MOVE: return opMove(dest); 1127 case RegOps.MOVE_PARAM: return opMoveParam(dest); 1128 case RegOps.MOVE_EXCEPTION: return opMoveException(dest); 1129 case RegOps.CONST: return opConst(dest); 1130 case RegOps.GOTO: return GOTO; 1131 case RegOps.IF_EQ: return opIfEq(sources); 1132 case RegOps.IF_NE: return opIfNe(sources); 1133 case RegOps.IF_LT: return opIfLt(sources); 1134 case RegOps.IF_GE: return opIfGe(sources); 1135 case RegOps.IF_LE: return opIfLe(sources); 1136 case RegOps.IF_GT: return opIfGt(sources); 1137 case RegOps.SWITCH: return SWITCH; 1138 case RegOps.ADD: return opAdd(sources); 1139 case RegOps.SUB: return opSub(sources); 1140 case RegOps.MUL: return opMul(sources); 1141 case RegOps.DIV: return opDiv(sources); 1142 case RegOps.REM: return opRem(sources); 1143 case RegOps.NEG: return opNeg(dest); 1144 case RegOps.AND: return opAnd(sources); 1145 case RegOps.OR: return opOr(sources); 1146 case RegOps.XOR: return opXor(sources); 1147 case RegOps.SHL: return opShl(sources); 1148 case RegOps.SHR: return opShr(sources); 1149 case RegOps.USHR: return opUshr(sources); 1150 case RegOps.NOT: return opNot(dest); 1151 case RegOps.CMPL: return opCmpl(sources.getType(0)); 1152 case RegOps.CMPG: return opCmpg(sources.getType(0)); 1153 case RegOps.CONV: return opConv(dest, sources.getType(0)); 1154 case RegOps.TO_BYTE: return TO_BYTE; 1155 case RegOps.TO_CHAR: return TO_CHAR; 1156 case RegOps.TO_SHORT: return TO_SHORT; 1157 case RegOps.RETURN: { 1158 if (sources.size() == 0) { 1159 return RETURN_VOID; 1160 } 1161 return opReturn(sources.getType(0)); 1162 } 1163 case RegOps.ARRAY_LENGTH: return ARRAY_LENGTH; 1164 case RegOps.THROW: return THROW; 1165 case RegOps.MONITOR_ENTER: return MONITOR_ENTER; 1166 case RegOps.MONITOR_EXIT: return MONITOR_EXIT; 1167 case RegOps.AGET: { 1168 Type source = sources.getType(0); 1169 Type componentType; 1170 if (source == Type.KNOWN_NULL) { 1171 /* 1172 * Treat a known-null as an array of the expected 1173 * result type. 1174 */ 1175 componentType = dest.getType(); 1176 } else { 1177 componentType = source.getComponentType(); 1178 } 1179 return opAget(componentType); 1180 } 1181 case RegOps.APUT: { 1182 Type source = sources.getType(1); 1183 Type componentType; 1184 if (source == Type.KNOWN_NULL) { 1185 /* 1186 * Treat a known-null as an array of the type being 1187 * stored. 1188 */ 1189 componentType = sources.getType(0); 1190 } else { 1191 componentType = source.getComponentType(); 1192 } 1193 return opAput(componentType); 1194 } 1195 case RegOps.NEW_INSTANCE: return NEW_INSTANCE; 1196 case RegOps.NEW_ARRAY: return opNewArray(dest.getType()); 1197 case RegOps.CHECK_CAST: return CHECK_CAST; 1198 case RegOps.INSTANCE_OF: return INSTANCE_OF; 1199 case RegOps.GET_FIELD: return opGetField(dest); 1200 case RegOps.GET_STATIC: return opGetStatic(dest); 1201 case RegOps.PUT_FIELD: return opPutField(sources.getType(0)); 1202 case RegOps.PUT_STATIC: return opPutStatic(sources.getType(0)); 1203 case RegOps.INVOKE_STATIC: { 1204 return opInvokeStatic(((CstMethodRef) cst).getPrototype()); 1205 } 1206 case RegOps.INVOKE_VIRTUAL: { 1207 CstBaseMethodRef cstMeth = (CstMethodRef) cst; 1208 Prototype meth = cstMeth.getPrototype(); 1209 CstType definer = cstMeth.getDefiningClass(); 1210 meth = meth.withFirstParameter(definer.getClassType()); 1211 return opInvokeVirtual(meth); 1212 } 1213 case RegOps.INVOKE_SUPER: { 1214 CstBaseMethodRef cstMeth = (CstMethodRef) cst; 1215 Prototype meth = cstMeth.getPrototype(); 1216 CstType definer = cstMeth.getDefiningClass(); 1217 meth = meth.withFirstParameter(definer.getClassType()); 1218 return opInvokeSuper(meth); 1219 } 1220 case RegOps.INVOKE_DIRECT: { 1221 CstBaseMethodRef cstMeth = (CstMethodRef) cst; 1222 Prototype meth = cstMeth.getPrototype(); 1223 CstType definer = cstMeth.getDefiningClass(); 1224 meth = meth.withFirstParameter(definer.getClassType()); 1225 return opInvokeDirect(meth); 1226 } 1227 case RegOps.INVOKE_INTERFACE: { 1228 CstBaseMethodRef cstMeth = (CstMethodRef) cst; 1229 Prototype meth = cstMeth.getPrototype(); 1230 CstType definer = cstMeth.getDefiningClass(); 1231 meth = meth.withFirstParameter(definer.getClassType()); 1232 return opInvokeInterface(meth); 1233 } 1234 case RegOps.INVOKE_POLYMORPHIC: { 1235 CstBaseMethodRef cstMeth = (CstMethodRef) cst; 1236 Prototype proto = cstMeth.getPrototype(); 1237 CstType definer = cstMeth.getDefiningClass(); 1238 Prototype meth = proto.withFirstParameter(definer.getClassType()); 1239 return opInvokePolymorphic(meth); 1240 } 1241 } 1242 1243 throw new RuntimeException("unknown opcode " + RegOps.opName(opcode)); 1244 } 1245 1246 /** 1247 * Returns the appropriate {@code move} rop for the given type. The 1248 * result is a shared instance. 1249 * 1250 * @param type {@code non-null;} type of value being moved 1251 * @return {@code non-null;} an appropriate instance 1252 */ opMove(TypeBearer type)1253 public static Rop opMove(TypeBearer type) { 1254 switch (type.getBasicFrameType()) { 1255 case Type.BT_INT: return MOVE_INT; 1256 case Type.BT_LONG: return MOVE_LONG; 1257 case Type.BT_FLOAT: return MOVE_FLOAT; 1258 case Type.BT_DOUBLE: return MOVE_DOUBLE; 1259 case Type.BT_OBJECT: return MOVE_OBJECT; 1260 case Type.BT_ADDR: return MOVE_RETURN_ADDRESS; 1261 } 1262 1263 return throwBadType(type); 1264 } 1265 1266 /** 1267 * Returns the appropriate {@code move-param} rop for the 1268 * given type. The result is a shared instance. 1269 * 1270 * @param type {@code non-null;} type of value being moved 1271 * @return {@code non-null;} an appropriate instance 1272 */ opMoveParam(TypeBearer type)1273 public static Rop opMoveParam(TypeBearer type) { 1274 switch (type.getBasicFrameType()) { 1275 case Type.BT_INT: return MOVE_PARAM_INT; 1276 case Type.BT_LONG: return MOVE_PARAM_LONG; 1277 case Type.BT_FLOAT: return MOVE_PARAM_FLOAT; 1278 case Type.BT_DOUBLE: return MOVE_PARAM_DOUBLE; 1279 case Type.BT_OBJECT: return MOVE_PARAM_OBJECT; 1280 } 1281 1282 return throwBadType(type); 1283 } 1284 1285 /** 1286 * Returns the appropriate {@code move-exception} rop for the 1287 * given type. The result may be a shared instance. 1288 * 1289 * @param type {@code non-null;} type of the exception 1290 * @return {@code non-null;} an appropriate instance 1291 */ opMoveException(TypeBearer type)1292 public static Rop opMoveException(TypeBearer type) { 1293 return new Rop(RegOps.MOVE_EXCEPTION, type.getType(), 1294 StdTypeList.EMPTY, (String) null); 1295 } 1296 1297 /** 1298 * Returns the appropriate {@code move-result} rop for the 1299 * given type. The result may be a shared instance. 1300 * 1301 * @param type {@code non-null;} type of the parameter 1302 * @return {@code non-null;} an appropriate instance 1303 */ opMoveResult(TypeBearer type)1304 public static Rop opMoveResult(TypeBearer type) { 1305 return new Rop(RegOps.MOVE_RESULT, type.getType(), 1306 StdTypeList.EMPTY, (String) null); 1307 } 1308 1309 /** 1310 * Returns the appropriate {@code move-result-pseudo} rop for the 1311 * given type. The result may be a shared instance. 1312 * 1313 * @param type {@code non-null;} type of the parameter 1314 * @return {@code non-null;} an appropriate instance 1315 */ opMoveResultPseudo(TypeBearer type)1316 public static Rop opMoveResultPseudo(TypeBearer type) { 1317 return new Rop(RegOps.MOVE_RESULT_PSEUDO, type.getType(), 1318 StdTypeList.EMPTY, (String) null); 1319 } 1320 1321 /** 1322 * Returns the appropriate {@code const} rop for the given 1323 * type. The result is a shared instance. 1324 * 1325 * @param type {@code non-null;} type of the constant 1326 * @return {@code non-null;} an appropriate instance 1327 */ opConst(TypeBearer type)1328 public static Rop opConst(TypeBearer type) { 1329 if (type.getType() == Type.KNOWN_NULL) { 1330 return CONST_OBJECT_NOTHROW; 1331 } 1332 1333 switch (type.getBasicFrameType()) { 1334 case Type.BT_INT: return CONST_INT; 1335 case Type.BT_LONG: return CONST_LONG; 1336 case Type.BT_FLOAT: return CONST_FLOAT; 1337 case Type.BT_DOUBLE: return CONST_DOUBLE; 1338 case Type.BT_OBJECT: return CONST_OBJECT; 1339 } 1340 1341 return throwBadType(type); 1342 } 1343 1344 /** 1345 * Returns the appropriate {@code if-eq} rop for the given 1346 * sources. The result is a shared instance. 1347 * 1348 * @param types {@code non-null;} source types 1349 * @return {@code non-null;} an appropriate instance 1350 */ opIfEq(TypeList types)1351 public static Rop opIfEq(TypeList types) { 1352 return pickIf(types, IF_EQZ_INT, IF_EQZ_OBJECT, 1353 IF_EQ_INT, IF_EQ_OBJECT); 1354 } 1355 1356 /** 1357 * Returns the appropriate {@code if-ne} rop for the given 1358 * sources. The result is a shared instance. 1359 * 1360 * @param types {@code non-null;} source types 1361 * @return {@code non-null;} an appropriate instance 1362 */ opIfNe(TypeList types)1363 public static Rop opIfNe(TypeList types) { 1364 return pickIf(types, IF_NEZ_INT, IF_NEZ_OBJECT, 1365 IF_NE_INT, IF_NE_OBJECT); 1366 } 1367 1368 /** 1369 * Returns the appropriate {@code if-lt} rop for the given 1370 * sources. The result is a shared instance. 1371 * 1372 * @param types {@code non-null;} source types 1373 * @return {@code non-null;} an appropriate instance 1374 */ opIfLt(TypeList types)1375 public static Rop opIfLt(TypeList types) { 1376 return pickIf(types, IF_LTZ_INT, null, IF_LT_INT, null); 1377 } 1378 1379 /** 1380 * Returns the appropriate {@code if-ge} rop for the given 1381 * sources. The result is a shared instance. 1382 * 1383 * @param types {@code non-null;} source types 1384 * @return {@code non-null;} an appropriate instance 1385 */ opIfGe(TypeList types)1386 public static Rop opIfGe(TypeList types) { 1387 return pickIf(types, IF_GEZ_INT, null, IF_GE_INT, null); 1388 } 1389 1390 /** 1391 * Returns the appropriate {@code if-gt} rop for the given 1392 * sources. The result is a shared instance. 1393 * 1394 * @param types {@code non-null;} source types 1395 * @return {@code non-null;} an appropriate instance 1396 */ opIfGt(TypeList types)1397 public static Rop opIfGt(TypeList types) { 1398 return pickIf(types, IF_GTZ_INT, null, IF_GT_INT, null); 1399 } 1400 1401 /** 1402 * Returns the appropriate {@code if-le} rop for the given 1403 * sources. The result is a shared instance. 1404 * 1405 * @param types {@code non-null;} source types 1406 * @return {@code non-null;} an appropriate instance 1407 */ opIfLe(TypeList types)1408 public static Rop opIfLe(TypeList types) { 1409 return pickIf(types, IF_LEZ_INT, null, IF_LE_INT, null); 1410 } 1411 1412 /** 1413 * Helper for all the {@code if*}-related methods, which 1414 * checks types and picks one of the four variants, throwing if 1415 * there's a problem. 1416 * 1417 * @param types {@code non-null;} the types 1418 * @param intZ {@code non-null;} the int-to-0 comparison 1419 * @param objZ {@code null-ok;} the object-to-null comparison 1420 * @param intInt {@code non-null;} the int-to-int comparison 1421 * @param objObj {@code non-null;} the object-to-object comparison 1422 * @return {@code non-null;} the appropriate instance 1423 */ pickIf(TypeList types, Rop intZ, Rop objZ, Rop intInt, Rop objObj)1424 private static Rop pickIf(TypeList types, Rop intZ, Rop objZ, Rop intInt, 1425 Rop objObj) { 1426 switch(types.size()) { 1427 case 1: { 1428 switch (types.getType(0).getBasicFrameType()) { 1429 case Type.BT_INT: { 1430 return intZ; 1431 } 1432 case Type.BT_OBJECT: { 1433 if (objZ != null) { 1434 return objZ; 1435 } 1436 } 1437 } 1438 break; 1439 } 1440 case 2: { 1441 int bt = types.getType(0).getBasicFrameType(); 1442 if (bt == types.getType(1).getBasicFrameType()) { 1443 switch (bt) { 1444 case Type.BT_INT: { 1445 return intInt; 1446 } 1447 case Type.BT_OBJECT: { 1448 if (objObj != null) { 1449 return objObj; 1450 } 1451 } 1452 } 1453 } 1454 break; 1455 } 1456 } 1457 1458 return throwBadTypes(types); 1459 } 1460 1461 /** 1462 * Returns the appropriate {@code add} rop for the given 1463 * types. The result is a shared instance. 1464 * 1465 * @param types {@code non-null;} types of the sources 1466 * @return {@code non-null;} an appropriate instance 1467 */ opAdd(TypeList types)1468 public static Rop opAdd(TypeList types) { 1469 return pickBinaryOp(types, ADD_CONST_INT, ADD_CONST_LONG, 1470 ADD_CONST_FLOAT, ADD_CONST_DOUBLE, ADD_INT, 1471 ADD_LONG, ADD_FLOAT, ADD_DOUBLE); 1472 } 1473 1474 /** 1475 * Returns the appropriate {@code sub} rop for the given 1476 * types. The result is a shared instance. 1477 * 1478 * @param types {@code non-null;} types of the sources 1479 * @return {@code non-null;} an appropriate instance 1480 */ opSub(TypeList types)1481 public static Rop opSub(TypeList types) { 1482 return pickBinaryOp(types, SUB_CONST_INT, SUB_CONST_LONG, 1483 SUB_CONST_FLOAT, SUB_CONST_DOUBLE, SUB_INT, 1484 SUB_LONG, SUB_FLOAT, SUB_DOUBLE); 1485 } 1486 1487 /** 1488 * Returns the appropriate {@code mul} rop for the given 1489 * types. The result is a shared instance. 1490 * 1491 * @param types {@code non-null;} types of the sources 1492 * @return {@code non-null;} an appropriate instance 1493 */ opMul(TypeList types)1494 public static Rop opMul(TypeList types) { 1495 return pickBinaryOp(types, MUL_CONST_INT, MUL_CONST_LONG, 1496 MUL_CONST_FLOAT, MUL_CONST_DOUBLE, MUL_INT, 1497 MUL_LONG, MUL_FLOAT, MUL_DOUBLE); 1498 } 1499 1500 /** 1501 * Returns the appropriate {@code div} rop for the given 1502 * types. The result is a shared instance. 1503 * 1504 * @param types {@code non-null;} types of the sources 1505 * @return {@code non-null;} an appropriate instance 1506 */ opDiv(TypeList types)1507 public static Rop opDiv(TypeList types) { 1508 return pickBinaryOp(types, DIV_CONST_INT, DIV_CONST_LONG, 1509 DIV_CONST_FLOAT, DIV_CONST_DOUBLE, DIV_INT, 1510 DIV_LONG, DIV_FLOAT, DIV_DOUBLE); 1511 } 1512 1513 /** 1514 * Returns the appropriate {@code rem} rop for the given 1515 * types. The result is a shared instance. 1516 * 1517 * @param types {@code non-null;} types of the sources 1518 * @return {@code non-null;} an appropriate instance 1519 */ opRem(TypeList types)1520 public static Rop opRem(TypeList types) { 1521 return pickBinaryOp(types, REM_CONST_INT, REM_CONST_LONG, 1522 REM_CONST_FLOAT, REM_CONST_DOUBLE, REM_INT, 1523 REM_LONG, REM_FLOAT, REM_DOUBLE); 1524 } 1525 1526 /** 1527 * Returns the appropriate {@code and} rop for the given 1528 * types. The result is a shared instance. 1529 * 1530 * @param types {@code non-null;} types of the sources 1531 * @return {@code non-null;} an appropriate instance 1532 */ opAnd(TypeList types)1533 public static Rop opAnd(TypeList types) { 1534 return pickBinaryOp(types, AND_CONST_INT, AND_CONST_LONG, null, null, 1535 AND_INT, AND_LONG, null, null); 1536 } 1537 1538 /** 1539 * Returns the appropriate {@code or} rop for the given 1540 * types. The result is a shared instance. 1541 * 1542 * @param types {@code non-null;} types of the sources 1543 * @return {@code non-null;} an appropriate instance 1544 */ opOr(TypeList types)1545 public static Rop opOr(TypeList types) { 1546 return pickBinaryOp(types, OR_CONST_INT, OR_CONST_LONG, null, null, 1547 OR_INT, OR_LONG, null, null); 1548 } 1549 1550 /** 1551 * Returns the appropriate {@code xor} rop for the given 1552 * types. The result is a shared instance. 1553 * 1554 * @param types {@code non-null;} types of the sources 1555 * @return {@code non-null;} an appropriate instance 1556 */ opXor(TypeList types)1557 public static Rop opXor(TypeList types) { 1558 return pickBinaryOp(types, XOR_CONST_INT, XOR_CONST_LONG, null, null, 1559 XOR_INT, XOR_LONG, null, null); 1560 } 1561 1562 /** 1563 * Returns the appropriate {@code shl} rop for the given 1564 * types. The result is a shared instance. 1565 * 1566 * @param types {@code non-null;} types of the sources 1567 * @return {@code non-null;} an appropriate instance 1568 */ opShl(TypeList types)1569 public static Rop opShl(TypeList types) { 1570 return pickBinaryOp(types, SHL_CONST_INT, SHL_CONST_LONG, null, null, 1571 SHL_INT, SHL_LONG, null, null); 1572 } 1573 1574 /** 1575 * Returns the appropriate {@code shr} rop for the given 1576 * types. The result is a shared instance. 1577 * 1578 * @param types {@code non-null;} types of the sources 1579 * @return {@code non-null;} an appropriate instance 1580 */ opShr(TypeList types)1581 public static Rop opShr(TypeList types) { 1582 return pickBinaryOp(types, SHR_CONST_INT, SHR_CONST_LONG, null, null, 1583 SHR_INT, SHR_LONG, null, null); 1584 } 1585 1586 /** 1587 * Returns the appropriate {@code ushr} rop for the given 1588 * types. The result is a shared instance. 1589 * 1590 * @param types {@code non-null;} types of the sources 1591 * @return {@code non-null;} an appropriate instance 1592 */ opUshr(TypeList types)1593 public static Rop opUshr(TypeList types) { 1594 return pickBinaryOp(types, USHR_CONST_INT, USHR_CONST_LONG, null, null, 1595 USHR_INT, USHR_LONG, null, null); 1596 } 1597 1598 /** 1599 * Returns the appropriate binary arithmetic rop for the given type 1600 * and arguments. The result is a shared instance. 1601 * 1602 * @param types {@code non-null;} sources of the operation 1603 * @param int1 {@code non-null;} the int-to-constant rop 1604 * @param long1 {@code non-null;} the long-to-constant rop 1605 * @param float1 {@code null-ok;} the float-to-constant rop, if any 1606 * @param double1 {@code null-ok;} the double-to-constant rop, if any 1607 * @param int2 {@code non-null;} the int-to-int rop 1608 * @param long2 {@code non-null;} the long-to-long or long-to-int rop 1609 * @param float2 {@code null-ok;} the float-to-float rop, if any 1610 * @param double2 {@code null-ok;} the double-to-double rop, if any 1611 * @return {@code non-null;} an appropriate instance 1612 */ pickBinaryOp(TypeList types, Rop int1, Rop long1, Rop float1, Rop double1, Rop int2, Rop long2, Rop float2, Rop double2)1613 private static Rop pickBinaryOp(TypeList types, Rop int1, Rop long1, 1614 Rop float1, Rop double1, Rop int2, 1615 Rop long2, Rop float2, Rop double2) { 1616 int bt1 = types.getType(0).getBasicFrameType(); 1617 Rop result = null; 1618 1619 switch (types.size()) { 1620 case 1: { 1621 switch(bt1) { 1622 case Type.BT_INT: return int1; 1623 case Type.BT_LONG: return long1; 1624 case Type.BT_FLOAT: result = float1; break; 1625 case Type.BT_DOUBLE: result = double1; break; 1626 } 1627 break; 1628 } 1629 case 2: { 1630 switch(bt1) { 1631 case Type.BT_INT: return int2; 1632 case Type.BT_LONG: return long2; 1633 case Type.BT_FLOAT: result = float2; break; 1634 case Type.BT_DOUBLE: result = double2; break; 1635 } 1636 break; 1637 } 1638 } 1639 1640 if (result == null) { 1641 return throwBadTypes(types); 1642 } 1643 1644 return result; 1645 } 1646 1647 /** 1648 * Returns the appropriate {@code neg} rop for the given type. The 1649 * result is a shared instance. 1650 * 1651 * @param type {@code non-null;} type of value being operated on 1652 * @return {@code non-null;} an appropriate instance 1653 */ opNeg(TypeBearer type)1654 public static Rop opNeg(TypeBearer type) { 1655 switch (type.getBasicFrameType()) { 1656 case Type.BT_INT: return NEG_INT; 1657 case Type.BT_LONG: return NEG_LONG; 1658 case Type.BT_FLOAT: return NEG_FLOAT; 1659 case Type.BT_DOUBLE: return NEG_DOUBLE; 1660 } 1661 1662 return throwBadType(type); 1663 } 1664 1665 /** 1666 * Returns the appropriate {@code not} rop for the given type. The 1667 * result is a shared instance. 1668 * 1669 * @param type {@code non-null;} type of value being operated on 1670 * @return {@code non-null;} an appropriate instance 1671 */ opNot(TypeBearer type)1672 public static Rop opNot(TypeBearer type) { 1673 switch (type.getBasicFrameType()) { 1674 case Type.BT_INT: return NOT_INT; 1675 case Type.BT_LONG: return NOT_LONG; 1676 } 1677 1678 return throwBadType(type); 1679 } 1680 1681 /** 1682 * Returns the appropriate {@code cmpl} rop for the given type. The 1683 * result is a shared instance. 1684 * 1685 * @param type {@code non-null;} type of value being compared 1686 * @return {@code non-null;} an appropriate instance 1687 */ opCmpl(TypeBearer type)1688 public static Rop opCmpl(TypeBearer type) { 1689 switch (type.getBasicType()) { 1690 case Type.BT_LONG: return CMPL_LONG; 1691 case Type.BT_FLOAT: return CMPL_FLOAT; 1692 case Type.BT_DOUBLE: return CMPL_DOUBLE; 1693 } 1694 1695 return throwBadType(type); 1696 } 1697 1698 /** 1699 * Returns the appropriate {@code cmpg} rop for the given type. The 1700 * result is a shared instance. 1701 * 1702 * @param type {@code non-null;} type of value being compared 1703 * @return {@code non-null;} an appropriate instance 1704 */ opCmpg(TypeBearer type)1705 public static Rop opCmpg(TypeBearer type) { 1706 switch (type.getBasicType()) { 1707 case Type.BT_FLOAT: return CMPG_FLOAT; 1708 case Type.BT_DOUBLE: return CMPG_DOUBLE; 1709 } 1710 1711 return throwBadType(type); 1712 } 1713 1714 /** 1715 * Returns the appropriate {@code conv} rop for the given types. The 1716 * result is a shared instance. 1717 * 1718 * @param dest {@code non-null;} target value type 1719 * @param source {@code non-null;} source value type 1720 * @return {@code non-null;} an appropriate instance 1721 */ opConv(TypeBearer dest, TypeBearer source)1722 public static Rop opConv(TypeBearer dest, TypeBearer source) { 1723 int dbt = dest.getBasicFrameType(); 1724 switch (source.getBasicFrameType()) { 1725 case Type.BT_INT: { 1726 switch (dbt) { 1727 case Type.BT_LONG: return CONV_I2L; 1728 case Type.BT_FLOAT: return CONV_I2F; 1729 case Type.BT_DOUBLE: return CONV_I2D; 1730 default: break; 1731 } 1732 } 1733 case Type.BT_LONG: { 1734 switch (dbt) { 1735 case Type.BT_INT: return CONV_L2I; 1736 case Type.BT_FLOAT: return CONV_L2F; 1737 case Type.BT_DOUBLE: return CONV_L2D; 1738 default: break; 1739 } 1740 } 1741 case Type.BT_FLOAT: { 1742 switch (dbt) { 1743 case Type.BT_INT: return CONV_F2I; 1744 case Type.BT_LONG: return CONV_F2L; 1745 case Type.BT_DOUBLE: return CONV_F2D; 1746 default: break; 1747 } 1748 } 1749 case Type.BT_DOUBLE: { 1750 switch (dbt) { 1751 case Type.BT_INT: return CONV_D2I; 1752 case Type.BT_LONG: return CONV_D2L; 1753 case Type.BT_FLOAT: return CONV_D2F; 1754 default: break; 1755 } 1756 } 1757 } 1758 1759 return throwBadTypes(StdTypeList.make(dest.getType(), 1760 source.getType())); 1761 } 1762 1763 /** 1764 * Returns the appropriate {@code return} rop for the given type. The 1765 * result is a shared instance. 1766 * 1767 * @param type {@code non-null;} type of value being returned 1768 * @return {@code non-null;} an appropriate instance 1769 */ opReturn(TypeBearer type)1770 public static Rop opReturn(TypeBearer type) { 1771 switch (type.getBasicFrameType()) { 1772 case Type.BT_INT: return RETURN_INT; 1773 case Type.BT_LONG: return RETURN_LONG; 1774 case Type.BT_FLOAT: return RETURN_FLOAT; 1775 case Type.BT_DOUBLE: return RETURN_DOUBLE; 1776 case Type.BT_OBJECT: return RETURN_OBJECT; 1777 case Type.BT_VOID: return RETURN_VOID; 1778 } 1779 1780 return throwBadType(type); 1781 } 1782 1783 /** 1784 * Returns the appropriate {@code aget} rop for the given type. The 1785 * result is a shared instance. 1786 * 1787 * @param type {@code non-null;} element type of array being accessed 1788 * @return {@code non-null;} an appropriate instance 1789 */ opAget(TypeBearer type)1790 public static Rop opAget(TypeBearer type) { 1791 switch (type.getBasicType()) { 1792 case Type.BT_INT: return AGET_INT; 1793 case Type.BT_LONG: return AGET_LONG; 1794 case Type.BT_FLOAT: return AGET_FLOAT; 1795 case Type.BT_DOUBLE: return AGET_DOUBLE; 1796 case Type.BT_OBJECT: return AGET_OBJECT; 1797 case Type.BT_BOOLEAN: return AGET_BOOLEAN; 1798 case Type.BT_BYTE: return AGET_BYTE; 1799 case Type.BT_CHAR: return AGET_CHAR; 1800 case Type.BT_SHORT: return AGET_SHORT; 1801 } 1802 1803 return throwBadType(type); 1804 } 1805 1806 /** 1807 * Returns the appropriate {@code aput} rop for the given type. The 1808 * result is a shared instance. 1809 * 1810 * @param type {@code non-null;} element type of array being accessed 1811 * @return {@code non-null;} an appropriate instance 1812 */ opAput(TypeBearer type)1813 public static Rop opAput(TypeBearer type) { 1814 switch (type.getBasicType()) { 1815 case Type.BT_INT: return APUT_INT; 1816 case Type.BT_LONG: return APUT_LONG; 1817 case Type.BT_FLOAT: return APUT_FLOAT; 1818 case Type.BT_DOUBLE: return APUT_DOUBLE; 1819 case Type.BT_OBJECT: return APUT_OBJECT; 1820 case Type.BT_BOOLEAN: return APUT_BOOLEAN; 1821 case Type.BT_BYTE: return APUT_BYTE; 1822 case Type.BT_CHAR: return APUT_CHAR; 1823 case Type.BT_SHORT: return APUT_SHORT; 1824 } 1825 1826 return throwBadType(type); 1827 } 1828 1829 /** 1830 * Returns the appropriate {@code new-array} rop for the given 1831 * type. The result is a shared instance. 1832 * 1833 * @param arrayType {@code non-null;} array type of array being created 1834 * @return {@code non-null;} an appropriate instance 1835 */ opNewArray(TypeBearer arrayType)1836 public static Rop opNewArray(TypeBearer arrayType) { 1837 Type type = arrayType.getType(); 1838 Type elementType = type.getComponentType(); 1839 1840 switch (elementType.getBasicType()) { 1841 case Type.BT_INT: return NEW_ARRAY_INT; 1842 case Type.BT_LONG: return NEW_ARRAY_LONG; 1843 case Type.BT_FLOAT: return NEW_ARRAY_FLOAT; 1844 case Type.BT_DOUBLE: return NEW_ARRAY_DOUBLE; 1845 case Type.BT_BOOLEAN: return NEW_ARRAY_BOOLEAN; 1846 case Type.BT_BYTE: return NEW_ARRAY_BYTE; 1847 case Type.BT_CHAR: return NEW_ARRAY_CHAR; 1848 case Type.BT_SHORT: return NEW_ARRAY_SHORT; 1849 case Type.BT_OBJECT: { 1850 return new Rop(RegOps.NEW_ARRAY, type, StdTypeList.INT, 1851 Exceptions.LIST_Error_NegativeArraySizeException, 1852 "new-array-object"); 1853 } 1854 } 1855 1856 return throwBadType(type); 1857 } 1858 1859 /** 1860 * Returns the appropriate {@code filled-new-array} rop for the given 1861 * type. The result may be a shared instance. 1862 * 1863 * @param arrayType {@code non-null;} type of array being created 1864 * @param count {@code count >= 0;} number of elements that the array should have 1865 * @return {@code non-null;} an appropriate instance 1866 */ opFilledNewArray(TypeBearer arrayType, int count)1867 public static Rop opFilledNewArray(TypeBearer arrayType, int count) { 1868 Type type = arrayType.getType(); 1869 Type elementType = type.getComponentType(); 1870 1871 if (elementType.isCategory2()) { 1872 return throwBadType(arrayType); 1873 } 1874 1875 if (count < 0) { 1876 throw new IllegalArgumentException("count < 0"); 1877 } 1878 1879 StdTypeList sourceTypes = new StdTypeList(count); 1880 1881 for (int i = 0; i < count; i++) { 1882 sourceTypes.set(i, elementType); 1883 } 1884 1885 // Note: The resulting rop is considered call-like. 1886 return new Rop(RegOps.FILLED_NEW_ARRAY, 1887 sourceTypes, 1888 Exceptions.LIST_Error); 1889 } 1890 1891 /** 1892 * Returns the appropriate {@code get-field} rop for the given 1893 * type. The result is a shared instance. 1894 * 1895 * @param type {@code non-null;} type of the field in question 1896 * @return {@code non-null;} an appropriate instance 1897 */ opGetField(TypeBearer type)1898 public static Rop opGetField(TypeBearer type) { 1899 switch (type.getBasicType()) { 1900 case Type.BT_INT: return GET_FIELD_INT; 1901 case Type.BT_LONG: return GET_FIELD_LONG; 1902 case Type.BT_FLOAT: return GET_FIELD_FLOAT; 1903 case Type.BT_DOUBLE: return GET_FIELD_DOUBLE; 1904 case Type.BT_OBJECT: return GET_FIELD_OBJECT; 1905 case Type.BT_BOOLEAN: return GET_FIELD_BOOLEAN; 1906 case Type.BT_BYTE: return GET_FIELD_BYTE; 1907 case Type.BT_CHAR: return GET_FIELD_CHAR; 1908 case Type.BT_SHORT: return GET_FIELD_SHORT; 1909 } 1910 1911 return throwBadType(type); 1912 } 1913 1914 /** 1915 * Returns the appropriate {@code put-field} rop for the given 1916 * type. The result is a shared instance. 1917 * 1918 * @param type {@code non-null;} type of the field in question 1919 * @return {@code non-null;} an appropriate instance 1920 */ opPutField(TypeBearer type)1921 public static Rop opPutField(TypeBearer type) { 1922 switch (type.getBasicType()) { 1923 case Type.BT_INT: return PUT_FIELD_INT; 1924 case Type.BT_LONG: return PUT_FIELD_LONG; 1925 case Type.BT_FLOAT: return PUT_FIELD_FLOAT; 1926 case Type.BT_DOUBLE: return PUT_FIELD_DOUBLE; 1927 case Type.BT_OBJECT: return PUT_FIELD_OBJECT; 1928 case Type.BT_BOOLEAN: return PUT_FIELD_BOOLEAN; 1929 case Type.BT_BYTE: return PUT_FIELD_BYTE; 1930 case Type.BT_CHAR: return PUT_FIELD_CHAR; 1931 case Type.BT_SHORT: return PUT_FIELD_SHORT; 1932 } 1933 1934 return throwBadType(type); 1935 } 1936 1937 /** 1938 * Returns the appropriate {@code get-static} rop for the given 1939 * type. The result is a shared instance. 1940 * 1941 * @param type {@code non-null;} type of the field in question 1942 * @return {@code non-null;} an appropriate instance 1943 */ opGetStatic(TypeBearer type)1944 public static Rop opGetStatic(TypeBearer type) { 1945 switch (type.getBasicType()) { 1946 case Type.BT_INT: return GET_STATIC_INT; 1947 case Type.BT_LONG: return GET_STATIC_LONG; 1948 case Type.BT_FLOAT: return GET_STATIC_FLOAT; 1949 case Type.BT_DOUBLE: return GET_STATIC_DOUBLE; 1950 case Type.BT_OBJECT: return GET_STATIC_OBJECT; 1951 case Type.BT_BOOLEAN: return GET_STATIC_BOOLEAN; 1952 case Type.BT_BYTE: return GET_STATIC_BYTE; 1953 case Type.BT_CHAR: return GET_STATIC_CHAR; 1954 case Type.BT_SHORT: return GET_STATIC_SHORT; 1955 } 1956 1957 return throwBadType(type); 1958 } 1959 1960 /** 1961 * Returns the appropriate {@code put-static} rop for the given 1962 * type. The result is a shared instance. 1963 * 1964 * @param type {@code non-null;} type of the field in question 1965 * @return {@code non-null;} an appropriate instance 1966 */ opPutStatic(TypeBearer type)1967 public static Rop opPutStatic(TypeBearer type) { 1968 switch (type.getBasicType()) { 1969 case Type.BT_INT: return PUT_STATIC_INT; 1970 case Type.BT_LONG: return PUT_STATIC_LONG; 1971 case Type.BT_FLOAT: return PUT_STATIC_FLOAT; 1972 case Type.BT_DOUBLE: return PUT_STATIC_DOUBLE; 1973 case Type.BT_OBJECT: return PUT_STATIC_OBJECT; 1974 case Type.BT_BOOLEAN: return PUT_STATIC_BOOLEAN; 1975 case Type.BT_BYTE: return PUT_STATIC_BYTE; 1976 case Type.BT_CHAR: return PUT_STATIC_CHAR; 1977 case Type.BT_SHORT: return PUT_STATIC_SHORT; 1978 } 1979 1980 return throwBadType(type); 1981 } 1982 1983 /** 1984 * Returns the appropriate {@code invoke-static} rop for the 1985 * given type. The result is typically a newly-allocated instance. 1986 * 1987 * @param meth {@code non-null;} descriptor of the method 1988 * @return {@code non-null;} an appropriate instance 1989 */ opInvokeStatic(Prototype meth)1990 public static Rop opInvokeStatic(Prototype meth) { 1991 return new Rop(RegOps.INVOKE_STATIC, 1992 meth.getParameterFrameTypes(), 1993 StdTypeList.THROWABLE); 1994 } 1995 1996 /** 1997 * Returns the appropriate {@code invoke-virtual} rop for the 1998 * given type. The result is typically a newly-allocated instance. 1999 * 2000 * @param meth {@code non-null;} descriptor of the method, including the 2001 * {@code this} parameter 2002 * @return {@code non-null;} an appropriate instance 2003 */ opInvokeVirtual(Prototype meth)2004 public static Rop opInvokeVirtual(Prototype meth) { 2005 return new Rop(RegOps.INVOKE_VIRTUAL, 2006 meth.getParameterFrameTypes(), 2007 StdTypeList.THROWABLE); 2008 } 2009 2010 /** 2011 * Returns the appropriate {@code invoke-super} rop for the 2012 * given type. The result is typically a newly-allocated instance. 2013 * 2014 * @param meth {@code non-null;} descriptor of the method, including the 2015 * {@code this} parameter 2016 * @return {@code non-null;} an appropriate instance 2017 */ opInvokeSuper(Prototype meth)2018 public static Rop opInvokeSuper(Prototype meth) { 2019 return new Rop(RegOps.INVOKE_SUPER, 2020 meth.getParameterFrameTypes(), 2021 StdTypeList.THROWABLE); 2022 } 2023 2024 /** 2025 * Returns the appropriate {@code invoke-direct} rop for the 2026 * given type. The result is typically a newly-allocated instance. 2027 * 2028 * @param meth {@code non-null;} descriptor of the method, including the 2029 * {@code this} parameter 2030 * @return {@code non-null;} an appropriate instance 2031 */ opInvokeDirect(Prototype meth)2032 public static Rop opInvokeDirect(Prototype meth) { 2033 return new Rop(RegOps.INVOKE_DIRECT, 2034 meth.getParameterFrameTypes(), 2035 StdTypeList.THROWABLE); 2036 } 2037 2038 /** 2039 * Returns the appropriate {@code invoke-interface} rop for the 2040 * given type. The result is typically a newly-allocated instance. 2041 * 2042 * @param meth {@code non-null;} descriptor of the method, including the 2043 * {@code this} parameter 2044 * @return {@code non-null;} an appropriate instance 2045 */ opInvokeInterface(Prototype meth)2046 public static Rop opInvokeInterface(Prototype meth) { 2047 return new Rop(RegOps.INVOKE_INTERFACE, 2048 meth.getParameterFrameTypes(), 2049 StdTypeList.THROWABLE); 2050 } 2051 2052 /** 2053 * Returns the appropriate {@code invoke-polymorphic} rop for the 2054 * given type. The result is typically a newly-allocated instance. 2055 * 2056 * @param meth {@code non-null;} descriptor of the method, including the 2057 * {@code this} parameter 2058 * @return {@code non-null;} an appropriate instance 2059 */ opInvokePolymorphic(Prototype meth)2060 public static Rop opInvokePolymorphic(Prototype meth) { 2061 return new Rop(RegOps.INVOKE_POLYMORPHIC, 2062 meth.getParameterFrameTypes(), 2063 StdTypeList.THROWABLE); 2064 } 2065 2066 /** 2067 * Returns the appropriate {@code mark-local} rop for the given type. 2068 * The result is a shared instance. 2069 * 2070 * @param type {@code non-null;} type of value being marked 2071 * @return {@code non-null;} an appropriate instance 2072 */ opMarkLocal(TypeBearer type)2073 public static Rop opMarkLocal(TypeBearer type) { 2074 switch (type.getBasicFrameType()) { 2075 case Type.BT_INT: return MARK_LOCAL_INT; 2076 case Type.BT_LONG: return MARK_LOCAL_LONG; 2077 case Type.BT_FLOAT: return MARK_LOCAL_FLOAT; 2078 case Type.BT_DOUBLE: return MARK_LOCAL_DOUBLE; 2079 case Type.BT_OBJECT: return MARK_LOCAL_OBJECT; 2080 } 2081 2082 return throwBadType(type); 2083 } 2084 2085 /** 2086 * This class is uninstantiable. 2087 */ Rops()2088 private Rops() { 2089 // This space intentionally left blank. 2090 } 2091 2092 /** 2093 * Throws the right exception to complain about a bogus type. 2094 * 2095 * @param type {@code non-null;} the bad type 2096 * @return never 2097 */ throwBadType(TypeBearer type)2098 private static Rop throwBadType(TypeBearer type) { 2099 throw new IllegalArgumentException("bad type: " + type); 2100 } 2101 2102 /** 2103 * Throws the right exception to complain about a bogus list of types. 2104 * 2105 * @param types {@code non-null;} the bad types 2106 * @return never 2107 */ throwBadTypes(TypeList types)2108 private static Rop throwBadTypes(TypeList types) { 2109 throw new IllegalArgumentException("bad types: " + types); 2110 } 2111 } 2112