1 28 29 package com.caucho.es; 30 31 import com.caucho.util.IntMap; 32 33 36 class NativeObject extends Native { 37 static final int TO_OBJECT = 2; 38 static final int TO_STRING = TO_OBJECT + 1; 39 static final int VALUE_OF = TO_STRING + 1; 40 static final int TO_SOURCE = VALUE_OF + 1; 41 static final int WATCH = TO_SOURCE + 1; 42 static final int UNWATCH = WATCH + 1; 43 44 47 private NativeObject(String name, int n, int len) 48 { 49 super(name, len); 50 51 this.n = n; 52 } 53 54 57 static ESObject create(Global resin) 58 { 59 Native nativeObj = new NativeObject("Object", TO_OBJECT, 1); 60 resin.objProto = new ESObject("Object", esBase); 61 62 NativeWrapper obj = new NativeWrapper(resin, nativeObj, 63 resin.objProto, ESThunk.OBJ_THUNK); 64 65 put(resin.objProto, "toString", TO_STRING, 0, DONT_ENUM); 66 put(resin.objProto, "valueOf", VALUE_OF, 0, DONT_ENUM); 67 68 put(resin.objProto, "toSource", TO_SOURCE, 0, DONT_ENUM); 69 put(resin.objProto, "watch", WATCH, 0, DONT_ENUM); 70 put(resin.objProto, "unwatch", UNWATCH, 0, DONT_ENUM); 71 72 resin.objProto.setClean(); 73 obj.setClean(); 74 75 return obj; 76 } 77 78 private static void put(ESObject obj, String name, int n, int len, 79 int flags) 80 { 81 ESId id = ESId.intern(name); 82 NativeObject fun = new NativeObject(name, n, len); 83 84 try { 85 obj.put(id, fun, flags); 86 } catch (Exception e) { 87 throw new RuntimeException (); 88 } 89 } 90 91 public ESBase call(Call eval, int length) throws Throwable 92 { 93 switch (n) { 94 case TO_STRING: 96 ESBase arg = eval.getArg(-1); 98 99 if (arg instanceof ESObject) 100 return toString((ESObject) arg); 101 else 102 return toString(arg.toObject()); 103 104 case VALUE_OF: 105 arg = eval.getArg(-1); 106 if (arg instanceof ESWrapper) { 107 ESWrapper obj = (ESWrapper) arg; 108 109 if (obj.value instanceof ESBase) 110 return (ESBase) obj.value; 111 else 112 return obj.toStr(); 113 } 114 return arg; 115 116 case TO_OBJECT: 117 if (length <= 0 || 118 (arg = eval.getArg(0)) == ESBase.esNull || 119 arg == ESBase.esUndefined || 120 arg == ESBase.esEmpty) 121 return Global.getGlobalProto().createObject(); 122 123 else if (length > 1) 124 return createObjectLiteral(eval, length); 125 126 else 127 return arg.toObject(); 128 129 case TO_SOURCE: 130 arg = eval.getThis(); 131 Global.getGlobalProto().clearMark(); 132 IntMap map = new IntMap(); 133 134 arg.toSource(map, true); 135 return arg.toSource(map, false); 136 137 case WATCH: 138 if (length < 2) 139 throw new ESException("watch expects two arguments"); 140 141 ESBase obj = eval.getThis(); 142 143 ESString key = eval.getArg(0).toStr(); 144 ESBase fun = eval.getArg(1); 145 if (! (fun instanceof ESClosure) && ! (fun instanceof Native)) 146 throw new ESException("watch requires function"); 147 148 ((ESObject) obj).watch(key, fun); 149 150 return esUndefined; 151 152 case UNWATCH: 153 if (length < 1) 154 throw new ESException("unwatch expects one argument"); 155 156 obj = eval.getThis(); 157 158 key = eval.getArg(0).toStr(); 159 160 ((ESObject) obj).unwatch(key); 161 162 return esUndefined; 163 164 default: 165 throw new RuntimeException ("Unknown object function"); 166 } 167 } 168 169 public ESBase construct(Call eval, int length) throws Throwable 170 { 171 if (n != TO_OBJECT) 172 return super.construct(eval, length); 173 174 if (length == 0 || eval.getArg(0) == esNull || 175 eval.getArg(0) == esUndefined || eval.getArg(0) == esEmpty) { 176 return Global.getGlobalProto().createObject(); 177 } 178 if (length > 1) { 179 return createObjectLiteral(eval, length); 180 } 181 182 return eval.getArg(0).toObject(); 183 } 184 185 private ESBase createObjectLiteral(Call call, int length) 186 throws Throwable 187 { 188 ESObject obj = Global.getGlobalProto().createObject(); 189 190 for (int i = 0; i + 1 < length; i += 2) { 191 ESString key = call.getArg(i, length).toStr(); 192 ESBase value = call.getArg(i + 1, length); 193 194 obj.setProperty(key, value); 195 } 196 197 return obj; 198 } 199 200 static public ESBase toString(ESObject obj) throws ESException 201 { 202 return ESString.create("[object " + obj.getClassName() + "]"); 203 } 204 } 205 | Popular Tags |