2003/04/30 04:39:09
[org.ibex.core.git] / src / org / xwt / js / JS.java
1 // Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL]\r
2 \r
3 package org.xwt.js;\r
4 import org.xwt.util.*;\r
5 \r
6 /** all objects other than Strings and Numbers which are exposed to JS code must implement this interface */\r
7 public interface JS {\r
8 \r
9     public Object get(Object key) throws JS.Exn;\r
10     public Object put(Object key, Object val) throws JS.Exn;\r
11     public Object[] enumerateProperties();\r
12     public String coerceToString() throws JS.Exn;\r
13     public Num coerceToNumber() throws JS.Exn;\r
14     public Object call(Object[] args) throws JS.Exn;\r
15 \r
16     /** if JS calls a Java method, and the Java method throws an exception, it can only be caught by JS if it is a subclass of Exn. */\r
17     public static class Exn extends RuntimeException {\r
18         private Object js = null;\r
19         public Exn(Object js) { this.js = js; }\r
20         public Object getObject() { return js; }\r
21     }\r
22 \r
23     /** Any object which becomes part of the scope chain must support this interface */\r
24     public static interface Scope extends JS {\r
25         public boolean has(Object key);\r
26         public JS getParentScope();\r
27     }\r
28 \r
29     /** A mutable, boxed numeric value.  These are recycled -- never duplicate references -- use duplicate() instead. */\r
30     public static class Num implements Cloneable, JS {\r
31         \r
32         private Num() { }\r
33         \r
34         public boolean isDouble = false;\r
35         public long longVal = -1;\r
36         public double doubleVal = -1;\r
37         \r
38         private static Vec pool = new Vec();\r
39         public static synchronized void recycle(Num n) { pool.push(n); }\r
40         public static synchronized Num getOne() { return (pool.size() > 0) ? (Num)pool.pop() : new Num(); }\r
41         \r
42         public Num duplicate() { try { return (Num)clone(); } catch (CloneNotSupportedException c) { throw new Error(c); } }\r
43 \r
44         public Object get(Object key) throws JS.Exn { return null; }\r
45         public Object put(Object key, Object val) throws JS.Exn { throw new JS.Exn("attempt to set a property on a Number"); }\r
46         public Object[] enumerateProperties() { return new Object[] { }; }\r
47         public String coerceToString() throws JS.Exn { return isDouble ? String.valueOf(doubleVal) : String.valueOf(longVal); }\r
48         public Num coerceToNumber() throws JS.Exn { return duplicate(); }\r
49         public Object call(Object[] args) throws JS.Exn { throw new JS.Exn("attempt to apply the () operator to a Number"); }\r
50         \r
51     }\r
52 }\r