From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18589 invoked by alias); 1 Nov 2018 05:32:10 -0000 Mailing-List: contact kawa-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: kawa-owner@sourceware.org Received: (qmail 8441 invoked by uid 89); 1 Nov 2018 05:25:29 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-7.6 required=5.0 tests=BAYES_00,GIT_PATCH_2,RCVD_IN_DNSWL_LOW,SPF_PASS,TIME_LIMIT_EXCEEDED autolearn=unavailable version=3.3.2 spammy=online X-HELO: aibo.runbox.com Received: from aibo.runbox.com (HELO aibo.runbox.com) (91.220.196.211) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 01 Nov 2018 05:25:00 +0000 Received: from [10.9.9.211] (helo=mailfront11.runbox.com) by mailtransmit02.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1gI5TQ-0006NN-Kl for kawa@sourceware.org; Thu, 01 Nov 2018 06:24:52 +0100 Received: by mailfront11.runbox.com with esmtpsa (uid:757155 ) (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.82) id 1gI5TN-0001T1-D0 for kawa@sourceware.org; Thu, 01 Nov 2018 06:24:50 +0100 Subject: Re: JavaFX unexpected warning To: kawa@sourceware.org References: <1301.1540979293@vpaur.eip10.org> <43f199d7-e2e8-ecf3-726f-c0ddc6965f39@bothner.com> From: Per Bothner Message-ID: <57543c7a-11fa-a0ce-9b07-bcc5c4243b9c@bothner.com> Date: Thu, 01 Nov 2018 05:32:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 MIME-Version: 1.0 In-Reply-To: <43f199d7-e2e8-ecf3-726f-c0ddc6965f39@bothner.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-IsSubscribed: yes X-SW-Source: 2018-q4/txt/msg00019.txt.bz2 On 10/31/18 10:23 AM, Per Bothner wrote: > This could be fixed if we implemented an optimization which sets the 'button' > variable before we set its fields.  This has a big advantage in that it enables > building self-referential data structures more easily, as well as data structures that > mutually reference each other.  It would have the side-effect of fixing this mini-bug. > > I've thought into doing the above optimization, but I don't remember how far I got. > (There are lot of old corners in Kawa.) > > Anyway, I'm looking into it. It looks like more work than I want to spend right now, but I came up with an approach that I think makes sense. I wrote it up in the "Ideas and tasks for contributing to Kawa" section (in the git version of the manual but not yet online): 3.6.1 Recusively initialized data structures -------------------------------------------- (GSoC) Kawa has convenient syntax to *note allocate and initialize objects: Allocating objects, but it gets messier it you want to initialize multiple objects that reference each other. Likewise for a single object “tree” which contains links to the root. In this example, we will looks at two vectors, but the feature is more useful for tree structures. Assume: (define-constant list1 [1 2 list2]) (define-constant list2 ['a 'b list1]) The compiler translates this to: (define-constant list1 (let ((t (object[] length: 3))) ;; allocate native Java array (set! (t 0) 1) (set! (t 1) 2) (set! (t 2) list2) (FVector:makeConstant t))) (define-constant list2 (let ((t (object[] length: 3))) ;; allocate native Java array (set! (t 0) 'a) (set! (t 1) 'b) (set! (t 2) list1) (FVector:makeConstant t))) The problem is that ‘list2’ has not been created when we evaluate the initializing expression for ‘list’. We can solve the problem by re-writing: (define-private tmp1 (object[] length: 3)) (define-constant list1 (FVector:makeConstant tmp1) (define-private tmp2 (object[] length: 3)) (define-constant list2 (FVector:makeConstant tmp2) (set! (tmp1 0) 1) (set! (tmp1 1) 2) (set! (tmp1 2) list2) (set! (tmp2 0) 1) (set! (tmp2 1) 2) (set! (tmp2 2) list1) The complication is that the code for re-writing vector and object constructors is spread out (depending on the result type), and not where we deal with initializing the variables. One solution is to introduce an inlineable helper function ‘$build$’ defined as: (define ($build$ raw-value create init) (let ((result (create raw-value)) (init raw-value result) result)) Then we can re-write the above code to: (define-constant list1 ($build$ (object[] length: 3) (lambda (raw) (FVector:makeConstant raw)) (lambda (raw result) ($init-raw-array$ raw 1 2 list2)))) (define-constant list2 ($build$ (object[] length: 3) (lambda (raw) (FVector:makeConstant raw)) (lambda (raw result) ($init-raw-array$ raw 'a 'b list1)))) Note that the call to ‘$build$’, as well as the generated ‘lambda’ expressions, are all easily inlineable. Now assume if at the top-level BODY if there is a sequence of ‘define-constant’ definitions initialized with calls to ‘$build$’. Now it is relatively easy to move all the ‘init’ calls after all ‘alloc’ and ‘create’ expressions. The ‘$init-raw-array$’ calls are expanded after the code has been re-ordered. The project includes both implementing the above framework, as well as updating type-specific (and default) object creation to use the framework. It would also be good to have compiler warnings if accessing an uninitialized object. -- --Per Bothner per@bothner.com http://per.bothner.com/