private static Object tryEmulateOperation(UnOp.Op op, Object arg) { if (arg == null) { return null; } switch (op) { case UNM: { Number n = Conversions.arithmeticValueOf(arg); return n != null ? Dispatch.unm(n) : null; } case BNOT: { Long l = Conversions.integerValueOf(arg); return l != null ? LuaMathOperators.bnot(l) : null; } case NOT: return arg.equals(Boolean.FALSE); case LEN: if (arg instanceof String) return Dispatch.len((String) arg); else if (arg instanceof ByteString) return Long.valueOf(((ByteString) arg).length()); else return null; default: throw new IllegalArgumentException("Illegal operation: " + op); } }
private void fetchLen(ExecutionContext context, int state, ArgumentIterator args, Table t) throws ResolvedControlThrowable { long len = 0; try { switch (state) { case STATE_OFFSET_LEN: state = STATE_OFFSET_LEN + 1; Dispatch.len(context, t); case STATE_OFFSET_LEN + 1: len = getLength(context.getReturnBuffer()); break; default: throw new IllegalStateException("Illegal state: " + state); } } catch (UnresolvedControlThrowable ct) { throw ct.resolve(this, new SuspendedState(state, -1, args, t, null, 1, -1, -1, null, null, null)); } prepareLoop(context, args, t, len); }
private void _len(ExecutionContext context, int state, Table t, ArgumentIterator args) throws ResolvedControlThrowable { // __len is defined, must go through Dispatch final long len; try { switch (state) { case _LEN_PREPARE: state = _LEN_RESUME; Dispatch.len(context, t); case _LEN_RESUME: { len = getLength(context.getReturnBuffer()); break; } default: throw new IllegalStateException("Illegal state: " + state); } } catch (UnresolvedControlThrowable ct) { throw ct.resolve(this, new SuspendedState(state, t, args, 0, 0, null)); } // next: process the arguments run_args(context, t, args, len); }
private void _len(ExecutionContext context, int state, Table t, ArgumentIterator args) throws ResolvedControlThrowable { // __len is defined, must go through Dispatch final long len; try { switch (state) { case _LEN_PREPARE: state = _LEN_RESUME; Dispatch.len(context, t); case _LEN_RESUME: { len = getLength(context.getReturnBuffer()); break; } default: throw new IllegalStateException("Illegal state: " + state); } } catch (UnresolvedControlThrowable ct) { throw ct.resolve(this, new SuspendedState(state, t, args, 0, 0, null)); } // next: process the arguments run_args(context, t, args, len); }
@Override protected void invoke(ExecutionContext context, ArgumentIterator args) throws ResolvedControlThrowable { final long result; // no need to distinguish missing value vs nil Object arg1 = args.nextOptionalAny(null); if (arg1 instanceof Table) { Table table = (Table) arg1; result = table.rawlen(); } else if (arg1 instanceof ByteString) { ByteString s = (ByteString) arg1; result = (long) s.length(); } else if (arg1 instanceof String) { String s = (String) arg1; result = Dispatch.len(s); } else { throw new BadArgumentException(1, name(), "table or string expected"); } context.getReturnBuffer().setTo(result); }
Dispatch.len(context, obj); // may suspend, will pass #obj through the stack
context.getReturnBuffer().setTo(len((String) o));
Dispatch.len(context, t); // may suspend, will pass #obj through the stack