And of course I forgot to reply to the list at large... sorry :x

-- Matthieu


On Wed, Mar 12, 2014 at 8:48 PM, Matthieu Monrocq <
matthieu.monr...@gmail.com> wrote:

>
>
>
> On Tue, Mar 11, 2014 at 10:18 PM, Patrick Walton <pcwal...@mozilla.com>wrote:
>
>> On 3/11/14 2:15 PM, Maciej Piechotka wrote:
>>
>>> Could you elaborate on DOM? I saw it referred a few times but I haven't
>>> seen any details. I wrote simple bindings to libxml2 dom
>>> (https://github.com/uzytkownik/xml-rs - warning - I wrote it while I was
>>> learning ruby) and I don't think there was a problem of OO - main
>>> problem was mapping libxml memory management and rust's one [I gave up
>>> with namespaces but with native rust dom implementation it would be
>>> possible to solve in nicer way]. Of course - I might've been at too
>>> early stage.
>>>
>>
>> You need:
>>
>> 1. One-word pointers to each DOM node, not two. Every DOM node has 5
>> pointers inside (parent, first child, last child, next sibling, previous
>> sibling). Using trait objects would 10 words, not 5 words, and would
>> constitute a large memory regression over current browser engines.
>>
>> 2. Access to fields common to every instance of a trait without virtual
>> dispatch. Otherwise the browser will be at a significant performance
>> disadvantage relative to other engines.
>>
>> 3. Downcasting and upcasting.
>>
>> 4. Inheritance with the prefix property, to allow for (2).
>>
>> If anyone has alternative proposals that handle these constraints that
>> are more orthogonal and are pleasant to use, then I'm happy to hear them.
>> I'm just saying that dismissing the feature out of hand is not productive.
>>
>>
>> Patrick
>>
>>
> Please excuse me, I need some kind of visualization here, so I concocted a
> simple tree:
>
> // So, in pseudo C++, let's imagine a DOM tree
> struct Element { Element *parent, *prevSib, *nextSib, *firstChild,
> *lastChild; uint leftPos, topPos, height, width; bool hidden; };
> struct Block: Element { BlockProperties blockP; }; struct Div: Block {};
> struct Inline: Element { InlineProperties inlineP; }; struct Span: Inline
> {};
>
>
> Now, I'll be basically mimicking the way LLVM structures its AST, since
> the LLVM AST achieves dynamic casting without RTTI. Note that this has a
> very specific downside: the hierarchy is NOT extensible.
>
> // And now in Rust (excuse my poor syntax/errors)
> enum ElementChild<'r> { ChildBlock(&'r Block), ChildInline(&'r Inline) }
>
> struct Element {
>     child: Option<&'self ElementChild<'self>>;
>     parent: &'self Element;
>     prevSib, nextSib, firstChild, lastChild: Option<&'self Element>;
>     leftPos, topPos, height, width: uint;
>     hidden: bool;
> }
>
>
> enum BlockChild<'r> { ChildDiv(&'r Div) }
>
> struct Block {
>     elementBase: Element;
>     child: Option<&'self BlockChild<'self>>;
>     blockP: BlockProperties;
> }
>
> struct Div { blockBase: Block; }
>
>
> enum InlineChild<'r> { ChildSpan(&'r Span) }
>
> struct Inline {
>     elementBase: Element;
>     child: Option<&'self InlineChild<'self>>;
>     inlineP: InlineProperties;
> }
>
> struct Span { inlineBase: Inline; }
>
>
> Let us review our objectives:
>
> (1) One word to each DOM element: check => Option<&'r Element>
>
> (2) Direct access to a field, without indirection: check =>
> span.inlineBase.elementBase.hidden
>
> (3) Downcast and upcasting: check => downcast is done by matching:
> match(element.child) { ChildBlock(&'r block) => /* act on block */,
> ChildInline(&'r inline) => /* act on inline */); upcast is just accessing
> the "base" field.
>
> (4) Inheritance with the prefix property => not necessary, (2) is already
> satisfied.
>
>
> Note on (3): multiple bases are allowed easily, it's one field per base.
>
>
> In order to reduce the foot-print; avoiding having a "child" field at each
> level of the hierarchy might be beneficial. In this case, only the final
> classes are considered in ElementChild
>
> enum ElementChild<'r> { ChildDiv(&'r Div), ChildSpan(&'r Span) }
>
> And then downcasting to &'r Block is achieved by:
>
> match(element.final) { ChildDiv(&'r div) => Some(&'r div.blockBase), _ =>
> None }
>
>
> I would note that this does not make use of traits at all; the analysis is
> only based on Patrick's list of objectives which I guess is incomplete and
> I was lacking a realistic example so it might not address the full scope of
> the problem...
>
> ... still, for CLOSED hierarchies, the use of traits should not be
> necessary, although it might be very convenient.
>
> -- Matthieu.
>
>
>>  _______________________________________________
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>
>
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to