# [SERVER] LambdaMOO 1.8.x feature wishlist

Christopher Unkel (cunkel@us.itd.umich.edu)
Mon, 11 Nov 1996 13:55:12 PST

- Messages sorted by:[ date ][ thread ][ subject ][ author ]

    On Mon, 11 Nov 1996, Michael Brundage wrote:

    >      Limit string and list lengths to prevent malicious programmers
    >      (or unfortunate accidents) from bringing down any MOO currently in
    >      existence.

    The problem with this is that it essentially removes a layer of
    abstraction: now any piece of code that manipulates lists or strings
    suddenly needs to know how long it should let that list/string become,
    which probably depends on the permissions of the programmer, etc.

    Furthermore, it doesn't solve the problem.  A malicious programmer can
    simply create a whole slew of properties on some object.

    >    - differentiate between constant and mutable strings (String and
    >      StringBuffer in Java)

    I don't see how this can be accomplished in a weakly-typed language such a
    MOO; without declarations, how can we get to "constant" strings?

    >    - differentiate between property fetches and stores so that
    >      property values could be cached if known to not be altered during
    >      task execution. This would obviate the need for things like
    >        ou = $object_utils; for each in ([1..max_object()])
    >        player:tell(ou:ancestors(each)); endfor

    Hmm.  Not nearly as easy as you might think.  In particular, if you wrote:

    for x in [#1..max_object()]
      player:tell($object_utils:ancestors(each));
    endfor

    the compiler can't remove the read of #0.object utils -- because
    $object_utils:ancestors might have altered it.  In fact, if any verb
    executes (or any built-in unless you want to teach the compiler about
    every built-in, and, ick), the compiler can't remove the call, because it
    can't know until runtime what that code does.

    There are also other issues, like how does the decompiler get your
    original code back.

    Perhaps there are optimizations that could be made at the VM/DB interface
    that would make it faster, however.

    >    - provide a mechanism for just-in-time compilation into native
    >      object code.  I wouldn't expect this to be fully implemented for
    >      any given architecture, but it would allow motivated individuals
    >      an opportunity to add support for it without each such person
    >      rewriting it themselves.

    Yeah, this would be cool, presuming it was done in a way such that it
    resulted in very fast and RELIABLE code.  The problem is, it is anything
    but easy.  I wouldn't hold your breath... ;>

    > (3) Customizable exceptions/error handling.
    >
    >     Okay, this is a server/db interface issue, but it comes into play
    >     with the VM.  Currently, the server says, "such and such error
    >     results in such and such error value."  For example, read() raises
    >     E_INVARG when a "connection is closed while a task is waiting for
    >     input but before any lines of input are received").  Now
    >     that we can raise arbitrary values as exceptions, it is no longer
    >     necessary to have somewhat arcane mappings from these errors to the
    >     limited set of builtin error values.  Instead, use property values
    >     on $exception (or if you don't like creating a new server-assumed
    >     object, maybe use $server_options.exception_*) to describe the
    >     exceptions to be raised.  E.g., $exception.divide_by_zero
    >     To keep the overhead down, you could require these properties to
    >     always exist in the database, and then those who don't want to
    >     customize them could just leave them at their current default values.

    Hmm.  It seems to me that this would encourage people to use either
    numbers (which are even less descriptive than the error values) or strings
    as error conditions.  Strings seem attractive at first glance, but in
    reality would be a poor choice: they are less efficient than errors (which
    are stored as integers), harder to compare (strcmp() or == which does a
    case-insensitive strcmp), and prone to errors of wide variety:

    try
      if (b==0)
        raise("overflow");
      else
        c=a/b;
      endif
    except ("overfolw") /* notice the typo */
      "Do stuff.";
    endtry

    I also don't think that...

    try
      "Code that can raise a division by zero exception";
    except ($exceptions.divbyzero)
      "Handle overflow exception";
    endtry

    is really much of an improvement; instead of having to remember what error
    foo verb/built-in can raise, we have to remember what prop on $exception
    it raises.  Not so much better.

    ...which really leaves only errors to use in $exceptions.whatever--and if
    we're going to be raising errors as usual, we might as well do it without
    the extra overhead of property fetches and compares.

    Still, error codes aren't very descriptive sometimes -- they can cover a
    rather wide range of errors. Perhaps one way to handle this would be to
    use the VALUE slot of the error info available for extended error
    information (and the MESSAGE field as well).  For example,
    open_network_connection()  returns E_QUOTA if it can't open a connection
    for any reason other than permissions.  If it set the message and value
    slots to more informative things, an error handler could make use of them:

    For example:

    try
      connobj=open_network_connection(host, port);
    except info (E_QUOTA)
      value=info[3];
      if (value==$exceptions.open_network_connection_hostname_lookup_failure)
        "Yeah, I know, that's clumsy.";
        player:tell("The connection could not be opened because the computer",
          "named '", host, "' could not be found.  Perhaps you mistyped it?");
      elseif (value==$exceptions.open_network_connection_timeout)
        player:tell("The connection could not be opened because the computer",
          "could not be contacted.  The machine or network may be down.");
      else
        player:tell("An unknown error occured opening the connection.  The",
          message given was: ", info[2]);
      endif
    endtry

    I still think that getting the value from a property is clumsy, but it's
    clearer than using an arbitrary negative object number or something
    (although the prop may just hold that value assigned arbitrarily by the
    server.)

    There's undoubtedly room to disagree with me on some of this stuff.  Isn't
    there always?  :)

      --Chris                           cunkel@engin.umich.edu
        ResComp Network Support Technician, Bursley Hall
        "Invisibility is in the eye of the beholder."
        Home Page: http://www-personal.engin.umich.edu/~cunkel/