1 /*
2 * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
1205 code.resolve(c.trueJumps);
1206 genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET);
1207 code.resolve(loopEnv.info.cont);
1208 genStats(step, loopEnv);
1209 code.resolve(code.branch(goto_), startpc);
1210 code.resolve(loopDone);
1211 } else {
1212 genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET);
1213 code.resolve(loopEnv.info.cont);
1214 genStats(step, loopEnv);
1215 CondItem c;
1216 if (cond != null) {
1217 code.statBegin(cond.pos);
1218 c = genCond(TreeInfo.skipParens(cond), CRT_FLOW_CONTROLLER);
1219 } else {
1220 c = items.makeCondItem(goto_);
1221 }
1222 code.resolve(c.jumpTrue(), startpc);
1223 code.resolve(c.falseJumps);
1224 }
1225 code.resolve(loopEnv.info.exit);
1226 if (loopEnv.info.exit != null) {
1227 loopEnv.info.exit.state.defined.excludeFrom(code.nextreg);
1228 }
1229 }
1230
1231 public void visitForeachLoop(JCEnhancedForLoop tree) {
1232 throw new AssertionError(); // should have been removed by Lower.
1233 }
1234
1235 public void visitLabelled(JCLabeledStatement tree) {
1236 Env<GenContext> localEnv = env.dup(tree, new GenContext());
1237 genStat(tree.body, localEnv, CRT_STATEMENT);
1238 code.resolve(localEnv.info.exit);
1239 }
1240
1241 public void visitSwitch(JCSwitch tree) {
1242 int limit = code.nextreg;
1243 Assert.check(!tree.selector.type.hasTag(CLASS));
1244 int startpcCrt = genCrt ? code.curCP() : 0;
1245 Item sel = genExpr(tree.selector, syms.intType);
1246 List<JCCase> cases = tree.cases;
1247 if (cases.isEmpty()) {
1248 // We are seeing: switch <sel> {}
1249 sel.load().drop();
1250 if (genCrt)
1251 code.crt.put(TreeInfo.skipParens(tree.selector),
1252 CRT_FLOW_CONTROLLER, startpcCrt, code.curCP());
1253 } else {
1254 // We are seeing a nonempty switch.
1255 sel.load();
1256 if (genCrt)
1257 code.crt.put(TreeInfo.skipParens(tree.selector),
1258 CRT_FLOW_CONTROLLER, startpcCrt, code.curCP());
1327 int pc = code.entryPoint(stateSwitch);
1328 // Insert offset directly into code or else into the
1329 // offsets table.
1330 if (i != defaultIndex) {
1331 if (opcode == tableswitch) {
1332 code.put4(
1333 tableBase + 4 * (labels[i] - lo + 3),
1334 pc - startpc);
1335 } else {
1336 offsets[i] = pc - startpc;
1337 }
1338 } else {
1339 code.put4(tableBase, pc - startpc);
1340 }
1341
1342 // Generate code for the statements in this case.
1343 genStats(c.stats, switchEnv, CRT_FLOW_TARGET);
1344 }
1345
1346 // Resolve all breaks.
1347 code.resolve(switchEnv.info.exit);
1348
1349 // If we have not set the default offset, we do so now.
1350 if (code.get4(tableBase) == -1) {
1351 code.put4(tableBase, code.entryPoint(stateSwitch) - startpc);
1352 }
1353
1354 if (opcode == tableswitch) {
1355 // Let any unfilled slots point to the default case.
1356 int defaultOffset = code.get4(tableBase);
1357 for (long i = lo; i <= hi; i++) {
1358 int t = (int)(tableBase + 4 * (i - lo + 3));
1359 if (code.get4(t) == -1)
1360 code.put4(t, defaultOffset);
1361 }
1362 } else {
1363 // Sort non-default offsets and copy into lookup table.
1364 if (defaultIndex >= 0)
1365 for (int i = defaultIndex; i < labels.length - 1; i++) {
1366 labels[i] = labels[i+1];
1367 offsets[i] = offsets[i+1];
|
1 /*
2 * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
1205 code.resolve(c.trueJumps);
1206 genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET);
1207 code.resolve(loopEnv.info.cont);
1208 genStats(step, loopEnv);
1209 code.resolve(code.branch(goto_), startpc);
1210 code.resolve(loopDone);
1211 } else {
1212 genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET);
1213 code.resolve(loopEnv.info.cont);
1214 genStats(step, loopEnv);
1215 CondItem c;
1216 if (cond != null) {
1217 code.statBegin(cond.pos);
1218 c = genCond(TreeInfo.skipParens(cond), CRT_FLOW_CONTROLLER);
1219 } else {
1220 c = items.makeCondItem(goto_);
1221 }
1222 code.resolve(c.jumpTrue(), startpc);
1223 code.resolve(c.falseJumps);
1224 }
1225 Chain exit = loopEnv.info.exit;
1226 if (exit != null) {
1227 code.resolve(exit);
1228 exit.state.defined.excludeFrom(code.nextreg);
1229 }
1230 }
1231
1232 public void visitForeachLoop(JCEnhancedForLoop tree) {
1233 throw new AssertionError(); // should have been removed by Lower.
1234 }
1235
1236 public void visitLabelled(JCLabeledStatement tree) {
1237 Env<GenContext> localEnv = env.dup(tree, new GenContext());
1238 genStat(tree.body, localEnv, CRT_STATEMENT);
1239 Chain exit = localEnv.info.exit;
1240 if (exit != null) {
1241 code.resolve(exit);
1242 exit.state.defined.excludeFrom(code.nextreg);
1243 }
1244 }
1245
1246 public void visitSwitch(JCSwitch tree) {
1247 int limit = code.nextreg;
1248 Assert.check(!tree.selector.type.hasTag(CLASS));
1249 int startpcCrt = genCrt ? code.curCP() : 0;
1250 Item sel = genExpr(tree.selector, syms.intType);
1251 List<JCCase> cases = tree.cases;
1252 if (cases.isEmpty()) {
1253 // We are seeing: switch <sel> {}
1254 sel.load().drop();
1255 if (genCrt)
1256 code.crt.put(TreeInfo.skipParens(tree.selector),
1257 CRT_FLOW_CONTROLLER, startpcCrt, code.curCP());
1258 } else {
1259 // We are seeing a nonempty switch.
1260 sel.load();
1261 if (genCrt)
1262 code.crt.put(TreeInfo.skipParens(tree.selector),
1263 CRT_FLOW_CONTROLLER, startpcCrt, code.curCP());
1332 int pc = code.entryPoint(stateSwitch);
1333 // Insert offset directly into code or else into the
1334 // offsets table.
1335 if (i != defaultIndex) {
1336 if (opcode == tableswitch) {
1337 code.put4(
1338 tableBase + 4 * (labels[i] - lo + 3),
1339 pc - startpc);
1340 } else {
1341 offsets[i] = pc - startpc;
1342 }
1343 } else {
1344 code.put4(tableBase, pc - startpc);
1345 }
1346
1347 // Generate code for the statements in this case.
1348 genStats(c.stats, switchEnv, CRT_FLOW_TARGET);
1349 }
1350
1351 // Resolve all breaks.
1352 Chain exit = switchEnv.info.exit;
1353 if (exit != null) {
1354 code.resolve(exit);
1355 exit.state.defined.excludeFrom(code.nextreg);
1356 }
1357
1358 // If we have not set the default offset, we do so now.
1359 if (code.get4(tableBase) == -1) {
1360 code.put4(tableBase, code.entryPoint(stateSwitch) - startpc);
1361 }
1362
1363 if (opcode == tableswitch) {
1364 // Let any unfilled slots point to the default case.
1365 int defaultOffset = code.get4(tableBase);
1366 for (long i = lo; i <= hi; i++) {
1367 int t = (int)(tableBase + 4 * (i - lo + 3));
1368 if (code.get4(t) == -1)
1369 code.put4(t, defaultOffset);
1370 }
1371 } else {
1372 // Sort non-default offsets and copy into lookup table.
1373 if (defaultIndex >= 0)
1374 for (int i = defaultIndex; i < labels.length - 1; i++) {
1375 labels[i] = labels[i+1];
1376 offsets[i] = offsets[i+1];
|