360 final Block block = lc.getCurrentBlock();
361 final Symbol symbol = findSymbol(block, exception.getName());
362
363 catchNestingLevel--;
364
365 assert symbol != null;
366 return end(catchNode.setException((IdentNode)exception.setSymbol(lc, symbol)));
367 }
368
369 /**
370 * Declare the definition of a new symbol.
371 *
372 * @param name Name of symbol.
373 * @param symbolFlags Symbol flags.
374 *
375 * @return Symbol for given name or null for redefinition.
376 */
377 private Symbol defineSymbol(final Block block, final String name, final int symbolFlags) {
378 int flags = symbolFlags;
379 Symbol symbol = findSymbol(block, name); // Locate symbol.
380
381 if ((flags & KINDMASK) == IS_GLOBAL) {
382 flags |= IS_SCOPE;
383 }
384
385 final FunctionNode function = lc.getFunction(block);
386 if (symbol != null) {
387 // Symbol was already defined. Check if it needs to be redefined.
388 if ((flags & KINDMASK) == IS_PARAM) {
389 if (!isLocal(function, symbol)) {
390 // Not defined in this function. Create a new definition.
391 symbol = null;
392 } else if (symbol.isParam()) {
393 // Duplicate parameter. Null return will force an error.
394 assert false : "duplicate parameter";
395 return null;
396 }
397 } else if ((flags & KINDMASK) == IS_VAR) {
398 if ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET) {
399 // Always create a new definition.
400 symbol = null;
401 } else {
402 // Not defined in this function. Create a new definition.
403 if (!isLocal(function, symbol) || symbol.less(IS_VAR)) {
404 symbol = null;
405 }
406 }
407 }
408 }
409
410 if (symbol == null) {
411 // If not found, then create a new one.
412 Block symbolBlock;
413
414 // Determine where to create it.
415 if ((flags & Symbol.KINDMASK) == IS_VAR && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) {
416 symbolBlock = block; //internal vars are always defined in the block closest to them
417 } else {
418 symbolBlock = lc.getFunctionBody(function);
419 }
420
421 // Create and add to appropriate block.
422 symbol = new Symbol(name, flags);
423 symbolBlock.putSymbol(lc, symbol);
424
425 if ((flags & Symbol.KINDMASK) != IS_GLOBAL) {
426 symbol.setNeedsSlot(true);
427 }
428 } else if (symbol.less(flags)) {
429 symbol.setFlags(flags);
430 }
431
432 return symbol;
433 }
434
435 @Override
436 public boolean enterFunctionNode(final FunctionNode functionNode) {
|
360 final Block block = lc.getCurrentBlock();
361 final Symbol symbol = findSymbol(block, exception.getName());
362
363 catchNestingLevel--;
364
365 assert symbol != null;
366 return end(catchNode.setException((IdentNode)exception.setSymbol(lc, symbol)));
367 }
368
369 /**
370 * Declare the definition of a new symbol.
371 *
372 * @param name Name of symbol.
373 * @param symbolFlags Symbol flags.
374 *
375 * @return Symbol for given name or null for redefinition.
376 */
377 private Symbol defineSymbol(final Block block, final String name, final int symbolFlags) {
378 int flags = symbolFlags;
379 Symbol symbol = findSymbol(block, name); // Locate symbol.
380 boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL;
381
382 if (isGlobal) {
383 flags |= IS_SCOPE;
384 }
385
386 final FunctionNode function = lc.getFunction(block);
387 if (symbol != null) {
388 // Symbol was already defined. Check if it needs to be redefined.
389 if ((flags & KINDMASK) == IS_PARAM) {
390 if (!isLocal(function, symbol)) {
391 // Not defined in this function. Create a new definition.
392 symbol = null;
393 } else if (symbol.isParam()) {
394 // Duplicate parameter. Null return will force an error.
395 assert false : "duplicate parameter";
396 return null;
397 }
398 } else if ((flags & KINDMASK) == IS_VAR) {
399 if ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET) {
400 // Always create a new definition.
401 symbol = null;
402 } else {
403 // Not defined in this function. Create a new definition.
404 if (!isLocal(function, symbol) || symbol.less(IS_VAR)) {
405 symbol = null;
406 }
407 }
408 }
409 }
410
411 if (symbol == null) {
412 // If not found, then create a new one.
413 Block symbolBlock;
414
415 // Determine where to create it.
416 if ((flags & Symbol.KINDMASK) == IS_VAR && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) {
417 symbolBlock = block; //internal vars are always defined in the block closest to them
418 } else if (isGlobal) {
419 symbolBlock = lc.getOutermostFunction().getBody();
420 } else {
421 symbolBlock = lc.getFunctionBody(function);
422 }
423
424 // Create and add to appropriate block.
425 symbol = new Symbol(name, flags);
426 symbolBlock.putSymbol(lc, symbol);
427
428 if ((flags & Symbol.KINDMASK) != IS_GLOBAL) {
429 symbol.setNeedsSlot(true);
430 }
431 } else if (symbol.less(flags)) {
432 symbol.setFlags(flags);
433 }
434
435 return symbol;
436 }
437
438 @Override
439 public boolean enterFunctionNode(final FunctionNode functionNode) {
|