Bringing up to date with default branch model
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 03 Apr 2013 09:19:03 +0200
branchmodel
changeset 918cee3a4e6872e
parent 915 b219134a2782
parent 917 09fee723d658
child 919 166924de6454
Bringing up to date with default branch
     1.1 --- a/rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js	Tue Apr 02 15:49:42 2013 +0200
     1.2 +++ b/rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js	Wed Apr 03 09:19:03 2013 +0200
     1.3 @@ -1,226 +1,244 @@
     1.4  // empty line needed here
     1.5 -Number.prototype.add32 = function(x) { return (this + x) | 0; };
     1.6 -Number.prototype.sub32 = function(x) { return (this - x) | 0; };
     1.7 -Number.prototype.mul32 = function(x) { 
     1.8 -    return (((this * (x >> 16)) << 16) + this * (x & 0xFFFF)) | 0;
     1.9 -};
    1.10 -Number.prototype.neg32 = function() { return (-this) | 0; };
    1.11  
    1.12 -Number.prototype.toInt8 = function()  { return (this << 24) >> 24; };
    1.13 -Number.prototype.toInt16 = function() { return (this << 16) >> 16; };
    1.14 +(function(numberPrototype) {
    1.15 +    numberPrototype.add32 = function(x) {
    1.16 +        return (this + x) | 0;
    1.17 +    };
    1.18 +    numberPrototype.sub32 = function(x) {
    1.19 +        return (this - x) | 0;
    1.20 +    };
    1.21 +    numberPrototype.mul32 = function(x) {
    1.22 +        return (((this * (x >> 16)) << 16) + this * (x & 0xFFFF)) | 0;
    1.23 +    };
    1.24 +    numberPrototype.neg32 = function() {
    1.25 +        return (-this) | 0;
    1.26 +    };
    1.27  
    1.28 -var __m32 = 0xFFFFFFFF;
    1.29 +    numberPrototype.toInt8 = function() {
    1.30 +        return (this << 24) >> 24;
    1.31 +    };
    1.32 +    numberPrototype.toInt16 = function() {
    1.33 +        return (this << 16) >> 16;
    1.34 +    };
    1.35  
    1.36 -Number.prototype.next32 = function(low) {
    1.37 -  if (this === 0) {
    1.38 -    return low;
    1.39 -  }
    1.40 -  var l = new Number(low);
    1.41 -  l.hi = this | 0;
    1.42 -  return l;
    1.43 -};
    1.44 +    var __m32 = 0xFFFFFFFF;
    1.45  
    1.46 -Number.prototype.high32 = function() { 
    1.47 -    return this.hi ? this.hi : (Math.floor(this / (__m32+1))) | 0;
    1.48 -};
    1.49 -Number.prototype.toInt32 = function() { return this | 0; };
    1.50 -Number.prototype.toFP = function() {
    1.51 -    return this.hi ? this.hi * (__m32+1) + this : this;
    1.52 -};
    1.53 -Number.prototype.toLong = function() {
    1.54 -    var hi = (this / (__m32+1)) | 0;
    1.55 -    var low = (this % (__m32+1)) | 0;
    1.56 -    if (low < 0) {
    1.57 -        low += __m32+1;
    1.58 -    }
    1.59 -        
    1.60 -    if (this < 0) {
    1.61 -        hi -= 1;
    1.62 -    }
    1.63 +    numberPrototype.next32 = function(low) {
    1.64 +        if (this === 0) {
    1.65 +            return low;
    1.66 +        }
    1.67 +        var l = new Number(low);
    1.68 +        l.hi = this | 0;
    1.69 +        return l;
    1.70 +    };
    1.71  
    1.72 -    return hi.next32(low);
    1.73 -};
    1.74 +    numberPrototype.high32 = function() {
    1.75 +        return this.hi ? this.hi : (Math.floor(this / (__m32 + 1))) | 0;
    1.76 +    };
    1.77 +    numberPrototype.toInt32 = function() {
    1.78 +        return this | 0;
    1.79 +    };
    1.80 +    numberPrototype.toFP = function() {
    1.81 +        return this.hi ? this.hi * (__m32 + 1) + this : this;
    1.82 +    };
    1.83 +    numberPrototype.toLong = function() {
    1.84 +        var hi = (this / (__m32 + 1)) | 0;
    1.85 +        var low = (this % (__m32 + 1)) | 0;
    1.86 +        if (low < 0) {
    1.87 +            low += __m32 + 1;
    1.88 +        }
    1.89  
    1.90 -Number.prototype.toExactString = function() {
    1.91 -    if (this.hi) {
    1.92 -        // check for Long.MIN_VALUE
    1.93 -        if ((this.hi == (0x80000000 | 0)) && (this == 0)) {
    1.94 -            return '-9223372036854775808';
    1.95 +        if (this < 0) {
    1.96 +            hi -= 1;
    1.97          }
    1.98 -        var res = 0;
    1.99 -        var a = [ 6,9,2,7,6,9,4,9,2,4 ];
   1.100 -        var s = '';
   1.101 -        var digit;
   1.102 -        var neg = this.hi < 0;
   1.103 -        if (neg) {
   1.104 -            var x = this.neg64();
   1.105 -            var hi = x.hi;
   1.106 -            var low = x;
   1.107 -        } else {
   1.108 -            var hi = this.hi;
   1.109 -            var low = this;
   1.110 -        }
   1.111 -        for (var i = 0; i < a.length; i++) {
   1.112 -            res += hi * a[i];
   1.113 -            var low_digit = low % 10;
   1.114 -            digit = (res % 10) + low_digit;
   1.115  
   1.116 -            low = Math.floor(low / 10);
   1.117 -            res = Math.floor(res / 10);
   1.118 -
   1.119 -            if (digit >= 10) {
   1.120 -                digit -= 10;
   1.121 -                res++;
   1.122 -            }
   1.123 -            s = String(digit).concat(s);
   1.124 -        }
   1.125 -        s = String(res).concat(s).replace(/^0+/, '');
   1.126 -        return (neg ? '-' : '').concat(s);
   1.127 -    }
   1.128 -    return String(this);
   1.129 -};
   1.130 -
   1.131 -Number.prototype.add64 = function(x) {
   1.132 -    var low = this + x;
   1.133 -    carry = 0;
   1.134 -    if (low > __m32) {
   1.135 -        carry = 1;
   1.136 -        low -= (__m32+1);
   1.137 -    }
   1.138 -    var hi = (this.high32() + x.high32() + carry) | 0;
   1.139 -    return hi.next32(low);
   1.140 -};
   1.141 -
   1.142 -Number.prototype.sub64 = function(x) {
   1.143 -    var low = this - x;
   1.144 -    carry = 0;
   1.145 -    if (low < 0) {
   1.146 -        carry = 1;
   1.147 -        low += (__m32+1);
   1.148 -    }
   1.149 -    var hi = (this.high32() - x.high32() - carry) | 0;
   1.150 -    return hi.next32(low);
   1.151 -};
   1.152 -
   1.153 -Number.prototype.mul64 = function(x) {
   1.154 -    var low = this.mul32(x);
   1.155 -    low += (low < 0) ? (__m32+1) : 0;
   1.156 -    // first count upper 32 bits of (this.low * x.low)
   1.157 -    var hi_hi = 0;
   1.158 -    var hi_low = 0;
   1.159 -    var m = 1;
   1.160 -    for (var i = 0; i < 32; i++) {
   1.161 -        if (x & m) {
   1.162 -            hi_hi += this >>> 16;
   1.163 -            hi_low += this & 0xFFFF
   1.164 -        }
   1.165 -        hi_low >>= 1;
   1.166 -        hi_low += (hi_hi & 1) ? 0x8000 : 0;
   1.167 -        hi_hi >>= 1;
   1.168 -        m <<= 1;
   1.169 -    }
   1.170 -    var hi = (hi_hi << 16) + hi_low;
   1.171 -    
   1.172 -    var m1 = this.high32().mul32(x);
   1.173 -    var m2 = this.mul32(x.high32());
   1.174 -    hi = hi.add32(m1).add32(m2);
   1.175 -    
   1.176 -    return hi.next32(low);
   1.177 -};
   1.178 -
   1.179 -Number.prototype.and64 = function(x) {
   1.180 -    var low = this & x;
   1.181 -    low += (low < 0) ? (__m32+1) : 0;
   1.182 -    if (this.hi && x.hi) {
   1.183 -        var hi = this.hi & x.hi;
   1.184          return hi.next32(low);
   1.185      };
   1.186 -    return low;
   1.187 -};
   1.188  
   1.189 -Number.prototype.or64 = function(x) {
   1.190 -    var low = this | x;
   1.191 -    low += (low < 0) ? (__m32+1) : 0;
   1.192 -    if (this.hi || x.hi) {
   1.193 -        var hi = this.hi | x.hi;
   1.194 +    numberPrototype.toExactString = function() {
   1.195 +        if (this.hi) {
   1.196 +            // check for Long.MIN_VALUE
   1.197 +            if ((this.hi == (0x80000000 | 0)) && (this == 0)) {
   1.198 +                return '-9223372036854775808';
   1.199 +            }
   1.200 +            var res = 0;
   1.201 +            var a = [6, 9, 2, 7, 6, 9, 4, 9, 2, 4];
   1.202 +            var s = '';
   1.203 +            var digit;
   1.204 +            var neg = this.hi < 0;
   1.205 +            if (neg) {
   1.206 +                var x = this.neg64();
   1.207 +                var hi = x.hi;
   1.208 +                var low = x;
   1.209 +            } else {
   1.210 +                var hi = this.hi;
   1.211 +                var low = this;
   1.212 +            }
   1.213 +            for (var i = 0; i < a.length; i++) {
   1.214 +                res += hi * a[i];
   1.215 +                var low_digit = low % 10;
   1.216 +                digit = (res % 10) + low_digit;
   1.217 +
   1.218 +                low = Math.floor(low / 10);
   1.219 +                res = Math.floor(res / 10);
   1.220 +
   1.221 +                if (digit >= 10) {
   1.222 +                    digit -= 10;
   1.223 +                    res++;
   1.224 +                }
   1.225 +                s = String(digit).concat(s);
   1.226 +            }
   1.227 +            s = String(res).concat(s).replace(/^0+/, '');
   1.228 +            return (neg ? '-' : '').concat(s);
   1.229 +        }
   1.230 +        return String(this);
   1.231 +    };
   1.232 +
   1.233 +    numberPrototype.add64 = function(x) {
   1.234 +        var low = this + x;
   1.235 +        carry = 0;
   1.236 +        if (low > __m32) {
   1.237 +            carry = 1;
   1.238 +            low -= (__m32 + 1);
   1.239 +        }
   1.240 +        var hi = (this.high32() + x.high32() + carry) | 0;
   1.241          return hi.next32(low);
   1.242      };
   1.243 -    return low;
   1.244 -};
   1.245  
   1.246 -Number.prototype.xor64 = function(x) {
   1.247 -    var low = this ^ x;
   1.248 -    low += (low < 0) ? (__m32+1) : 0;
   1.249 -    if (this.hi || x.hi) {
   1.250 -        var hi = this.hi ^ x.hi;
   1.251 +    numberPrototype.sub64 = function(x) {
   1.252 +        var low = this - x;
   1.253 +        carry = 0;
   1.254 +        if (low < 0) {
   1.255 +            carry = 1;
   1.256 +            low += (__m32 + 1);
   1.257 +        }
   1.258 +        var hi = (this.high32() - x.high32() - carry) | 0;
   1.259          return hi.next32(low);
   1.260      };
   1.261 -    return low;
   1.262 -};
   1.263  
   1.264 -Number.prototype.shl64 = function(x) {
   1.265 -    if (x >= 32) {
   1.266 -        var hi = this << (x - 32);
   1.267 -        return hi.next32(0);
   1.268 -    } else {
   1.269 -        var hi = this.high32() << x;
   1.270 -        var low_reminder = this >> (32 - x);
   1.271 -        hi |= low_reminder;
   1.272 -        var low = this << x;
   1.273 -        low += (low < 0) ? (__m32+1) : 0;
   1.274 +    numberPrototype.mul64 = function(x) {
   1.275 +        var low = this.mul32(x);
   1.276 +        low += (low < 0) ? (__m32 + 1) : 0;
   1.277 +        // first count upper 32 bits of (this.low * x.low)
   1.278 +        var hi_hi = 0;
   1.279 +        var hi_low = 0;
   1.280 +        var m = 1;
   1.281 +        for (var i = 0; i < 32; i++) {
   1.282 +            if (x & m) {
   1.283 +                hi_hi += this >>> 16;
   1.284 +                hi_low += this & 0xFFFF
   1.285 +            }
   1.286 +            hi_low >>= 1;
   1.287 +            hi_low += (hi_hi & 1) ? 0x8000 : 0;
   1.288 +            hi_hi >>= 1;
   1.289 +            m <<= 1;
   1.290 +        }
   1.291 +        var hi = (hi_hi << 16) + hi_low;
   1.292 +
   1.293 +        var m1 = this.high32().mul32(x);
   1.294 +        var m2 = this.mul32(x.high32());
   1.295 +        hi = hi.add32(m1).add32(m2);
   1.296 +
   1.297          return hi.next32(low);
   1.298 -    }
   1.299 -};
   1.300 +    };
   1.301  
   1.302 -Number.prototype.shr64 = function(x) {
   1.303 -    if (x >= 32) {
   1.304 -        var low = this.high32() >> (x - 32);
   1.305 -        low += (low < 0) ? (__m32+1) : 0;
   1.306 +    numberPrototype.and64 = function(x) {
   1.307 +        var low = this & x;
   1.308 +        low += (low < 0) ? (__m32 + 1) : 0;
   1.309 +        if (this.hi && x.hi) {
   1.310 +            var hi = this.hi & x.hi;
   1.311 +            return hi.next32(low);
   1.312 +        }
   1.313 +        ;
   1.314          return low;
   1.315 -    } else {
   1.316 -        var low = this >> x;
   1.317 -        var hi_reminder = this.high32() << (32 - x);
   1.318 -        low |= hi_reminder;
   1.319 -        low += (low < 0) ? (__m32+1) : 0;
   1.320 -        var hi = this.high32() >> x;
   1.321 -        return hi.next32(low);
   1.322 -    }
   1.323 -};
   1.324 +    };
   1.325  
   1.326 -Number.prototype.ushr64 = function(x) {
   1.327 -    if (x >= 32) {
   1.328 -        var low = this.high32() >>> (x - 32);
   1.329 -        low += (low < 0) ? (__m32+1) : 0;
   1.330 +    numberPrototype.or64 = function(x) {
   1.331 +        var low = this | x;
   1.332 +        low += (low < 0) ? (__m32 + 1) : 0;
   1.333 +        if (this.hi || x.hi) {
   1.334 +            var hi = this.hi | x.hi;
   1.335 +            return hi.next32(low);
   1.336 +        }
   1.337 +        ;
   1.338          return low;
   1.339 -    } else {
   1.340 -        var low = this >>> x;
   1.341 -        var hi_reminder = this.high32() << (32 - x);
   1.342 -        low |= hi_reminder;
   1.343 -        low += (low < 0) ? (__m32+1) : 0;
   1.344 -        var hi = this.high32() >>> x;
   1.345 -        return hi.next32(low);
   1.346 -    }
   1.347 -};
   1.348 +    };
   1.349  
   1.350 -Number.prototype.compare64 = function(x) {
   1.351 -    if (this.high32() === x.high32()) {
   1.352 -        return (this < x) ? -1 : ((this > x) ? 1 : 0);
   1.353 -    }
   1.354 -    return (this.high32() < x.high32()) ? -1 : 1;
   1.355 -};
   1.356 +    numberPrototype.xor64 = function(x) {
   1.357 +        var low = this ^ x;
   1.358 +        low += (low < 0) ? (__m32 + 1) : 0;
   1.359 +        if (this.hi || x.hi) {
   1.360 +            var hi = this.hi ^ x.hi;
   1.361 +            return hi.next32(low);
   1.362 +        }
   1.363 +        ;
   1.364 +        return low;
   1.365 +    };
   1.366  
   1.367 -Number.prototype.neg64 = function() {
   1.368 -    var hi = this.high32();
   1.369 -    var low = this;
   1.370 -    if ((hi === 0) && (low < 0)) { return -low; }
   1.371 -    hi = ~hi;
   1.372 -    low = ~low;
   1.373 -    low += (low < 0) ? (__m32+1) : 0;
   1.374 -    var ret = hi.next32(low);
   1.375 -    return ret.add64(1);
   1.376 -};
   1.377 +    numberPrototype.shl64 = function(x) {
   1.378 +        if (x >= 32) {
   1.379 +            var hi = this << (x - 32);
   1.380 +            return hi.next32(0);
   1.381 +        } else {
   1.382 +            var hi = this.high32() << x;
   1.383 +            var low_reminder = this >> (32 - x);
   1.384 +            hi |= low_reminder;
   1.385 +            var low = this << x;
   1.386 +            low += (low < 0) ? (__m32 + 1) : 0;
   1.387 +            return hi.next32(low);
   1.388 +        }
   1.389 +    };
   1.390  
   1.391 -(function(numberPrototype) {
   1.392 +    numberPrototype.shr64 = function(x) {
   1.393 +        if (x >= 32) {
   1.394 +            var low = this.high32() >> (x - 32);
   1.395 +            low += (low < 0) ? (__m32 + 1) : 0;
   1.396 +            return low;
   1.397 +        } else {
   1.398 +            var low = this >> x;
   1.399 +            var hi_reminder = this.high32() << (32 - x);
   1.400 +            low |= hi_reminder;
   1.401 +            low += (low < 0) ? (__m32 + 1) : 0;
   1.402 +            var hi = this.high32() >> x;
   1.403 +            return hi.next32(low);
   1.404 +        }
   1.405 +    };
   1.406 +
   1.407 +    numberPrototype.ushr64 = function(x) {
   1.408 +        if (x >= 32) {
   1.409 +            var low = this.high32() >>> (x - 32);
   1.410 +            low += (low < 0) ? (__m32 + 1) : 0;
   1.411 +            return low;
   1.412 +        } else {
   1.413 +            var low = this >>> x;
   1.414 +            var hi_reminder = this.high32() << (32 - x);
   1.415 +            low |= hi_reminder;
   1.416 +            low += (low < 0) ? (__m32 + 1) : 0;
   1.417 +            var hi = this.high32() >>> x;
   1.418 +            return hi.next32(low);
   1.419 +        }
   1.420 +    };
   1.421 +
   1.422 +    numberPrototype.compare64 = function(x) {
   1.423 +        if (this.high32() === x.high32()) {
   1.424 +            return (this < x) ? -1 : ((this > x) ? 1 : 0);
   1.425 +        }
   1.426 +        return (this.high32() < x.high32()) ? -1 : 1;
   1.427 +    };
   1.428 +
   1.429 +    numberPrototype.neg64 = function() {
   1.430 +        var hi = this.high32();
   1.431 +        var low = this;
   1.432 +        if ((hi === 0) && (low < 0)) {
   1.433 +            return -low;
   1.434 +        }
   1.435 +        hi = ~hi;
   1.436 +        low = ~low;
   1.437 +        low += (low < 0) ? (__m32 + 1) : 0;
   1.438 +        var ret = hi.next32(low);
   1.439 +        return ret.add64(1);
   1.440 +    };
   1.441 +    
   1.442      function __handleDivByZero() {
   1.443          var exception = new vm.java_lang_ArithmeticException;
   1.444          vm.java_lang_ArithmeticException(false).constructor
     2.1 --- a/rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/impl/Console.java	Tue Apr 02 15:49:42 2013 +0200
     2.2 +++ b/rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/impl/Console.java	Wed Apr 03 09:19:03 2013 +0200
     2.3 @@ -41,21 +41,73 @@
     2.4      @JavaScriptBody(args = {"id", "attr"}, body = 
     2.5          "return window.document.getElementById(id)[attr].toString();")
     2.6      private static native Object getAttr(String id, String attr);
     2.7 +    @JavaScriptBody(args = {"elem", "attr"}, body = 
     2.8 +        "return elem[attr].toString();")
     2.9 +    private static native Object getAttr(Object elem, String attr);
    2.10  
    2.11      @JavaScriptBody(args = {"id", "attr", "value"}, body = 
    2.12          "window.document.getElementById(id)[attr] = value;")
    2.13      private static native void setAttr(String id, String attr, Object value);
    2.14 +    @JavaScriptBody(args = {"elem", "attr", "value"}, body = 
    2.15 +        "elem[attr] = value;")
    2.16 +    private static native void setAttr(Object id, String attr, Object value);
    2.17      
    2.18      @JavaScriptBody(args = {}, body = "return; window.close();")
    2.19      private static native void closeWindow();
    2.20  
    2.21 +    private static Object textArea;
    2.22 +    private static Object statusArea;
    2.23 +    
    2.24      private static void log(String newText) {
    2.25 -        String id = "bck2brwsr.result";
    2.26 +        if (textArea == null) {
    2.27 +            return;
    2.28 +        }
    2.29          String attr = "value";
    2.30 -        setAttr(id, attr, getAttr(id, attr) + "\n" + newText);
    2.31 -        setAttr(id, "scrollTop", getAttr(id, "scrollHeight"));
    2.32 +        setAttr(textArea, attr, getAttr(textArea, attr) + "\n" + newText);
    2.33 +        setAttr(textArea, "scrollTop", getAttr(textArea, "scrollHeight"));
    2.34      }
    2.35      
    2.36 +    private static void beginTest(Case c) {
    2.37 +        Object[] arr = new Object[2];
    2.38 +        beginTest(c.getClassName() + "." + c.getMethodName(), c, arr);
    2.39 +        textArea = arr[0];
    2.40 +        statusArea = arr[1];
    2.41 +    }
    2.42 +    
    2.43 +    private static void finishTest(Case c, Object res) {
    2.44 +        if ("null".equals(res)) {
    2.45 +            setAttr(statusArea, "innerHTML", "OK");
    2.46 +            setAttr(statusArea, "href", null);
    2.47 +        } else {
    2.48 +            setAttr(statusArea, "innerHTML", "run again");
    2.49 +        }
    2.50 +        statusArea = null;
    2.51 +        textArea = null;
    2.52 +    }
    2.53 +
    2.54 +    @JavaScriptBody(args = { "test", "c", "arr" }, body = 
    2.55 +          "var ul = window.document.getElementById('bck2brwsr.result');\n"
    2.56 +        + "var li = window.document.createElement('li');\n"
    2.57 +        + "var span = window.document.createElement('span');\n"
    2.58 +        + "span.innerHTML = test + ' - ';\n"
    2.59 +        + "var p = window.document.createElement('p');\n"
    2.60 +        + "var status = window.document.createElement('a');\n"
    2.61 +        + "status.innerHTML = 'running';"
    2.62 +        + "status.href = '#';\n"
    2.63 +        + "status.onclick = function() { c.again__V_3Ljava_lang_Object_2(arr); }\n"
    2.64 +        + "var pre = window.document.createElement('textarea');\n"
    2.65 +        + "pre.width = '90%';"
    2.66 +        + "pre.height = 100;"
    2.67 +        + "li.appendChild(span);\n"
    2.68 +        + "li.appendChild(status);\n"
    2.69 +        + "li.appendChild(p);\n"
    2.70 +        + "p.appendChild(pre);\n"
    2.71 +        + "ul.appendChild(li);\n"
    2.72 +        + "arr[0] = pre;\n"
    2.73 +        + "arr[1] = status;\n"
    2.74 +    )
    2.75 +    private static native void beginTest(String test, Case c, Object[] arr);
    2.76 +    
    2.77      public static void execute() throws Exception {
    2.78          String clazz = (String) getAttr("clazz", "value");
    2.79          String method = (String) getAttr("method", "value");
    2.80 @@ -109,19 +161,9 @@
    2.81                  }
    2.82                  
    2.83                  Case c = Case.parseData(data);
    2.84 -                if (c.getHtmlFragment() != null) {
    2.85 -                    setAttr("bck2brwsr.fragment", "innerHTML", c.getHtmlFragment());
    2.86 -                }
    2.87 -                log("Invoking " + c.getClassName() + '.' + c.getMethodName() + " as request: " + c.getRequestId());
    2.88 -
    2.89 -                Object result = invokeMethod(c.getClassName(), c.getMethodName());
    2.90 -                
    2.91 -                setAttr("bck2brwsr.fragment", "innerHTML", "");
    2.92 -                log("Result: " + result);
    2.93 -                
    2.94 -                result = encodeURL("" + result);
    2.95 -                
    2.96 -                log("Sending back: " + url + "?request=" + c.getRequestId() + "&result=" + result);
    2.97 +                beginTest(c);
    2.98 +                Object result = c.runTest();
    2.99 +                finishTest(c, result);
   2.100                  String u = url + "?request=" + c.getRequestId() + "&result=" + result;
   2.101                  
   2.102                  loadText(u, this, arr);
   2.103 @@ -247,6 +289,30 @@
   2.104              return value("html", data);
   2.105          }
   2.106          
   2.107 +        void again(Object[] arr) {
   2.108 +            try {
   2.109 +                textArea = arr[0];
   2.110 +                statusArea = arr[1];
   2.111 +                setAttr(textArea, "value", "");
   2.112 +                runTest();
   2.113 +            } catch (Exception ex) {
   2.114 +                log(ex.getClass().getName() + ":" + ex.getMessage());
   2.115 +            }
   2.116 +        }
   2.117 +
   2.118 +        private Object runTest() throws IllegalAccessException, IllegalArgumentException, ClassNotFoundException, UnsupportedEncodingException, InvocationTargetException, InstantiationException, SecurityException {
   2.119 +            if (this.getHtmlFragment() != null) {
   2.120 +                setAttr("bck2brwsr.fragment", "innerHTML", this.getHtmlFragment());
   2.121 +            }
   2.122 +            log("Invoking " + this.getClassName() + '.' + this.getMethodName() + " as request: " + this.getRequestId());
   2.123 +            Object result = invokeMethod(this.getClassName(), this.getMethodName());
   2.124 +            setAttr("bck2brwsr.fragment", "innerHTML", "");
   2.125 +            log("Result: " + result);
   2.126 +            result = encodeURL("" + result);
   2.127 +            log("Sending back: ...?request=" + this.getRequestId() + "&result=" + result);
   2.128 +            return result;
   2.129 +        }
   2.130 +        
   2.131          @JavaScriptBody(args = "s", body = "return eval('(' + s + ')');")
   2.132          private static native Object toJSON(String s);
   2.133          
     3.1 --- a/rt/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/harness.xhtml	Tue Apr 02 15:49:42 2013 +0200
     3.2 +++ b/rt/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/harness.xhtml	Wed Apr 03 09:19:03 2013 +0200
     3.3 @@ -31,8 +31,8 @@
     3.4          
     3.5          <h1>Bck2Brwsr Execution Harness</h1>
     3.6          
     3.7 -        <textarea id="bck2brwsr.result" rows="25" style="width: 100%;" disabled="">
     3.8 -        </textarea>
     3.9 +        <ul id="bck2brwsr.result" style="width: 100%;" >
    3.10 +        </ul>
    3.11  
    3.12          <div id="bck2brwsr.fragment"/>
    3.13