Revision: 3592
          http://vexi.svn.sourceforge.net/vexi/?rev=3592&view=rev
Author:   clrg
Date:     2009-08-10 10:30:56 +0000 (Mon, 10 Aug 2009)

Log Message:
-----------
Catch a StackOverflowError generated by cyclic apply processes

Modified Paths:
--------------
    trunk/core/org.vexi.core/src/org/vexi/core/Blessing.java

Modified: trunk/core/org.vexi.core/src/org/vexi/core/Blessing.java
===================================================================
--- trunk/core/org.vexi.core/src/org/vexi/core/Blessing.java    2009-08-10 
10:19:18 UTC (rev 3591)
+++ trunk/core/org.vexi.core/src/org/vexi/core/Blessing.java    2009-08-10 
10:30:56 UTC (rev 3592)
@@ -6,11 +6,11 @@
 import org.ibex.js.*;
 
 public class Blessing extends JS.Clone implements Constants {
-       
-       static final String[] EXTS_IMAGES = new String[] { ".png", ".jpeg", 
".gif", ".jpg" };
-       static final String[] EXTS_TTF = new String[] { ".ttf"};
-       
-       
+    
+    static final String[] EXTS_IMAGES = new String[] { ".png", ".jpeg", 
".gif", ".jpg" };
+    static final String[] EXTS_TTF = new String[] { ".ttf"};
+    
+    
     private JS vexi;
     private Template t = null;
     public JS parentkey = null;
@@ -18,7 +18,7 @@
     public Blessing parent = null;
 
     //OPTIMIZE - use our own hash map
-       private HashMap cache = new HashMap(16);  
+    private HashMap cache = new HashMap(16);  
     boolean initializing = false;
     Blessing(JS clonee, JS vexi, Blessing parent, JS parentkey) throws JSExn {
         super(clonee);
@@ -33,30 +33,30 @@
     }
 
     public JS getAndTriggerTraps(JS key) throws JSExn {
-       Trap t = super.getTrap(key);
-       // REMARK - We're not like Clone here, we don't check the clonee's traps
-       // (since we do it in the get method)
+        Trap t = super.getTrap(key);
+        // REMARK - We're not like Clone here, we don't check the clonee's 
traps
+        // (since we do it in the get method)
         if(t==null || (t = t.findRead())==null) return get(key);
         return Main.SCHEDULER.runInCurrent(t);
     }
     
     public JS get(JS key) throws JSExn {
-       // FEATURE - do we need to resolve here? We can resolve later perhaps, 
so
-       // if you refer to a template but don't use it then it won't get 
resolved?
+        // FEATURE - do we need to resolve here? We can resolve later perhaps, 
so
+        // if you refer to a template but don't use it then it won't get 
resolved?
         if (SC_.equals(key))
-               return getStatic();
+            return getStatic();
         if (cache.get(key) != null)
-               return (JS)cache.get(key);
+            return (JS)cache.get(key);
         String key_ = JSU.toString(key);
         // x.t is equivalent to x
-        if(key_.endsWith(".t")){
-               key_ = key_.substring(0,key_.length()-2);
-               JS origKey = key;
-               key = JSU.S(key_);
-            if (cache.get(key) != null){
-               JS ret = (JS)cache.get(key);
-               cache.put(origKey, ret);
-               return ret;
+        if (key_.endsWith(".t")) {
+            key_ = key_.substring(0,key_.length()-2);
+            JS origKey = key;
+            key = JSU.S(key_);
+            if (cache.get(key) != null) {
+                JS ret = (JS)cache.get(key);
+                cache.put(origKey, ret);
+                return ret;
             }
         }
         // REMARK - calling getAndTriggerTraps in a plain get?
@@ -71,15 +71,15 @@
     }
     
     public void addTrap(JS key, JS f) throws JSExn {
-               // FIXME - this is not sufficient. However it will work for the 
common
-       // case where the trap always returns the same value (i.e. an override)
-       // Actually if the JS added is a function read trap then the correct
-       // behaviour would be to disable the cache for that value.
-               // 
-       // Adding a read trap -> Cache is dirty -> Remove item from cache.
-               if(f.getFormalArgs().length == 0)
-               cache.remove(key);
-       super.addTrap(key, f);
+        // FIXME - this is not sufficient. However it will work for the common
+        // case where the trap always returns the same value (i.e. an override)
+        // Actually if the JS added is a function read trap then the correct
+        // behaviour would be to disable the cache for that value.
+        // 
+        // Adding a read trap -> Cache is dirty -> Remove item from cache.
+        if (f.getFormalArgs().length == 0)
+            cache.remove(key);
+        super.addTrap(key, f);
     }
     
     private InputStream getForExtensions(String[] exts) throws JSExn{
@@ -89,7 +89,7 @@
         } catch (Exception e) { /* DELIBERATE */ }
         for (int i=0; i < exts.length; i++) {
             try {
-               JS o = parent.get(JSU.S(JSU.toString(parentkey) + exts[i]));
+                JS o = parent.get(JSU.S(JSU.toString(parentkey) + exts[i]));
                 InputStream in = JSU.getInputStream(o);
                 if (in != null) return in;
             } catch (Exception f) { /* DELIBERATE */ }
@@ -101,34 +101,33 @@
     
     // FEATURE: This is a gross hack
     public InputStream getImage() throws JSExn {
-       return getForExtensions(EXTS_IMAGES);
+        return getForExtensions(EXTS_IMAGES);
     }
     
     // FEATURE: Also a gross hack
     public InputStream getTtf() throws JSExn {
-       return getForExtensions(EXTS_TTF);
+        return getForExtensions(EXTS_TTF);
     }
     
-    private void resolve(Template unresolved) throws JSExn{
-       // Otherwise we recurse infinitely.
-               if(initializing)
-                       throw new JSExn("Accessing template during its own 
initialization");
-               initializing = true;
+    private void resolve(Template unresolved) throws JSExn {
+          // Otherwise we recurse infinitely.
+           if (initializing)
+               throw new JSExn("Accessing template during its own 
initialization");
+           initializing = true;
         // FEATURE: Might want to handle the ".t" part better
-        try{
-               JS res = (parent==null)?
-                       this:parent.getTemplateRes(parentkey);
-               unresolved.staticPart.sourceName = description();
-               t = TemplateBuilder.build(unresolved, res);
-        }finally{
-               initializing = false;
+        try {
+            JS res = (parent==null) ? this : parent.getTemplateRes(parentkey);
+            unresolved.staticPart.sourceName = description();
+            t = TemplateBuilder.build(unresolved, res);
+        } finally {
+            initializing = false;
         }
     }
     
-    private JS getTemplateRes(JS key) throws JSExn{
-       String key_ = JSU.toString(key);
-       if(!key_.endsWith(".t")) key = JSU.S(key_ + ".t");
-       return JSU.unclone(clonee).getAndTriggerTraps(key);
+    private JS getTemplateRes(JS key) throws JSExn {
+        String key_ = JSU.toString(key);
+        if(!key_.endsWith(".t")) key = JSU.S(key_ + ".t");
+        return JSU.unclone(clonee).getAndTriggerTraps(key);
     }
     
     JS getStatic() throws JSExn {
@@ -137,59 +136,63 @@
     }
     
     private String description() {
-       if(parent==null) return JSU.toString(name);
+        if (parent==null) return JSU.toString(name);
         String s = JSU.toString(parentkey);
-        for(Blessing b = parent; b!=null && b.parentkey != null; b = b.parent)
-               s = JSU.toString(b.parentkey) + "." + s;
+        for (Blessing b = parent; b!=null && b.parentkey != null; b = b.parent)
+            s = JSU.toString(b.parentkey) + "." + s;
         return s;
     }
-    public int callType(){ return CALLTYPE_APPLY; }
-    private Template getTemplate() throws JSExn{
-       // Ensure template is created by creating the static part.
-       getStatic();
-       if (t == null) throw new JSExn("No such template '"+description()+"'");
-       return t;
+    public int callType() { return CALLTYPE_APPLY; }
+    private Template getTemplate() throws JSExn {
+        // Ensure template is created by creating the static part.
+        getStatic();
+        if (t == null) throw new JSExn("No such template '"+description()+"'");
+        return t;
     }
     
     public JS new_(JS[] args) throws JSExn {
-       return apply_(null,args);
+        return apply_(null,args);
     }
     
     public JS apply(JS this_, JS[] args) throws JSExn {
-       if(this_==null) throw new JSExn("Attempt to apply "+this+" to a null 
object");
-       return apply_(this_, args);
+        if (this_==null) throw new JSExn("Attempt to apply "+this+" to a null 
object");
+        return apply_(this_, args);
     }
     
     private JS apply_(JS this_, JS[] args) throws JSExn {
         Template template = getTemplate();
-       return template.apply(this_,args);
+        try {
+            return template.apply(this_,args);
+        } catch (java.lang.StackOverflowError soe) {
+            throw new JSExn("Encountered likely cyclic apply during: 
"+description());
+        }
     }
     
     // FEATURE: This is a gross hack
     //Template getTemplate() throws JSExn { ...
     // COROLLARY: this must also be then ...
     Template initTemplate(Template unresolved) throws JSExn {
-       if (t == null) resolve(unresolved);
+        if (t == null) resolve(unresolved);
         if (t == null) throw new JSExn("No such template '"+description()+"'");
         return t;
     }
  
     public String coerceToString() {
-       return description()+"$"+Integer.toHexString(hashCode());
+        return description()+"$"+Integer.toHexString(hashCode());
     }
     public JS type() { return SC_stream; }
     
     public Keys keys() throws JSExn {
-       return clonee.keys();
-    }  
+        return clonee.keys();
+    }    
     
     // Useful when debugging
-    public String toString(){
-       return coerceToString();
+    public String toString() {
+        return coerceToString();
     }
     
     public JS unclone() {
-       // TODO Auto-generated method stub
-       return super.unclone();
+        // TODO Auto-generated method stub
+        return super.unclone();
     }
 }


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Vexi-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/vexi-svn

Reply via email to