Re: Object spec [x-adr][x-bayes]

2003-03-10 Thread Christopher Armstrong
On Sun, Mar 09, 2003 at 03:46:39PM -0500, Dan Sugalski wrote:

 Presenting internal state in a rational form is a rather 
 significantly different thing than being able to serialize things, 
 and I don't think it's feasable, unfortunately. It'll require too 
 much consistency to be useful (as I don't think you'll get that 
 consistency) and you'll likely end up just dropping back and 
 grovelling over the internal nasty bits anyway.
 
 Serialization is a specific and very useful application, and one that 
 we need in general (otherwise we won't be able to have constant PMCs) 
 so it'll be there, but being able to expect to walk a pool of 
 heterogenous objects from a variety of different object systems is 
 more than I think you're likely to get.
 
 More to the point, it's a level of complexity I'm unwilling to commit 
 to, because it's not needed for our required functionality, useful 
 though it might be. (Even in the limited circumstances it's likely to 
 be available in)

Forgive me for jumping into the conversation late, but I'm not really
sure where this complexity is coming from. I've worked quite a bit
with serialization mechanisms in Python and other languages, but maybe
I'm missing something. In Python, we just have a method named
__getstate__ that must return one of the basic types: dict (hash),
list (vector), None, int, string. The marshaller must know how to
write these things to a file, send them across a socket via some
protocol, or whatever.  The dicts and lists can contain other objects,
of course, and those will be queried for their state, and so on. 

This isn't really that hard to implement, IME, and it's never been an
issue to put the state of an object into these datastructures. If a
method doesn't have a __getstate__, we just grab its attribute
__dict__. This bit is obviously not friendly to other languages, but
it's also unneccessary - Each language can implement a default
`get_state'-type method on its root object PMC that can either return
something useful or crash out (Python's would check for
self.__getstate__, and if not found, return self.__dict__).

Unserializing basically instantiates an object without initializing it
and calls __setstate__(data) on it where `data' is what was previously
returned from its __getstate__ call.

I'm not on a crusade to get a cross-language serialization mechanism,
but it would be very convenient and it doesn't seem it would require
that much hassle.

-- 
 Twisted | Christopher Armstrong: International Man of Twistery
  Radix  |  Release Manager,  Twisted Project
-+ http://twistedmatrix.com/users/radix.twistd/


Re: Objects and classes, try 3

2003-03-10 Thread Christopher Armstrong
On Sun, Mar 09, 2003 at 01:07:46PM -0500, Dan Sugalski wrote:

 * Objects have properties you can fetch and store by name
 * Objects have methods you can call
 * Objects have attributes you can fetch
 * You can fetch a hash of all the properties
 * When fetching or storing a generic property, you may call a method 
 instead, as methods win
 * You can fetch a method PMC from the object
 * You can fetch the object's Class PMC
 
 All of these have vtable entries in the PMC: get_prop, set_prop, 
 get_attrib, set_attrib, get_prop_hash, get_method, call_method, 
 get_class. (Some already have names, I'm doing this from memory)
 
 No, you can't set a method or the property hash from an object PMC. 
 Arguments with good reasons to do so will be cheerfully read and not 
 implemented. :)

How about target languages allow you to do this? :) (Python!)

But otherwise, I like this spec much more than your previous ones. It
seems more interface-oriented than implementation-oriented. That's
crucial for language compatibility, I think. If you stick to an
interface-oriented approach, then it should be no problem for Python,
Perl, Ruby, etc, to implement all of their wacky object semantics
while preventing incompatibility (or even special inter-language glue
code).

-- 
 Twisted | Christopher Armstrong: International Man of Twistery
  Radix  |  Release Manager,  Twisted Project
-+ http://twistedmatrix.com/users/radix.twistd/


