@@ -20,7 +20,15 @@ Handle<Value> WatchableNamedPropertyGetter(
2020 ) {
2121 HandleScope scope;
2222 // Grab the value of the property
23- Handle<Object> holder=info.Holder ();
23+ Handle<Object> holder = info.Holder ();
24+ Handle<Object> map = Handle<Object>::Cast (
25+ holder->GetInternalField (0 )
26+ );
27+ // Default
28+ Handle<Value> data = holder->GetInternalField (1 );
29+ if (data->IsNull ()) {
30+ return scope.Close (map->Get (property));
31+ }
2432 Handle<Value> value;
2533 Handle<Value> had_value;
2634
@@ -37,7 +45,6 @@ Handle<Value> WatchableNamedPropertyGetter(
3745 Handle<Value> values[3 ] = {property,value,had_value};
3846
3947 // Grab function and call (property,value)
40- Handle<Value> data = holder->GetInternalField (1 );
4148 Handle<Function> callback = Handle<Function>::Cast (data);
4249 Handle<Value> new_value = callback->Call (info.Holder (),3 ,values);
4350
@@ -52,7 +59,8 @@ Handle<Value> WatchableNamedPropertySetter(
5259 ) {
5360 HandleScope scope;
5461 // Grab the value of the property
55- Handle<Object> holder = Handle<Object>::Cast (
62+ Handle<Object> holder = info.Holder ();
63+ Handle<Object> map = Handle<Object>::Cast (
5664 holder->GetInternalField (0 )
5765 );
5866 Handle<Value> old_value;
@@ -66,14 +74,21 @@ Handle<Value> WatchableNamedPropertySetter(
6674 old_value = Undefined ();
6775 had_value = False ();
6876 }
77+ // Default
78+ Handle<Value> data = holder->GetInternalField (2 );
79+ if (data->IsNull ()) {
80+ return scope.Close (map->Set (property,value)
81+ ?value
82+ :old_value
83+ );
84+ }
6985
7086 // Set up arguments
7187 Handle<Value> values[4 ] = {property,old_value,value,had_value};
7288
7389 // Grab function and call (property,value)
74- Handle<Value> data = holder->GetInternalField (2 );
7590 Handle<Function> callback = Handle<Function>::Cast (data);
76- Handle<Value> new_value = callback->Call (Holder ,4 ,values);
91+ Handle<Value> new_value = callback->Call (holder ,4 ,values);
7792
7893 holder->ForceSet (property,new_value);
7994
@@ -86,26 +101,32 @@ Handle<Array> WatchableNamedPropertyEnumerator(
86101 ) {
87102 HandleScope scope;
88103 // Grab the value of the property
89- Handle<Object> holder = Handle<Object>::Cast (
104+ Handle<Object> holder = info.Holder ();
105+ Handle<Object> map = Handle<Object>::Cast (
90106 holder->GetInternalField (0 )
91107 );
108+ // Default
109+ Handle<Value> data = holder->GetInternalField (4 );
110+ if (data->IsNull ()) {
111+ return scope.Close (map->GetPropertyNames ());
112+ }
92113 Handle<Value> old_value;
93114 Handle<Value> had_value;
94115
95- Handle<Array> names = holder->GetPropertyNames ();
96-
97116 // Set up arguments
98- Handle<Value> values[4 ] = {property,old_value,value,had_value };
117+ Handle<Value> values[0 ] = {};
99118
100119 // Grab function and call (property,value)
101- Handle<Value> data = holder->GetInternalField (2 );
102120 Handle<Function> callback = Handle<Function>::Cast (data);
103- Handle<Value> new_value = callback->Call (holder,4 ,values);
104-
105- holder->ForceSet (property,new_value);
121+ Handle<Value> new_value = callback->Call (holder,0 ,values);
106122
107- // Return value is the return of the function call
108- return scope.Close (new_value);
123+ if (new_value->IsArray ()) {
124+ return scope.Close (Handle<Array>::Cast (new_value));
125+ }
126+ else {
127+ ThrowException (String::New (" Callback must return an Array." ));
128+ return scope.Close (Array::New ());
129+ }
109130}
110131
111132Handle<Value> WatchableIndexedPropertyGetter (
@@ -115,15 +136,21 @@ Handle<Value> WatchableIndexedPropertyGetter(
115136 HandleScope scope;
116137
117138 // Grab the value
118- Handle<Object> holder = Handle<Object>::Cast (
139+ Handle<Object> holder = info.Holder ();
140+ Handle<Object> map = Handle<Object>::Cast (
119141 holder->GetInternalField (0 )
120142 );
143+ // Default
144+ Handle<Value> data = holder->GetInternalField (1 );
145+ if (data->IsNull ()) {
146+ return scope.Close (map->Get (index));
147+ }
121148 Handle<Number> property = Number::New (index);
122149 Handle<Value> value;
123150 Handle<Value> had_value;
124151
125152 if ( holder->Has (index) ) {
126- value = holder ->Get (index);
153+ value = map ->Get (index);
127154 had_value = True ();
128155 }
129156 else {
@@ -134,7 +161,6 @@ Handle<Value> WatchableIndexedPropertyGetter(
134161 Handle<Value> values[3 ] = {property,value,had_value};
135162
136163 // Grab function and call (property,value)
137- Handle<Value> data = holder->GetInternalField (1 );
138164 Handle<Function> callback = Handle<Function>::Cast (data);
139165 Handle<Value> new_value = callback->Call (holder,3 ,values);
140166
@@ -148,82 +174,143 @@ Handle<Value> WatchableIndexedPropertySetter(
148174 , const AccessorInfo& info
149175 ) {
150176 HandleScope scope;
151-
152177 // Grab the value
153- Handle<Object> holder = Handle<Object>::Cast (
178+ Handle<Object> holder = info.Holder ();
179+ Handle<Object> map = Handle<Object>::Cast (
154180 holder->GetInternalField (0 )
155181 );
156182 Handle<Number> property = Number::New (index);
157183 Handle<Value> had_value;
158184
159185 Handle<Value> old_value;
160186 if ( holder->Has (index) ) {
161- old_value = holder ->Get (index);
187+ old_value = map ->Get (index);
162188 had_value = True ();
163189 }
164190 else {
165191 old_value = Undefined ();
166192 had_value = False ();
167193 }
168-
194+ // Default
195+ Handle<Value> data = holder->GetInternalField (2 );
196+ if (data->IsNull ()) {
197+ return scope.Close (map->Set (index,value)
198+ ?value
199+ :old_value
200+ );
201+ }
169202 // Set up arguments
170203 Handle<Value> values[4 ] = {property,old_value,value,had_value};
171204
172205 // Grab function and call (property,value)
173- Handle<Value> data = holder->GetInternalField (2 );
174206 Handle<Function> callback = Handle<Function>::Cast (data);
175207 Handle<Value> new_value = callback->Call (holder,4 ,values);
176208
177- holder ->Set (index,new_value);
209+ map ->Set (index,new_value);
178210
179211 // Return value is the return of the function call
180212 return scope.Close (new_value);
181213}
214+ Handle<Array> WatchableIndexedPropertyEnumerator (
215+ const AccessorInfo& info
216+ ) {
217+ HandleScope scope;
218+ // Grab the value
219+ Handle<Object> holder = info.Holder ();
220+ Handle<Object> map = Handle<Object>::Cast (
221+ holder->GetInternalField (0 )
222+ );
223+ // Default
224+ Handle<Value> data = holder->GetInternalField (2 );
225+ if (data->IsNull ()) {
226+ return scope.Close (map->GetPropertyNames ());
227+ }
228+ // Set up arguments
229+ Handle<Value> values[0 ];
230+
231+ // Grab function and call (property,value)
232+ Handle<Function> callback = Handle<Function>::Cast (data);
233+ Handle<Value> new_value = callback->Call (holder,0 ,values);
234+
235+ if (new_value->IsArray ()) {
236+ return scope.Close (Handle<Array>::Cast (new_value));
237+ }
238+ else {
239+ ThrowException (String::New (" Callback must return an Array." ));
240+ return scope.Close (Array::New ());
241+ }
242+ }
243+
182244
183- Local<ObjectTemplate> object_template = ObjectTemplate::New();
184245Handle<Value> Watchable (const Arguments& args) {
185246 HandleScope scope;
186- Handle<Value> getter = args[0 ];
187247 // Check our arguments!
188- if (getter.IsEmpty () || getter->IsFunction ()) {}
248+ Handle<Value> getter = args[0 ];
249+ if (getter->IsFunction ()) {
250+ // Do nothing
251+ }
252+ else if (getter->IsNull () || getter->IsUndefined ()) {
253+ getter = Null ();
254+ }
189255 else {
190256 return ThrowException (String::New (" Getter callback must be a function" ));
191257 }
192258 Handle<Value> setter = args[1 ];
193- if (setter.IsEmpty () || setter->IsFunction ()) {}
259+ if (setter->IsFunction ()) {
260+ // Do nothing
261+ }
262+ else if (setter->IsNull () || setter->IsUndefined ()) {
263+ setter = Null ();
264+ }
194265 else {
195266 return ThrowException (String::New (" Getter callback must be a function" ));
196267 }
197- Handle<Object> watchable = object_template->NewInstance ();
198- watchable->SetInternalField (0 ,Object::New ());
199- watchable->SetInternalField (1 ,getter);
200- watchable->SetInternalField (2 ,setter);
201- return scope.Close (watchable);
202- }
203-
204- extern " C" void init (Handle<Object> target)
205- {
206- HandleScope scope;
207- // Every one with a different callback needs a different template
208- // 0 - Holder object - aka the real one
209- // 1 - Getter
210- // 2 - Setter
211- // 3 - Query
212- // 4 - Deleter
213- // 5 - Enumerator
214- object_template->SetInternalFieldCount (5 );
268+ Handle<Value> enumerator = args[2 ];
269+ if (enumerator->IsFunction ()) {
270+ // Do nothing
271+ }
272+ else if (enumerator->IsNull () || enumerator->IsUndefined ()) {
273+ enumerator = Null ();
274+ }
275+ else {
276+ return ThrowException (String::New (" Getter callback must be a function" ));
277+ }
278+ Local<ObjectTemplate> object_template = ObjectTemplate::New ();
215279 object_template->SetNamedPropertyHandler (
216280 WatchableNamedPropertyGetter
217- ,WatchableNamedPropertySetter
281+ ,WatchableNamedPropertySetter, 0 , 0
218282// ,WatchableNamedPropertyQuery
219283// ,WatchableNamedPropertyDeleter
220284 ,WatchableNamedPropertyEnumerator
221285 );
222286 object_template->SetIndexedPropertyHandler (
223287 WatchableIndexedPropertyGetter
224288 ,WatchableIndexedPropertySetter
225- ,0 ,0 ,0
289+ ,0 ,0
290+ // Is this ever used?
291+ // ,WatchableIndexedPropertyEnumerator
226292 );
293+ // Every one with a different callback needs a different template
294+ // 0 - Holder object - aka the real one
295+ // 1 - Getter
296+ // 2 - Setter
297+ // 3 - Query
298+ // 4 - Deleter
299+ // 5 - Enumerator
300+ object_template->SetInternalFieldCount (5 );
301+ Handle<Object> watchable = object_template->NewInstance ();
302+ watchable->SetInternalField (0 ,Object::New ());
303+ watchable->SetInternalField (1 ,getter);
304+ watchable->SetInternalField (2 ,setter);
305+ watchable->SetInternalField (4 ,enumerator);
306+ // printf("watchable created\n");
307+ return scope.Close (watchable);
308+ }
309+
310+ extern " C" void init (Handle<Object> target)
311+ {
312+ HandleScope scope;
313+ // printf("init\n");
227314 Local<FunctionTemplate> watchable_template = FunctionTemplate::New (Watchable);
228315 Local<Function> watchable = watchable_template->GetFunction ();
229316 // Export
0 commit comments