Revision: 3931 http://vexi.svn.sourceforge.net/vexi/?rev=3931&view=rev Author: mkpg2 Date: 2010-10-20 23:50:18 +0000 (Wed, 20 Oct 2010)
Log Message: ----------- Fix. Check for cycles in json marshaller. Modified Paths: -------------- trunk/org.vexi-library.js/src/main/java/org/ibex/js/JSON.java trunk/org.vexi-library.js/src/main/java/org/ibex/js/Scheduler.java Modified: trunk/org.vexi-library.js/src/main/java/org/ibex/js/JSON.java =================================================================== --- trunk/org.vexi-library.js/src/main/java/org/ibex/js/JSON.java 2010-10-20 14:41:12 UTC (rev 3930) +++ trunk/org.vexi-library.js/src/main/java/org/ibex/js/JSON.java 2010-10-20 23:50:18 UTC (rev 3931) @@ -1,54 +1,83 @@ package org.ibex.js; +import java.util.HashSet; +import java.util.Set; + +import org.ibex.js.JS.Trap; +import org.ibex.js.JS.TrapHolder; + public class JSON implements Constants { static public JS marshal(JS value) throws JSExn{ try { StringBuffer sb=new StringBuffer(); - marshal(sb,value); + Set avoidCycles = new HashSet(10); + marshal(sb,avoidCycles,value); return JSU.S(sb.toString()); } catch(java.lang.StackOverflowError soe) { throw new JSExn("stack overflow - probable attempt to stringify with recursive references"); } } - static public void marshal(StringBuffer sb, JS value) throws JSExn{ - + static void marshal(StringBuffer sb, Set avoidCycles, JS value) throws JSExn{ if(value==null){ sb.append("null"); return; } - JS type = value.type(); - if(type == SC_object || type == SC_exception){ - sb.append("{"); - JS.Enumeration ks = value.keys().iterator(); - while(ks.hasNext()){ - JS key = ks.next(); + if(avoidCycles.contains(value)){ + sb.append("<cycle>"); + } + + avoidCycles.add(value); + try{ + + JS type = value.type(); + if(type == SC_object || type == SC_exception){ + sb.append("{"); + JS.Enumeration ks = value.keys().iterator(); + while(ks.hasNext()){ + JS key = ks.next(); + sb.append("\""); + sb.append(escape(key)); + sb.append("\":"); + Scheduler sched = Scheduler.getCurrent(); + if(sched==null){ + // not in an executable context, so cannot serialize completely, return trap locations + Trap t = value.getTrap(key); + if (t != null && (t=t.findRead()) != null) { + for(; t!=null; t=t.findRead()){ + TrapHolder th = (TrapHolder)t; + sb.append(JSU.toString(th.function())); + sb.append("<-"); + } + } + } + marshal(sb, avoidCycles, sched.getAndTriggerTraps(value, key)); + if(ks.hasNext())sb.append(","); + } + sb.append("}"); + } + else if(type == SC_array){ + sb.append("["); + JS[] arr = ((JSArrayLike)value).toArray(); + if(arr.length>0) marshal(sb,avoidCycles,arr[0]); + for(int i=1; i<arr.length; i++){ + sb.append(","); + marshal(sb,avoidCycles,arr[i]); + } + sb.append("]"); + } + else if(type == SC_number || type == SC_boolean){ + sb.append(value.coerceToString()); + } + else{ sb.append("\""); - sb.append(escape(key)); - sb.append("\":"); - marshal(sb,Scheduler.getAndTriggerTrapsNoScheduler(value,key)); - if(ks.hasNext())sb.append(","); + sb.append(escape(value)); + sb.append("\""); } - sb.append("}"); + + }finally{ + avoidCycles.remove(value); } - else if(type == SC_array){ - sb.append("["); - JS[] arr = ((JSArrayLike)value).toArray(); - if(arr.length>0) marshal(sb,arr[0]); - for(int i=1; i<arr.length; i++){ - sb.append(","); - marshal(sb,arr[i]); - } - sb.append("]"); - } - else if(type == SC_number || type == SC_boolean){ - sb.append(value.coerceToString()); - } - else{ - sb.append("\""); - sb.append(escape(value)); - sb.append("\""); - } } /** Modified: trunk/org.vexi-library.js/src/main/java/org/ibex/js/Scheduler.java =================================================================== --- trunk/org.vexi-library.js/src/main/java/org/ibex/js/Scheduler.java 2010-10-20 14:41:12 UTC (rev 3930) +++ trunk/org.vexi-library.js/src/main/java/org/ibex/js/Scheduler.java 2010-10-20 23:50:18 UTC (rev 3931) @@ -343,11 +343,7 @@ /** Gets the value for a given key, triggering any read traps for the key. */ static public JS getAndTriggerTrapsNoScheduler(JS obj, JS key) throws JSExn { - Trap t = obj.getTrap(key); - if (t == null || (t = t.findRead()) == null) { - return (JS)obj.get(key); - } - return Scheduler.findCurrent().runInCurrent(t); + return Scheduler.findCurrent().getAndTriggerTraps(obj,key); } /** Simulates a put to the given key, triggering any write traps for the key This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Nokia and AT&T present the 2010 Calling All Innovators-North America contest Create new apps & games for the Nokia N8 for consumers in U.S. and Canada $10 million total in prizes - $4M cash, 500 devices, nearly $6M in marketing Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store http://p.sf.net/sfu/nokia-dev2dev _______________________________________________ Vexi-svn mailing list Vexi-svn@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/vexi-svn