Re: bit rot (and other tribulations) in parrot/languages/*

2003-02-18 Thread Christopher Armstrong
On Tue, Feb 18, 2003 at 02:14:39AM -0800, Tupshin Harper wrote:
 Befunge-93:
 Trivial, but a fresh cvs checkout has a lingering empty Befunge-93 
 directory.

This is a CVS annoyance. It's a good idea to add:

checkout -P
update -d -P

to your ~/.cvsrc. You won't get empty directories if you use -P.

As for the rest of your problems, I'm clueless. :-)


-- 
 Twisted | Christopher Armstrong: International Man of Twistery
  Radix  |  Release Manager,  Twisted Project
-+ http://twistedmatrix.com/users/radix.twistd/



Re: Securing Parrot ASM

2003-01-28 Thread Christopher Armstrong
On Tue, Jan 28, 2003 at 11:41:14AM +, Thomas Whateley wrote:
 Hi,
 
 I've been thinking about how to run un-trusted code,
 without having to audit every line, or use some sort of sandbox,
 and was wondering if Parrot could provide a Mandator Access 
 Control mechanism (ala SE Linux/Flask).
 
 When assembling Parrot, the assembler could either look in a 
 file or a perl BEGIN type block containing a list of access 
 requests along the lines of:
 
   syscall time
   read-write directory /tmp
   listen socket 80
   connect socket 25
   read-write file /etc/shadow
 
 
 If people think something like this would be usefull, I'd be
 more than happy to research this further and try to come up
 with some code


It would be immensely useful, especially for online, distributed
games, in addition to general sysadmin paranoia. I'm very interested
in this. It reminds me of the capability systems. I'm admittedly
pretty culeless when it comes to this stuff, but it's one of the
reasons I really want Parrot to succeed.

Of course, doing this on the parrot level brings up some interesting
issues; how exactly do we define what needs to be restricted in case
of untrusted code? I'm inclined to say All classes, because a white
list is really the only sane way to do security, with defaults being
classes that are deemed harmless. Also, I think that this should be
made as dynamic as possible so different languages/applications can
plug in to the security system to overload certain things
(intentionally vague here).

One other thing to think about is resource limits. It'd be nice to not
require `ulimit' or whatever system-specific resource limitation
mechanism, but rather rely on the parrot interpreter to
baby-sit. Also, it'd make catching these resource-limit violations
much more convenient; an exception could be raised (or, e.g., the rate
at which bytecodes are executed could be throttled), rather than
simply rudely killing the process. For what I want to do, it's not
really required, and it's not really relevant to the type of security
we're discussing here, but it would still be very, very useful.

Some incoherent ramblings of mine about secure distributed code in
virtual worlds:

http://twistedmatrix.com/users/radix.twistd/Distributed_20Games

A really cool research-project language, E, which is all about
capabilities:

http://erights.org/

CapDesk, a slightly irrelevant but very interesting design for
capability UIs:

http://www.combex.com/tech/index.html


-- 
 Twisted | Christopher Armstrong: International Man of Twistery
  Radix  |  Release Manager,  Twisted Project
-+ http://twistedmatrix.com/users/radix.twistd/



Re: Securing Parrot ASM

2003-01-28 Thread Christopher Armstrong
On Tue, Jan 28, 2003 at 02:11:39PM +, Matthew Byng-Maddick wrote:
 On Tue, Jan 28, 2003 at 11:41:14AM +, Thomas Whateley wrote:
  I've been thinking about how to run un-trusted code,
  without having to audit every line, or use some sort of sandbox,
 [snip]
  block to audit and be certain of what a module/program could
  do to my system.
 
 As author of http://dev.perl.org/rfc/353.pod, I thought somewhat about
 these issues, and eventually hit a rather hard brick wall.
 
 What happens when you link in some module that's written natively?
 Basically, my conclusion was that this was, unfortunately, still
 necessary, but once you do it, then all bets about restriction and
 security are off. If you can get around the necessity of that (and
 only allow things which are parrot-native, then you can control it).

Hrm, maybe I just don't know what's going on, but I'm not sure why
this is a problem. Couldn't call out to native functions or perhaps
call out to native functions in this library or even call out to
*this* native function be a capability? AFAIC (which means for the
applications I'm interested in), any of the three are still Good
Enough.

I guess what I'm saying is, sure, you can't stop a native function
(which was called from parrot code) from doing whatever it wants, but
you can still prevent the parrot code from using that function in the
first place (right?).

-- 
 Twisted | Christopher Armstrong: International Man of Twistery
  Radix  |  Release Manager,  Twisted Project
-+ http://twistedmatrix.com/users/radix.twistd/



Re: Securing Parrot ASM

2003-01-28 Thread Christopher Armstrong
On Tue, Jan 28, 2003 at 09:24:20AM -0800, Brent Dax wrote:
 Christopher Armstrong:
 # One other thing to think about is resource limits. It'd be nice to not
 # require `ulimit' or whatever system-specific resource limitation
 # mechanism, but rather rely on the parrot interpreter to
 # baby-sit. Also, it'd make catching these resource-limit violations
 # much more convenient; an exception could be raised (or, e.g., the rate
 # at which bytecodes are executed could be throttled), rather than
 # simply rudely killing the process. For what I want to do, it's not
 # really required, and it's not really relevant to the type of security
 # we're discussing here, but it would still be very, very useful.
 
 I don't see why Parrot couldn't do much of this.  It can certainly audit
 allocations made through its own memory-allocation system, and with only
 a little help from the system it should be able to audit its processor
 usage as well (at least within Parrot bytecode).  I'm not sure about
 disk space usage, but that's a pretty OS-level thing anyway.

Cool. I'm really only concerned about CPU and memory usage, as I'd
never allow plain file I/O to my untrusted code -- just
application-level APIs for doing specific things that might access the
disk.

-- 
 Twisted | Christopher Armstrong: International Man of Twistery
  Radix  |  Release Manager,  Twisted Project
-+ http://twistedmatrix.com/users/radix.twistd/



Re: Securing Parrot ASM

2003-01-28 Thread Christopher Armstrong
On Tue, Jan 28, 2003 at 04:15:41PM +, Matthew Byng-Maddick wrote:
 On Tue, Jan 28, 2003 at 11:04:43AM -0500, Christopher Armstrong wrote:
  Hrm, maybe I just don't know what's going on, but I'm not sure why
  this is a problem. Couldn't call out to native functions or perhaps
  call out to native functions in this library or even call out to
  *this* native function be a capability? AFAIC (which means for the
  applications I'm interested in), any of the three are still Good
  Enough.
 
 Oh, yes, it is still a reasonable capability, but at the point that you
 allow that capability, you can forget any of the rest of them. (this is
 of course, ignoring any possible buffer overruns/format string/double-free
 or other types of vulnerability where you can change the executed code).
 
  I guess what I'm saying is, sure, you can't stop a native function
  (which was called from parrot code) from doing whatever it wants, but
  you can still prevent the parrot code from using that function in the
  first place (right?).
 
 Yes, but looking at the current Perl core, a large number of the
 day-to-day useful modules are written native (read: in C), so you end
 up losing there. That's not to say that future ones will have to be,
 but... In reality, however, the problem as I see it is that this is a
 capability which, once acquired overrides all others (wheras the others
 can be mutually orthogonal).

I don't see why. Why, for example, would socket access (a
C-implemented feature, certainly) allow access to everything else?
Presumably, the built-in parrot[/perl/python/etc] functionality is
`trusted' such that it only does what it *says* it does (after
auditing and removing 100% of the bugs, of course ;), and you can give
out caps to them on a per-func/obj/whatever basis. But maybe I'm
totally misunderstanding what you're saying. Are you just assuming
there are bugs in all native built-in functions that are exploitable
to gain other capabilities? An example would help.

Anyway, even if you're right about access to native functions, the way
I'm thinking I'd use this would be to have a trusted program (i.e., my
imaginary virtual world engine) running various untrusted scripts from
around the world. With such a system, we'll just give the untrusted
code access to application-level APIs (which themselves will be
managed with capabilities, to facilitate differing trust levels) -- no
need to give them access to such things as file I/O and
whatnot. However, I guess socket access would be required, as I plan
on having them executed in a separate process (with ulimits) and talk
to the main system through an RPC (i.e., sockets) mechanism, with
probably a chroot/jail thrown in for good measure, but this is an easy
thing to audit and I can't see ever requiring more low-level access.

-- 
Twisted | Christopher Armstrong: International Man of Twistery 
Radix   | Release Manager, Twisted Project
+ http://twistedmatrix.com/users/radix.twistd/



PyCon

2003-01-28 Thread Christopher Armstrong
Hey, any Parrot hackers going to the Python convention at the end of
March? http://python.org/pycon/. Price will be $150-$200. I'm very
interested in meeting and discussing there :-)

-- 
 Twisted | Christopher Armstrong: International Man of Twistery
  Radix  |  Release Manager,  Twisted Project
-+ http://twistedmatrix.com/users/radix.twistd/



Re: AUTOLOADED pre- and post- handler methods?

2003-01-25 Thread Christopher Armstrong
Dan Sugalski [EMAIL PROTECTED] writes:
 I know (now) that python lets you have an interceptor method that gets
 called before a named method is called even. Does it allow this method
 to be generated by the generic fallback method?

Python doesn't really have interceptor methods. In fact, there
aren't any magic methods that are called specifically on method
calling -- only attribute access (well, except for __call__, which
happens when you do obj(), but that's a separate step in the process).


__getattribute__(self, name) -- Always called on attribute access.

__getattr__(self, name) -- Called after looking up the attribute
fails by regular means.

__get__(self, obj, type=None) -- Called on an object when that object
  is accessed as an attribute of
  another object. f34r this. :-)

Any of which, of course, can return methods. :-) btw, remember how
Python creates `bound methods' when you access a method through an
instance? It's implemented with (the C equivalent of) __get__ (As of
Python 2.2). More information related to that (and other useful
information in general) is here:
http://www.python.org/2.2.2/descrintro.html.

Btw, these all have `set' and `del' friends, but they don't always
perfectly match up with the `get's... I'll get back to you on that.

-- 
 Twisted | Christopher Armstrong: International Man of Twistery
  Radix  |  Release Manager,  Twisted Project
-+ http://twistedmatrix.com/users/radix.twistd/



Re: Objects, finally (try 1)

2003-01-22 Thread Christopher Armstrong
On Wed, Jan 15, 2003 at 01:57:28AM -0500, Dan Sugalski wrote:
 At 9:37 PM -0500 1/14/03, Christopher Armstrong wrote:
 But who knows, maybe it could be made modular enough (i.e., more
 interface-oriented?) to allow the best of both worlds -- I'm far too
 novice wrt Parrot to figure out what it'd look like, unfortunately.
 
 It'll actually look like what we have now. If you can come up with 
 something more abstract than:
 
   callmethod P1, foo
 
 that delegates the calling of the foo method to the method dispatch 
 vtable entry for the object in P1, well... gimme, I want it. :)

Just curious. Exactly how overridable is that `callmethod'? I don't
really know anything about the vtable stuff in Parrot, but is it
possible to totally delegate the lookup/calling of foo to a function
that's bound somehow to P1? Or does the foo entry have to exist in
the vtable already? Sorry for the naive question :-) Oh, and if you
just want to point me at a source file, I guess I can try reading it
:-) Python basically requires that each step in the process be
overridable. (1. look up attribute 2. call attribute, at least in
`callmethod's case).

Thanks.

-- 
 Twisted | Christopher Armstrong: International Man of Twistery
  Radix  |  Release Manager,  Twisted Project
-+ http://twistedmatrix.com/users/radix.twistd/



Re: Compiling to Parrot

2003-01-21 Thread Christopher Armstrong
On Tue, Jan 21, 2003 at 08:41:47AM +, Simon Wistow wrote:
 Speaking of games, it would be interesting to see Parrot be used in that
 direction. A lot of games currently are pretty much developed along the
 lines of 'custom scripting language interfaced to custom game engine'

One of the reasons I'm interested in Parrot -- I'm hoping that it's
going to have some secure execution facilities built-in from the
ground up (to facilitate user-code on virtual world servers) :-)

-- 
 Twisted | Christopher Armstrong: International Man of Twistery
  Radix  |  Release Manager,  Twisted Project
-+ http://twistedmatrix.com/users/radix.twistd/



Re: Objects, finally (try 1)

2003-01-15 Thread Christopher Armstrong
On Wed, Jan 15, 2003 at 01:57:28AM -0500, Dan Sugalski wrote:
 At 9:37 PM -0500 1/14/03, Christopher Armstrong wrote:
 But who knows, maybe it could be made modular enough (i.e., more
 interface-oriented?) to allow the best of both worlds -- I'm far too
 novice wrt Parrot to figure out what it'd look like, unfortunately.
 
 It'll actually look like what we have now. If you can come up with 
 something more abstract than:
 
   callmethod P1, foo
 
 that delegates the calling of the foo method to the method dispatch 
 vtable entry for the object in P1, well... gimme, I want it. :)

 I'll add define method dispatch more to the list o' stuff for the 
 next edit of the proposal.

I'll help you along by offering this explanation of how instance
methods work in Python. (sorry if you're already familiar with this
stuff, but it's in my best interest to make sure you are ;-))

When you say something like `o.foo()', it translates into these steps:

 1) LOAD_NAME 'o'
 2) LOAD_ATTR 'bar'
 3) CALL_FUNCTION

#2 has extra magic. What I mean is, when you LOAD_ATTR a function from
a *class*, you just get back a plain old `unbound method'. When you
LOAD_ATTR from an *instance*, and (after failing to find an instance
attribute) the attribute is found on its class, you get a `bound
method', which basically means that Python has curried that method
so the first argument is automatically passed -- that first argument
is the instance which you LOAD_ATTRd from. This is why you see all
those python methods with the first argument being `self', and rarely
see code which explicitly passes that first argument.

Now, like I said, this magic is done in LOAD_ATTR, not CALL_FUNCTION,
so you can take that bound method object and do whatever you want with
it before calling it.

Here's an interesting code snippet which also demonstrates the fact
that methods are just attributes.

 def toot(): print hello
... 
 class Foo: pass
... 
 # binding a method *to the instance* -- this prevents magic
 o = Foo(); o.toot = toot 
 o.toot()
hello
 # binding method *to the class* -- just the same as if we defined
 # `toot' in the class definition
 Foo.toot = toot 
 o2 = Foo()
 o2.toot()
Traceback (most recent call last):
  File stdin, line 1, in ?
TypeError: toot() takes no arguments (1 given)

That traceback happened because, as I explained above, when the `toot'
attribute was LOAD_ATTR'd from the instance and found on the class, it
was turned into a bound method that would have the instance
automatically passed to it.

HTH,

-- 
 Twisted | Christopher Armstrong: International Man of Twistery
  Radix  |  Release Manager,  Twisted Project
-+ http://twistedmatrix.com/users/radix.twistd/



Re: Objects, finally (try 1)

2003-01-14 Thread Christopher Armstrong
On Tue, Jan 14, 2003 at 12:38:35PM -0800, Jonathan Sillito wrote:
  -Original Message-
  From: Dan Sugalski [mailto:[EMAIL PROTECTED]]
 
  A property is a runtime assignable name/value pair that you stick on
  a variable or value. An attribute is a named variable that all
  objects of a particular class have.
 
  Properties can come and go at runtime, but attributes are fixed. (I
  think you could also consider attributes instance variables, but
  I'm a bit OO fuzzy so I'm not sure that's entirely right)
 
 Ok, in the case of python or ruby, instance variables are not fixed and they
 are not declared as part of the class. I suppose this can be handled by
 giving such classes one hash attribute for storing these instance variables.

Yeah, that would be similar to how Python works now anyway; all
instance attributes are stored in a dict which is itself accessible as
an attribute on an instance: '__dict__'. Oh, except for the new
__slots__ feature, which might actually find a use with the
fixed-attribute-system that Dan has proposed.

-- 
 Twisted | Christopher Armstrong: International Man of Twistery
  Radix  |  Release Manager,  Twisted Project
-+ http://twistedmatrix.com/users/radix.twistd/



Re: Objects, finally (try 1)

2003-01-14 Thread Christopher Armstrong
On Tue, Jan 14, 2003 at 03:00:17PM -0500, Dan Sugalski wrote:
 At 11:44 AM -0800 1/14/03, Mr. Nobody wrote:
 Seems pretty reasonable, but don't you mean PerlRef, PerlAttr, PerlClass,
 PerlObject?
 
 Nope. There's nothing particularly perlish about them, and if we're 
 going to have a common base set of object functionality, they'll 
 probably be named ParrotRef/Attr/Class/Object. They should suffice 
 for perl, python, and ruby (at the very least) unless I've missed 
 something.

Hmm, well. Are you really trying to make it so Python won't have to
make a specialized subclass (err, subPMC?) of this system? If so, then
it'll probably need drastic changes.. I'm a Python hacker who's pretty
familiar with its object system. If you want, I can offer up some
explanations/advice for making this system usable directly by Python.

As it stands, an implementation of the Python object system could
definitely be implemented _in terms of_ what you have now, but, for
example, the method system that you have worked out now would be
totally unusable (afaics), as instance methods have some pretty
whacky, dynamic semantics. It'd probably have to be implemented in
terms of properties.

The problem, of course, is that either you go more static and make the
very dynamic, reflective languages like Python harder to implement (or
prevent them from making use of your existing abstractions like
methods, as explained above), or you go more dynamic and make the more
static languages (like Haskell?) slower because they'd have to
implement their features in terms of dynamic ones, when a lot of the
information could be available at compile-time.

But who knows, maybe it could be made modular enough (i.e., more
interface-oriented?) to allow the best of both worlds -- I'm far too
novice wrt Parrot to figure out what it'd look like, unfortunately.

I've been lurking this thread for a while, very interested, and unsure
if I should offer my suggestions for making the object system more
compatible with Python, and this looks like a great chance for me to
jump in. :-)

-- 
 Twisted | Christopher Armstrong: International Man of Twistery
  Radix  |  Release Manager,  Twisted Project
-+ http://twistedmatrix.com/users/radix.twistd/