Interesting, thanks. This summer I am hoping an intern will work on
investigating sync/async transformations, this stuff is very relevant to
that.

- Alon



On Mon, Mar 17, 2014 at 3:38 PM, Joel Croteau <[email protected]> wrote:

> The syntax is a little different, but the C++11 promise/future template
> offers essentially the same functionality. See
> http://www.cplusplus.com/reference/future/promise/ for the usage of this,
> and http://promises-aplus.github.io/promises-spec/ for the proposed
> Javascript spec.
> On Mar 17, 2014 3:16 PM, "Alon Zakai" <[email protected]> wrote:
>
>> I didn't know about the JavaScript Promises stuff, that's interesting. To
>> allow sync-looking code on the C++ side, it would need to integrate with
>> something there, if there is a c++11 feature that works there, as you say,
>> then this might work very well.
>>
>> - Alon
>>
>>
>>
>> On Sun, Mar 16, 2014 at 11:44 PM, Joel Croteau <[email protected]>wrote:
>>
>>> I was able to implement this using Javascript Promises (I haven't made
>>> this a pull request because it's rather experimental):
>>>
>>>   emscripten_sync_wget2_data: function(url, request, param, arg, free,
>>> onload, onerror, onprogress) {
>>>     var _url = Pointer_stringify(url);
>>>     var _request = Pointer_stringify(request);
>>>     var _param = Pointer_stringify(param);
>>>
>>>     var promise = new Promise(function(resolve, reject) {
>>>       var http = new XMLHttpRequest();
>>>       http.open(_request, _url, true);
>>>       http.responseType = 'arraybuffer';
>>>
>>>       // LOAD
>>>       http.onload = function http_onload(e) {
>>>         if (http.status == 200 || _url.substr(0,4).toLowerCase() !=
>>> "http") {
>>>           resolve(http.response);
>>>         }
>>>         else {
>>>           reject(http.status, http.statusText);
>>>         }
>>>       };
>>>
>>>       // ERROR
>>>       http.onerror = function http_onerror(e) {
>>>         reject(http.status, http.statusText);
>>>       };
>>>
>>>       // PROGRESS
>>>       http.onprogress = function http_onprogress(e) {
>>>         if (onprogress) Runtime.dynCall('viii', onprogress, [arg,
>>> e.loaded, e.lengthComputable || e.lengthComputable === undefined ? e.total
>>> : 0]);
>>>       };
>>>
>>>       // Useful because the browser can limit the number of redirection
>>>       try {
>>>         if (http.channel instanceof Ci.nsIHttpChannel)
>>>           http.channel.redirectionLimit = 0;
>>>       } catch (ex) { /* whatever */ }
>>>
>>>       if (_request == "POST") {
>>>         //Send the proper header information along with the request
>>>         http.setRequestHeader("Content-type",
>>> "application/x-www-form-urlencoded");
>>>         http.setRequestHeader("Content-length", _param.length);
>>>         http.setRequestHeader("Connection", "close");
>>>         http.send(_param);
>>>       } else {
>>>         http.send(null);
>>>       }
>>>     });
>>>
>>>     promise.then(function(data) {
>>>       var byteArray = new Uint8Array(data);
>>>       var buffer = _malloc(byteArray.length);
>>>       HEAPU8.set(byteArray, buffer);
>>>       if (onload) Runtime.dynCall('viii', onload, [arg, buffer,
>>> byteArray.length]);
>>>       if (free) _free(buffer);
>>>     }, function(status, statusText) {
>>>       if (onerror) Runtime.dynCall('viii', onerror, [arg, status,
>>> statusText]);
>>>     });
>>>   },
>>>
>>> Promises are still fairly new, and only supported by the most recent
>>> versions of Chrome and Firefox, but they do give us the functionality we
>>> want here. I think the best way to implement this in code would be if I
>>> could use the C++ promise and future APIs. You can use these if you compile
>>> with -std=c++11. All this seems to do at present is send the code into an
>>> infinite loop, but if they could map into equivalent Javascript promise
>>> calls, I think it could work quite well. At least in the case of
>>> emscripten_sync_wget2_data, it could be set to use synchronous XHRs as a
>>> fallback. This would still work, just require some extra conversion work,
>>> and wouldn't call onprogress events.
>>>
>>> On Sunday, March 16, 2014 7:17:56 PM UTC-7, Alon Zakai wrote:
>>>
>>>> It can capture its environment, so you can put the second half of the
>>>> function in a lambda, and call the lambda later on when you want to, in
>>>> response to something.
>>>>
>>>> - Alon
>>>>
>>>>
>>>>
>>>> On Sun, Mar 16, 2014 at 7:12 PM, Joel Croteau <[email protected]>wrote:
>>>>
>>>>>  I can understand using Javascript generators, but how would c++
>>>>> lambdas help?
>>>>> On Mar 16, 2014 3:47 PM, "Alon Zakai" <[email protected]> wrote:
>>>>>
>>>>>> Currently not. It would require a very different code generation
>>>>>> approach than we currently have.
>>>>>>
>>>>>> In theory something similar could be done using generators, in very
>>>>>> recent versions of firefox and chrome. But even with the help of
>>>>>> generators, this is not easy to do, and it is not clear how it would 
>>>>>> affect
>>>>>> performance - likely very adversely.
>>>>>>
>>>>>> One similar thing you can do is manage your own code using c++11
>>>>>> lambdas. You could write a little system that continues to run the 
>>>>>> current
>>>>>> function once a callback triggers that.
>>>>>>
>>>>>> - Alon
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Sun, Mar 16, 2014 at 1:43 AM, Joel Croteau <[email protected]>wrote:
>>>>>>
>>>>>>> I would like to have a function that makes an async call, and
>>>>>>> returns control to the browser during the call, then resumes once the 
>>>>>>> async
>>>>>>> call is complete. However, I would like this to appear to the calling 
>>>>>>> code
>>>>>>> to be a synchronous call. So for instance, I could do something like 
>>>>>>> this:
>>>>>>>
>>>>>>> struct FileInfo
>>>>>>> {
>>>>>>>     void* buffer;
>>>>>>>     unsigned size;
>>>>>>> };
>>>>>>>
>>>>>>> FileInfo loadUrl(const char* url)
>>>>>>> {
>>>>>>>     FileInfo info;
>>>>>>>     emscripten_async_wget2_data(url, "GET", "", &info, false,
>>>>>>> onload, onerror, onprogress);
>>>>>>>     emscripten_pause(); // Blocks until emscripten_resume() is called
>>>>>>>     return info;
>>>>>>> }
>>>>>>>
>>>>>>> void onerror(void* ptr, int code, const char* desc)
>>>>>>> {
>>>>>>>     // Handle not found, etc.
>>>>>>> }
>>>>>>>
>>>>>>> void onprogress(void* ptr, int loaded, int total)
>>>>>>> {
>>>>>>>     // Update progress bar
>>>>>>> }
>>>>>>>
>>>>>>> void onload(void* ptr, void* buffer, unsigned size)
>>>>>>> {
>>>>>>>     static_cast<FileInfo*>(ptr)->buffer = buffer;
>>>>>>>      static_cast<FileInfo*>(ptr)->size = size;
>>>>>>>
>>>>>>>     emscripten_resume(); // Now loadUrl resumes and returns FileInfo.
>>>>>>> }
>>>>>>>
>>>>>>> Is there any way to do this?
>>>>>>>
>>>>>>> --
>>>>>>> You received this message because you are subscribed to the Google
>>>>>>> Groups "emscripten-discuss" group.
>>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>>> send an email to [email protected].
>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>>
>>>>>>
>>>>>>  --
>>>>>> You received this message because you are subscribed to a topic in
>>>>>> the Google Groups "emscripten-discuss" group.
>>>>>> To unsubscribe from this topic, visit https://groups.google.com/d/
>>>>>> topic/emscripten-discuss/Op5ifeMjauA/unsubscribe.
>>>>>> To unsubscribe from this group and all its topics, send an email to
>>>>>> [email protected].
>>>>>>
>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>
>>>>>  --
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups "emscripten-discuss" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>>> an email to [email protected].
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>>
>>>>  --
>>> You received this message because you are subscribed to the Google
>>> Groups "emscripten-discuss" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to [email protected].
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>  --
>> You received this message because you are subscribed to a topic in the
>> Google Groups "emscripten-discuss" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/d/topic/emscripten-discuss/Op5ifeMjauA/unsubscribe
>> .
>> To unsubscribe from this group and all its topics, send an email to
>> [email protected].
>> For more options, visit https://groups.google.com/d/optout.
>>
>  --
> You received this message because you are subscribed to the Google Groups
> "emscripten-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to