Hi,

I played with the statement and turned out that it is really do a full
scope chain resolution which was unexpected. I thought this feature is
similar to joined objects:

function f() {
    var x = 3;
    this.get = function() { return x; }
    this.set = function(value) { x = value; }
}

o = new f();     // prints 3
print(o.get());
o.set(7);
print(o.get());  // prints 7

If we cannot find a better solution, we should "export" the whole scope
chain as local variables, and let the joined object mechanism handle the
expression.

var a = { x:5 }
var b = { y:6 }

// expression: return x + y
// scope a, b

var f = (function() {
    // Generate the accessible member list
    var x = a.x; // index 1
    var y = b.y; // index 2
    return [
        // index 0 - the function
        // the members are resolved
        // by locals if possible
        function() { return x + y; },
        // same order as the vars above
        function(value) { x = value; },
        function(value) { y = value; },
    ];
})();

// The following code does not involves lookups,
// only joined objects

print(f[0]()); // 5 + 6 = 11
a.x = 8;
print(f[0]()); // still 11, the change
               // does not affects it anymore
f[1](12);      // change 'x' to 12
print(f[0]()); // 12 + 6 = 18

This mechanism really does not involve any lookups, and we only need to
statically record the property indicies for each function instance. When
the property is changed, just call the appropriate handler (by the index,
no lookup here either). We could wrap the array into another function, so
f[1](12) could be turned to f(1, 12), which has a call API in v8. '1' is
SMI, so changing the value does not involve memory allocation (except for
the second argument sometimes).

Regards,
Zoltan

> Hello guys,
>
> Zoltan, I think I'm misunderstanding something here. :-/  I have some
> questions that will help me understand better:
>
> 1) Thinking about the example that uses JS
>
>   globalObject->Set(String::New("context"), instance);
>   globalObject->Set(String::New("newGlobal"), globalObject);
>
>   Local<Value> result = CompileRun(
>       "(function() {"
>       "   with(context)"
>       "     with(newGlobal)"
>       "       return (function() { valueA + valueB + Math.sin(0) });"
>       "})();");
>
> imagine that during compilation 'newGlobal' has valueA. If I
> understand correct, you are saying that when I execute the function in
> result, it will not perform lookup?
>
> Imagine that we remove it from 'newGlobal' and add another into
> 'context'. We need another lookup to know that valueA comes from
> context and not newGlobal anymore, right? How does v8 knows that it's
> time to perform lookup again?
>
>
> 2) The C++ API we have exists to create programatically the construct
> with with-statements in JavaScript. So I wasn't really expecting that
> we get too much difference from the both approaches. This is how the
> feature is implemented today.
>
>> As for cunclusion I would suggest the with statement, since if you
>> happens
>> to change the JS engine again, it will still work.
>
> Yes, we get the semantics we want with this approach but the whole
> point is that it is slow in current engines :-(  so we have two ways:
> (a) optimize the cases we use; (b) find another approach.
>
> For (a) there is the idea that engine could do better if knew that the
> objects in with() are "sealed". For (b) there's the approach of
> changing the lookup code to match our semantics.
>
>
> Cheers,
>
>
> --
> Caio Marcelo de Oliveira Filho
> OpenBossa - INdT


_______________________________________________
Qt-script mailing list
[email protected]
http://lists.qt.nokia.com/mailman/listinfo/qt-script

Reply via email to