OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 10 matching lines...) Expand all Loading... | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 #include "config.h" | 30 #include "config.h" |
31 #include "DartNode.h" | |
31 #include "bindings/dart/DartHandleProxy.h" | 32 #include "bindings/dart/DartHandleProxy.h" |
32 | |
33 #include "bindings/dart/DartScriptValue.h" | 33 #include "bindings/dart/DartScriptValue.h" |
34 #include "bindings/dart/DartUtilities.h" | 34 #include "bindings/dart/DartUtilities.h" |
35 #include "bindings/dart/V8Converter.h" | 35 #include "bindings/dart/V8Converter.h" |
36 #include "bindings/v8/PageScriptDebugServer.h" | |
37 #include "bindings/v8/ScriptController.h" | |
38 #include "bindings/v8/ScriptState.h" | |
39 #include "bindings/v8/V8Binding.h" | |
40 | |
41 #include "core/platform/Logging.h" | |
42 | |
43 #include "wtf/StdLibExtras.h" | |
36 | 44 |
37 #include <dart_debugger_api.h> | 45 #include <dart_debugger_api.h> |
38 | 46 |
39 namespace WebCore { | 47 namespace WebCore { |
40 | 48 |
41 static v8::Persistent<v8::FunctionTemplate> proxyTemplate(); | 49 typedef HashMap<String, v8::Persistent<v8::FunctionTemplate> > FunctionTemplateM ap; |
42 | 50 |
43 static DartScriptValue* readPointerFromProxy(v8::Handle<v8::Value> proxy) | 51 static v8::Persistent<v8::FunctionTemplate> objectProxyTemplate(Dart_Handle inst ance); |
52 static v8::Persistent<v8::FunctionTemplate> functionProxyTemplate(); | |
53 static v8::Persistent<v8::FunctionTemplate> libraryProxyTemplate(); | |
54 static v8::Persistent<v8::FunctionTemplate> classProxyTemplate(Dart_Handle clazz ); | |
55 static v8::Persistent<v8::FunctionTemplate> frameProxyTemplate(); | |
56 | |
57 DartScriptValue* readPointerFromProxy(v8::Handle<v8::Value> proxy) | |
44 { | 58 { |
45 void* pointer = proxy.As<v8::Object>()->GetAlignedPointerFromInternalField(0 ); | 59 void* pointer = proxy.As<v8::Object>()->GetAlignedPointerFromInternalField(0 ); |
46 return static_cast<DartScriptValue*>(pointer); | 60 return static_cast<DartScriptValue*>(pointer); |
47 } | 61 } |
48 | 62 |
49 static void weakCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* proxy , void*) | 63 static void weakCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* proxy , void*) |
50 { | 64 { |
51 delete readPointerFromProxy(*proxy); | 65 delete readPointerFromProxy(*proxy); |
52 proxy->Dispose(isolate); | 66 proxy->Dispose(isolate); |
53 } | 67 } |
54 | 68 |
69 static Dart_Handle unwrapValue(v8::Handle<v8::Value> value) | |
70 { | |
71 if (DartHandleProxy::isDartProxy(value)) { | |
72 return Dart_HandleFromPersistent(readPointerFromProxy(value)->value()); | |
73 } | |
74 Dart_Handle exception = 0; | |
75 Dart_Handle handle = V8Converter::toDart(value, exception); | |
76 ASSERT(!exception); | |
77 return handle; | |
78 } | |
79 | |
80 bool libraryHasMember(Dart_Handle library, Dart_Handle name) | |
Jacob
2013/07/11 18:52:27
Requested Dart API:
"LibraryHasMember" or somethin
| |
81 { | |
82 return !Dart_IsError(Dart_GetField(library, name)) | |
83 || !Dart_IsError(Dart_GetClass(library, name)) | |
84 || Dart_IsFunction(Dart_LookupFunction(library, name)); | |
85 } | |
86 | |
87 bool classHasMember(Dart_Handle clazz, Dart_Handle name) | |
88 { | |
Jacob
2013/07/11 18:52:27
Requested Dart Api:
"ClassHasMember"
would be nice
| |
89 return !Dart_IsError(Dart_GetField(clazz, name)) || Dart_IsFunction(Dart_Loo kupFunction(clazz, name)); | |
90 } | |
91 | |
92 Dart_Handle getEncodedMapKeyList(Dart_Handle object) | |
93 { | |
94 return DartUtilities::invokeUtilsMethod("getEncodedMapKeyList", 1, &object); | |
95 } | |
96 | |
97 Dart_Handle stripTrailingDot(Dart_Handle str) | |
98 { | |
99 return DartUtilities::invokeUtilsMethod("stripTrailingDot", 1, &str); | |
100 } | |
101 | |
102 Dart_Handle addTrailingDot(Dart_Handle str) | |
103 { | |
104 return DartUtilities::invokeUtilsMethod("addTrailingDot", 1, &str); | |
105 } | |
106 | |
107 Dart_Handle lookupValueForEncodedMapKey(Dart_Handle object, Dart_Handle key) | |
108 { | |
109 Dart_Handle args[] = {object, key}; | |
110 return DartUtilities::invokeUtilsMethod("lookupValueForEncodedMapKey", 2, ar gs); | |
111 } | |
112 | |
113 Dart_Handle buildConstructorName(Dart_Handle className, Dart_Handle constructorN ame) | |
114 { | |
115 Dart_Handle args[] = {className, constructorName}; | |
116 return DartUtilities::invokeUtilsMethod("buildConstructorName", 2, args); | |
117 } | |
118 | |
119 Dart_Handle stripClassName(Dart_Handle str, Dart_Handle className) | |
120 { | |
121 Dart_Handle args[] = {str, className}; | |
122 return DartUtilities::invokeUtilsMethod("stripClassName", 2, args); | |
123 } | |
124 | |
125 Dart_Handle isNode(Dart_Handle clazz) | |
126 { | |
127 return DartUtilities::invokeUtilsMethod("isNode", 1, &clazz); | |
128 } | |
129 | |
130 void addFunctionNames(Dart_Handle handle, v8::Local<v8::Array>& properties, intp tr_t* count, bool isInstance, bool noMethods) | |
131 { | |
132 intptr_t length = 0; | |
133 Dart_Handle functionNames = Dart_GetFunctionNames(handle); | |
134 ASSERT(!Dart_IsError(functionNames)); | |
135 bool isLibrary = Dart_IsLibrary(handle); | |
136 Dart_ListLength(functionNames, &length); | |
137 for (intptr_t i = 0; i < length; i++) { | |
138 Dart_Handle functionName = Dart_ListGetAt(functionNames, i); | |
139 Dart_Handle function = Dart_LookupFunction(handle, functionName); | |
140 bool isStatic = false; | |
141 Dart_FunctionIsStatic(function, &isStatic); | |
142 | |
143 bool isConstructor = false; | |
144 Dart_FunctionIsConstructor(function, &isConstructor); | |
145 | |
146 if (!isLibrary) { | |
147 if (isInstance && (isStatic || isConstructor)) | |
148 continue; | |
149 | |
150 bool isSetter = false; | |
151 Dart_FunctionIsSetter(function, &isSetter); | |
152 bool isGetter = false; | |
153 Dart_FunctionIsGetter(function, &isGetter); | |
154 | |
155 if (noMethods && !isSetter && !isGetter) | |
156 continue; | |
157 | |
158 if (isInstance && (isSetter || isStatic || isConstructor)) | |
159 continue; | |
160 } | |
161 | |
162 // Strip off the leading classname from constructor name. | |
163 if (isConstructor) | |
Jacob
2013/07/11 18:52:27
Nit: why are constructor names prefixed with the c
| |
164 functionName = stripClassName(functionName, Dart_ClassName(handle)); | |
165 | |
166 properties->Set(*count, V8Converter::stringToV8(functionName)); | |
167 *count = *count + 1; | |
168 } | |
169 } | |
170 | |
171 void addClassNames(Dart_Handle library, v8::Local<v8::Array>& properties, intptr _t* count) | |
172 { | |
173 intptr_t length = 0; | |
174 Dart_Handle classNames = Dart_LibraryGetClassNames(library); | |
175 ASSERT(!Dart_IsNull(classNames)); | |
176 ASSERT(Dart_IsList(classNames)); | |
177 Dart_ListLength(classNames, &length); | |
178 for (intptr_t i = 0; i < length; i++) { | |
179 Dart_Handle className = Dart_ListGetAt(classNames, i); | |
180 properties->Set(*count, V8Converter::stringToV8(className)); | |
181 *count = *count + 1; | |
182 } | |
183 } | |
184 | |
185 void addFieldNames(intptr_t libraryId, v8::Local<v8::Array>& properties, intptr_ t* count) | |
186 { | |
187 intptr_t length = 0; | |
188 Dart_Handle fieldNames = Dart_GetLibraryFields(libraryId); | |
189 ASSERT(!Dart_IsNull(fieldNames)); | |
190 ASSERT(Dart_IsList(fieldNames)); | |
191 Dart_ListLength(fieldNames, &length); | |
192 for (intptr_t i = 0; i < length; i+=2) { | |
193 Dart_Handle fieldName = Dart_ListGetAt(fieldNames, i); | |
194 properties->Set(*count, V8Converter::stringToV8(fieldName)); | |
195 *count = *count + 1; | |
196 } | |
197 } | |
198 | |
199 static v8::Handle<v8::Value> convertResult(Dart_Handle result) | |
200 { | |
201 if (Dart_IsError(result)) { | |
202 // FIXME: we would really prefer to call the following however it has | |
203 // bad unintended consequences as then JS cannot catch the thrown except ion. | |
204 // DartUtilities::reportProblem(DartUtilities::scriptExecutionContext(), result); | |
205 // return v8::Undefined(); | |
206 | |
207 return v8::ThrowException(v8::String::New(Dart_GetError(result))); | |
208 } | |
209 return DartHandleProxy::create(result); | |
210 } | |
211 | |
212 void setDartHandleInternalField(v8::Local<v8::Object> proxy, Dart_Handle value) | |
213 { | |
214 proxy->SetAlignedPointerInInternalField(0, new DartScriptValue(value)); | |
215 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | |
216 v8::Persistent<v8::Object> persistentHandle = v8::Persistent<v8::Object>::Ne w(isolate, proxy); | |
217 persistentHandle.MakeWeak<v8::Object, void>(0, &weakCallback); | |
218 } | |
219 | |
220 intptr_t getLibraryId(v8::Local<v8::Object> proxy) | |
221 { | |
222 return (intptr_t)proxy.As<v8::Object>()->GetHiddenValue(v8::String::NewSymbo l("libraryId"))->Int32Value(); | |
223 } | |
224 | |
225 // Returns a String of the library prefix or Dart_Null if no prefix is found. | |
226 Dart_Handle getLibraryPrefix(v8::Local<v8::Object> proxy) | |
227 { | |
228 v8::Local<v8::Value> prefix = proxy.As<v8::Object>()->GetHiddenValue(v8::Str ing::NewSymbol("prefix")); | |
229 if (*prefix && prefix->IsString()) | |
230 return V8Converter::stringToDart(prefix); | |
231 return Dart_Null(); | |
232 } | |
233 | |
234 static v8::Handle<v8::Value> functionNamedPropertyGetter(v8::Local<v8::String> n ame, const v8::AccessorInfo& info) | |
235 { | |
236 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
237 ASSERT(scriptValue->isIsolateAlive()); | |
238 DartIsolateScope scope(scriptValue->isolate()); | |
239 DartApiScope apiScope; | |
240 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
241 | |
242 Dart_Handle ret; | |
243 ASSERT(Dart_IsFunction(handle) || Dart_IsClosure(handle)); | |
244 | |
245 ret = Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::S tring::New("get:"), name)), 0, 0); | |
Jacob
2013/07/11 18:52:27
For classes, I can just call
Dart_Invoke with the
| |
246 if (Dart_IsError(ret) && name->Equals(v8::String::NewSymbol("__proto__"))) | |
247 return v8::Undefined(); | |
248 | |
249 return convertResult(ret); | |
250 } | |
251 | |
252 static v8::Handle<v8::Value> functionNamedPropertySetter(v8::Local<v8::String> p roperty, v8::Local<v8::Value> value, const v8::AccessorInfo& info) | |
253 { | |
254 return throwError(v8ReferenceError, "Dart functions do not have writeable pr operties", v8::Isolate::GetCurrent()); | |
255 } | |
256 | |
257 static v8::Handle<v8::Value> functionInvocationCallback(v8::Arguments const& arg s) | |
258 { | |
259 DartScriptValue* scriptValue = readPointerFromProxy(args.Holder()); | |
260 ASSERT(scriptValue->isIsolateAlive()); | |
261 DartIsolateScope scope(scriptValue->isolate()); | |
262 DartApiScope apiScope; | |
263 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
264 | |
265 ASSERT(Dart_IsFunction(handle) || Dart_IsClosure(handle)); | |
266 bool isConstructor = false; | |
267 Dart_FunctionIsConstructor(handle, &isConstructor); | |
268 if (args.IsConstructCall() != isConstructor) { | |
269 return throwError(v8ReferenceError, | |
270 isConstructor ? "Constructor called without new" : "Regular function called as constructor", | |
271 v8::Isolate::GetCurrent()); | |
272 } | |
273 | |
274 Vector<Dart_Handle> dartFunctionArgs; | |
275 for (uint32_t i = 0; i < args.Length(); ++i) | |
276 dartFunctionArgs.append(unwrapValue(args[i])); | |
277 | |
278 if (Dart_IsClosure(handle)) | |
279 return convertResult(Dart_InvokeClosure(handle, dartFunctionArgs.size(), dartFunctionArgs.data())); | |
280 Dart_Handle clazz = Dart_FunctionOwner(handle); | |
281 if (isConstructor) | |
282 // FIXME: this seems like an overly complex way to have to invoke a cons tructor. | |
Jacob
2013/07/11 18:52:27
nit: this seems more complex than needed.
| |
283 return convertResult( | |
284 Dart_New(clazz, stripClassName(Dart_FunctionName(handle), Dart_Class Name(clazz)), | |
285 dartFunctionArgs.size(), dartFunctionArgs.data())); | |
286 else | |
287 return convertResult( | |
288 Dart_Invoke(clazz, Dart_FunctionName(handle), dartFunctionArgs.size( ), dartFunctionArgs.data())); | |
289 } | |
290 | |
291 static v8::Handle<v8::Value> classProxyConstructorInvocationCallback(v8::Argumen ts const& args) | |
292 { | |
293 DartScriptValue* scriptValue = readPointerFromProxy(args.Holder()); | |
294 ASSERT(scriptValue->isIsolateAlive()); | |
295 DartIsolateScope scope(scriptValue->isolate()); | |
296 DartApiScope apiScope; | |
297 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
298 | |
299 ASSERT(Dart_IsClass(handle)); | |
300 | |
301 if (!args.IsConstructCall()) | |
302 return throwError(v8SyntaxError, "Constructors can only be invoked with 'new'", v8::Isolate::GetCurrent()); | |
303 | |
304 Vector<Dart_Handle> dartFunctionArgs; | |
305 for (uint32_t i = 0; i < args.Length(); ++i) | |
306 dartFunctionArgs.append(unwrapValue(args[i])); | |
307 | |
308 return convertResult(Dart_New(handle, Dart_Null(), dartFunctionArgs.size(), dartFunctionArgs.data())); | |
309 } | |
310 | |
311 void getImportedLibrariesMatchingPrefix(int32_t libraryId, Dart_Handle prefix, V ector<std::pair<Dart_Handle, intptr_t> >* libraries) | |
Jacob
2013/07/11 18:52:27
It would be nice if I didn't have to do all this w
| |
312 { | |
313 Dart_Handle imports = Dart_GetLibraryImports(libraryId); | |
314 ASSERT(!Dart_IsError(imports)); | |
315 // Unfortunately dart_debugger_api.h adds a trailing dot to import prefixes. | |
316 if (!Dart_IsNull(prefix)) | |
317 prefix = addTrailingDot(prefix); | |
318 intptr_t length = 0; | |
319 Dart_ListLength(imports, &length); | |
320 for (intptr_t i = 0; i < length; i += 2) { | |
321 Dart_Handle importPrefix = Dart_ListGetAt(imports, i); | |
322 ASSERT(Dart_IsNull(importPrefix) || Dart_IsString(importPrefix)); | |
323 bool equals = false; | |
324 Dart_Handle result = Dart_ObjectEquals(prefix, importPrefix, &equals); | |
325 ASSERT(!Dart_IsError(result)); | |
326 if (equals) { | |
327 Dart_Handle importedLibraryIdHandle = Dart_ListGetAt(imports, i + 1) ; | |
328 ASSERT(Dart_IsInteger(importedLibraryIdHandle)); | |
329 int64_t importedLibraryId; | |
330 Dart_IntegerToInt64(importedLibraryIdHandle, &importedLibraryId); | |
331 Dart_Handle libraryURL = Dart_GetLibraryURL(importedLibraryId); | |
332 ASSERT(!Dart_IsError(libraryURL)); | |
333 Dart_Handle library = Dart_LookupLibrary(libraryURL); | |
334 ASSERT(Dart_IsLibrary(library)); | |
335 libraries->append(std::pair<Dart_Handle, intptr_t>(library, imported LibraryId)); | |
336 } | |
337 } | |
338 } | |
339 | |
340 static v8::Handle<v8::Value> libraryNamedPropertyGetterHelper(Dart_Handle librar y, Dart_Handle dartName, bool* handled) | |
341 { | |
Jacob
2013/07/11 18:52:27
would be nice if I could just call Dart_Invoke ins
| |
342 Dart_Handle ret; | |
343 ret = Dart_GetField(library, dartName); | |
344 if (!Dart_IsApiError(ret)) { | |
345 *handled = true; | |
346 return convertResult(ret); | |
347 } | |
348 | |
349 ret = Dart_GetClass(library, dartName); | |
350 if (!Dart_IsError(ret)) { | |
351 *handled = true; | |
352 return convertResult(ret); | |
353 } | |
354 | |
355 ret = Dart_LookupFunction(library, dartName); | |
356 if (!Dart_IsNull(ret) && !Dart_IsError(ret)) { | |
Jacob
2013/07/15 18:03:26
why do i have a null check here?
| |
357 *handled = true; | |
358 return convertResult(ret); | |
359 } | |
360 return v8::Undefined(); | |
361 } | |
362 | |
363 static v8::Handle<v8::Value> libraryNamedPropertyGetterHelper(v8::Local<v8::Stri ng> name, | |
364 const v8::AccessorInfo& info, bool* handled) | |
365 { | |
Jacob
2013/07/11 18:52:27
This is a mess due to handling prefixes.
It would
| |
366 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
367 ASSERT(scriptValue->isIsolateAlive()); | |
368 DartIsolateScope scope(scriptValue->isolate()); | |
369 DartApiScope apiScope; | |
370 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
371 | |
372 Dart_Handle ret; | |
373 ASSERT(Dart_IsLibrary(handle)); | |
374 intptr_t libraryId = getLibraryId(info.This()); | |
375 Dart_Handle dartName = V8Converter::stringToDart(name); | |
376 Dart_Handle prefix = getLibraryPrefix(info.This()); | |
377 bool hasLibraryPrefix = !Dart_IsNull(prefix) && Dart_IsString(prefix); | |
378 | |
379 if (hasLibraryPrefix) { | |
380 Vector<std::pair<Dart_Handle, intptr_t> > libraries; | |
381 getImportedLibrariesMatchingPrefix(libraryId, prefix, &libraries); | |
382 for (size_t i = 0; i < libraries.size(); i++) { | |
383 v8::Handle<v8::Value> returnValue = libraryNamedPropertyGetterHelper (libraries[i].first, dartName, handled); | |
384 if (*handled) | |
385 return returnValue; | |
386 } | |
387 } else { | |
388 v8::Handle<v8::Value> returnValue = libraryNamedPropertyGetterHelper(han dle, dartName, handled); | |
389 if (*handled) | |
390 return returnValue; | |
391 | |
392 // Check whether there is at least one library imported with the specifi ed prefix. | |
393 Vector<std::pair<Dart_Handle, intptr_t> > libraries; | |
394 getImportedLibrariesMatchingPrefix(libraryId, dartName, &libraries); | |
395 if (libraries.size() > 0) { | |
396 *handled = true; | |
397 return DartHandleProxy::createLibraryProxy(handle, libraryId, dartNa me); | |
398 } | |
399 } | |
400 | |
401 if (name->Equals(v8::String::NewSymbol("__proto__"))) { | |
402 *handled = true; | |
403 return v8::Null(); | |
404 } | |
405 return v8::Undefined(); | |
406 } | |
407 | |
408 static v8::Handle<v8::Value> libraryNamedPropertyGetter(v8::Local<v8::String> na me, const v8::AccessorInfo& info) | |
409 { | |
410 bool handled = false; | |
411 v8::Handle<v8::Value> ret = libraryNamedPropertyGetterHelper(name, info, &ha ndled); | |
412 if (handled) | |
413 return ret; | |
414 return v8::ThrowException(v8::Exception::ReferenceError(v8::String::Concat(n ame, v8::String::New(" is not defined")))); | |
415 } | |
416 | |
417 // TODO(jacobr): need to handle prefixes in this case as well. | |
418 // Before checkin, handle prefixes correctly. | |
419 static v8::Handle<v8::Value> libraryNamedPropertySetter(v8::Local<v8::String> pr operty, v8::Local<v8::Value> value, const v8::AccessorInfo& info) | |
420 { | |
421 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
422 ASSERT(scriptValue->isIsolateAlive()); | |
423 DartIsolateScope scope(scriptValue->isolate()); | |
424 DartApiScope apiScope; | |
425 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
426 | |
427 Dart_Handle ret; | |
428 ASSERT(Dart_IsLibrary(handle)); | |
429 Dart_Handle dartValue = unwrapValue(value); | |
430 ret = Dart_SetField(handle, V8Converter::stringToDart(property), dartValue); | |
431 return convertResult(ret); | |
432 } | |
433 | |
434 static v8::Handle<v8::Integer> libraryQueryProperty(v8::Local<v8::String> name, const v8::AccessorInfo& info) | |
435 { | |
436 bool handled = false; | |
437 libraryNamedPropertyGetterHelper(name, info, &handled); | |
438 return handled ? v8Integer(0, info.GetIsolate()) : v8::Handle<v8::Integer>() ; | |
439 } | |
440 | |
441 void libraryEnumerateHelper(Dart_Handle library, intptr_t libraryId, v8::Local<v 8::Array> properties, intptr_t* count) | |
442 { | |
443 addFunctionNames(library, properties, count, false, false); | |
444 addClassNames(library, properties, count); | |
445 addFieldNames(libraryId, properties, count); | |
446 } | |
447 | |
448 static v8::Handle<v8::Array> libraryPropertyEnumerator(const v8::AccessorInfo& i nfo) | |
449 { | |
Jacob
2013/07/11 18:52:27
It would be nice if Dart libraries provided a meth
| |
450 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
451 ASSERT(scriptValue->isIsolateAlive()); | |
452 DartIsolateScope scope(scriptValue->isolate()); | |
453 DartApiScope apiScope; | |
454 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
455 | |
456 intptr_t libraryId = getLibraryId(info.This()); | |
457 ASSERT(Dart_IsLibrary(handle)); | |
458 v8::Local<v8::Array> cachedProperties = info.This().As<v8::Object>()->GetHid denValue(v8::String::NewSymbol("cache")).As<v8::Array>(); | |
459 if (*cachedProperties) | |
460 return cachedProperties; | |
461 | |
462 Dart_Handle prefix = getLibraryPrefix(info.This()); | |
463 bool hasLibraryPrefix = Dart_IsString(prefix); | |
464 | |
465 v8::Local<v8::Array> properties = v8::Array::New(); | |
466 intptr_t count = 0; | |
467 | |
468 if (hasLibraryPrefix) { | |
469 Vector<std::pair<Dart_Handle, intptr_t> > libraries; | |
470 getImportedLibrariesMatchingPrefix(libraryId, prefix, &libraries); | |
471 for (intptr_t i = 0; i < libraries.size(); i++) | |
472 libraryEnumerateHelper(libraries[i].first, libraries[i].second, prop erties, &count); | |
473 } else { | |
474 libraryEnumerateHelper(handle, libraryId, properties, &count); | |
475 // Add all library prefixes of imports to the library. | |
476 Dart_Handle imports = Dart_GetLibraryImports(libraryId); | |
477 ASSERT(!Dart_IsError(imports)); | |
478 intptr_t length = 0; | |
479 Dart_ListLength(imports, &length); | |
480 for (intptr_t i = 0; i < length; i += 2) { | |
481 Dart_Handle importPrefix = Dart_ListGetAt(imports, i); | |
482 if (!Dart_IsNull(importPrefix)) { | |
483 ASSERT(Dart_IsString(importPrefix)); | |
484 properties->Set(count, V8Converter::stringToV8( | |
485 stripTrailingDot(importPrefix))); | |
486 count++; | |
487 } | |
488 bool equals = false; | |
489 } | |
490 } | |
491 info.This()->SetHiddenValue(v8::String::NewSymbol("cache"), properties); | |
492 return properties; | |
493 } | |
494 | |
495 static v8::Handle<v8::Value> classNamedPropertyGetter(v8::Local<v8::String> name , const v8::AccessorInfo& info) | |
496 { | |
497 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
498 ASSERT(scriptValue->isIsolateAlive()); | |
499 DartIsolateScope scope(scriptValue->isolate()); | |
500 DartApiScope apiScope; | |
501 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
502 | |
503 Dart_Handle ret; | |
504 ASSERT(Dart_IsClass(handle)); | |
505 // XXX hack... remove... FILE A BUG! | |
506 bool isDynamic = false; | |
Jacob
2013/07/11 18:52:27
What should we do about the class "dynamic".
It ex
| |
507 Dart_ObjectEquals(Dart_ClassName(handle), Dart_NewStringFromCString("dynamic "), &isDynamic); | |
508 | |
509 if (!Dart_ClassIsTypedef(handle) && !Dart_ClassIsFunctionType(handle) && !is Dynamic) { | |
Jacob
2013/07/11 18:52:27
Similarly to the case of Library, it would be nice
| |
510 | |
511 Dart_Handle dartName = V8Converter::stringToDart(name); | |
512 ret = Dart_GetField(handle, dartName); | |
513 if (!Dart_IsError(ret)) | |
514 return convertResult(ret); | |
515 ret = Dart_LookupFunction(handle, dartName); | |
516 if (!Dart_IsNull(ret) && !Dart_IsError(ret)) | |
517 return convertResult(ret); | |
518 | |
519 Dart_Handle className = Dart_ClassName(handle); | |
520 ASSERT(Dart_IsString(className)); | |
521 Dart_Handle constructorName = buildConstructorName(className, V8Converte r::stringToDart(name)); | |
522 ret = Dart_LookupFunction(handle, constructorName); | |
523 if (!Dart_IsNull(ret) && !Dart_IsError(ret)) | |
524 return convertResult(ret); | |
525 } | |
526 | |
527 if (name->Equals(v8::String::NewSymbol("__proto__"))) { | |
528 Dart_Handle superclass = Dart_GetSuperclass(handle); | |
529 if (!Dart_IsError(superclass)) | |
530 return DartHandleProxy::create(superclass); | |
531 return v8::Undefined(); | |
532 } | |
533 return v8::ThrowException(v8::Exception::ReferenceError(v8::String::Concat(n ame, v8::String::New(" is not defined")))); | |
534 } | |
535 | |
536 static v8::Handle<v8::Value> classNamedPropertySetter(v8::Local<v8::String> prop erty, v8::Local<v8::Value> value, const v8::AccessorInfo& info) | |
537 { | |
538 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
539 ASSERT(scriptValue->isIsolateAlive()); | |
540 DartIsolateScope scope(scriptValue->isolate()); | |
541 DartApiScope apiScope; | |
542 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
543 | |
544 Dart_Handle ret; | |
545 ASSERT(Dart_IsClass(handle)); | |
546 Dart_Handle dartValue = unwrapValue(value); | |
547 ret = Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::S tring::New("set:"), property)), 1, &dartValue); | |
Jacob
2013/07/11 18:52:27
TODO(jacobr): similar to the case of Libraries, th
| |
548 return convertResult(ret); | |
549 } | |
550 | |
551 static v8::Handle<v8::Integer> classQueryProperty(v8::Local<v8::String> name, co nst v8::AccessorInfo& info) | |
552 { | |
553 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
554 ASSERT(scriptValue->isIsolateAlive()); | |
555 DartIsolateScope scope(scriptValue->isolate()); | |
556 DartApiScope apiScope; | |
557 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
558 | |
559 Dart_Handle ret; | |
560 ASSERT(Dart_IsClass(handle)); | |
561 if (classHasMember(handle, V8Converter::stringToDart(name))) | |
562 return v8Integer(0, info.GetIsolate()); | |
563 return v8::Handle<v8::Integer>(); | |
564 } | |
565 | |
566 static v8::Handle<v8::Array> classPropertyEnumerator(const v8::AccessorInfo& inf o) | |
567 { | |
568 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
569 ASSERT(scriptValue->isIsolateAlive()); | |
570 DartIsolateScope scope(scriptValue->isolate()); | |
571 DartApiScope apiScope; | |
572 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
573 | |
574 ASSERT(Dart_IsClass(handle)); | |
575 | |
576 v8::Local<v8::Array> properties = v8::Array::New(); | |
577 intptr_t count = 0; | |
578 addFunctionNames(handle, properties, &count, false, false); | |
Jacob
2013/07/11 18:52:27
it would be nice if there was just an Dart API met
| |
579 return properties; | |
580 } | |
581 | |
582 // Returns the index in the list of the property if it is found, -1 otherwise. | |
583 static int findMatchingNamedProperty(Dart_Handle list, v8::Local<v8::String> nam e) | |
584 { | |
585 // FIXME: perhaps push this logic into Dart code instead. | |
586 v8::String::Utf8Value stringValue(name); | |
587 const char* nameData = *stringValue; | |
588 intptr_t nameLength = stringValue.length(); | |
589 | |
590 intptr_t length = 0; | |
591 Dart_ListLength(list, &length); | |
592 for (intptr_t i = 0; i < length; i += 2) { | |
593 intptr_t candidateNameLength = 0; | |
594 uint8_t* candidateData = 0; | |
595 intptr_t candidateLength = 0; | |
596 Dart_StringToUTF8(Dart_ListGetAt(list, i), &candidateData, &candidateLen gth); | |
597 if ((candidateLength >= nameLength | |
598 && (candidateLength == nameLength || candidateData[nameLength] == '@ ')) | |
599 && !memcmp(candidateData, nameData, nameLength)) | |
600 return i / 2; | |
601 } | |
602 return -1; | |
603 } | |
604 | |
605 static v8::Handle<v8::Value> frameNamedPropertyGetter(v8::Local<v8::String> name , const v8::AccessorInfo& info) | |
606 { | |
Jacob
2013/07/11 18:52:27
It would be nice if the local frame was just expos
| |
607 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
608 ASSERT(scriptValue->isIsolateAlive()); | |
609 DartIsolateScope scope(scriptValue->isolate()); | |
610 DartApiScope apiScope; | |
611 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
612 | |
613 ASSERT(Dart_IsList(handle)); | |
614 int index = findMatchingNamedProperty(handle, name); | |
615 if (index != -1) | |
616 return convertResult(Dart_ListGetAt(handle, index * 2 + 1)); | |
617 if (name->Equals(v8::String::NewSymbol("this"))) | |
618 return v8::Undefined(); | |
619 return v8::ThrowException(v8::Exception::ReferenceError(v8::String::Concat(n ame, v8::String::New(" is not defined")))); | |
620 } | |
621 | |
622 static v8::Handle<v8::Value> frameNamedPropertySetter(v8::Local<v8::String> prop erty, v8::Local<v8::Value> value, const v8::AccessorInfo& info) | |
623 { | |
Jacob
2013/07/11 18:52:27
This is the one case where we can't manipulate Dat
| |
624 return throwError(v8ReferenceError, "Dart does not yet provide a debugger ap i for setting local fields", v8::Isolate::GetCurrent()); | |
625 } | |
626 | |
627 static v8::Handle<v8::Integer> frameQueryProperty(v8::Local<v8::String> name, co nst v8::AccessorInfo& info) | |
628 { | |
629 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
630 ASSERT(scriptValue->isIsolateAlive()); | |
631 DartIsolateScope scope(scriptValue->isolate()); | |
632 DartApiScope apiScope; | |
633 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
634 | |
635 ASSERT(Dart_IsList(handle)); | |
636 int index = findMatchingNamedProperty(handle, name); | |
637 return index == -1 ? v8::Handle<v8::Integer>() : v8Integer(0, info.GetIsolat e()); | |
638 } | |
639 | |
640 static v8::Handle<v8::Array> framePropertyEnumerator(const v8::AccessorInfo& inf o) | |
641 { | |
642 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
643 ASSERT(scriptValue->isIsolateAlive()); | |
644 DartIsolateScope scope(scriptValue->isolate()); | |
645 DartApiScope apiScope; | |
646 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
647 | |
648 ASSERT(Dart_IsList(handle)); | |
649 | |
650 intptr_t length = 0; | |
651 Dart_ListLength(handle, &length); | |
652 v8::Local<v8::Array> properties = v8::Array::New(length / 2); | |
653 for (intptr_t i = 0; i < length; i += 2) { | |
654 // Truncate everything after the '@'. | |
Jacob
2013/07/11 18:52:27
it would be nice if there was an option to get nam
| |
655 // TODO(jacobr): we shouldn't have to do this, there should be an API th at provides | |
656 // Mirror APIs on frames directly. | |
657 const char* nameData = 0; | |
658 Dart_StringToCString(Dart_ListGetAt(handle, i), &nameData); | |
659 ASSERT(nameData); | |
660 if (!nameData) | |
661 continue; | |
662 | |
663 intptr_t nameLength = strlen(nameData); | |
664 | |
665 for (intptr_t j = 0; j < nameLength; j++) { | |
666 if (nameData[j] == '@') { | |
667 nameLength = j; | |
668 break; | |
669 } | |
670 } | |
671 properties->Set(i / 2, v8::String::New(nameData, nameLength)); | |
672 } | |
673 return properties; | |
674 } | |
675 | |
676 static v8::Handle<v8::Value> namedPropertyGetter(v8::Local<v8::String> name, con st v8::AccessorInfo& info) | |
677 { | |
678 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
679 ASSERT(scriptValue->isIsolateAlive()); | |
680 DartIsolateScope scope(scriptValue->isolate()); | |
681 DartApiScope apiScope; | |
682 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
683 | |
684 Dart_Handle ret; | |
685 ASSERT(Dart_IsInstance(handle)); | |
686 v8::String::Utf8Value stringName(name); | |
687 const char* data = *stringName; | |
688 if (data[0] == ':' || data[0] == '#') { | |
689 // Look up a map key instead of a regular property as regular dart prope rty names | |
690 // cannot start with these symbols. | |
691 return convertResult( | |
692 lookupValueForEncodedMapKey(handle, V8Converter::stringToDart(name)) ); | |
693 } | |
694 | |
695 ret = Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::S tring::New("get:"), name)), 0, 0); | |
696 if (Dart_IsError(ret) && name->Equals(v8::String::NewSymbol("__proto__"))) | |
697 return DartHandleProxy::create(Dart_GetObjClass(handle)); | |
698 | |
699 return convertResult(ret); | |
700 } | |
701 | |
702 static v8::Handle<v8::Value> namedPropertySetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) | |
703 { | |
704 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
705 ASSERT(scriptValue->isIsolateAlive()); | |
706 DartIsolateScope scope(scriptValue->isolate()); | |
707 DartApiScope apiScope; | |
708 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
709 | |
710 Dart_Handle ret; | |
711 Dart_Handle dartValue = unwrapValue(value); | |
712 ret = Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::S tring::New("set:"), property)), 1, &dartValue); | |
713 if (Dart_IsError(ret)) { | |
714 Dart_Handle dartPropertyName = V8Converter::stringToDart(property); | |
715 Dart_Handle indexedGetterOperator = Dart_NewStringFromCString("[]="); | |
716 Dart_Handle args[] = {dartPropertyName, dartValue}; | |
717 ret = Dart_Invoke(handle, indexedGetterOperator, 2, args); | |
718 } | |
719 return convertResult(ret); | |
720 } | |
721 | |
722 // FIXME: duplicated code with getter. XXX | |
723 static v8::Handle<v8::Integer> objectQueryProperty(v8::Local<v8::String> name, c onst v8::AccessorInfo& info) | |
724 { | |
725 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
726 ASSERT(scriptValue->isIsolateAlive()); | |
727 DartIsolateScope scope(scriptValue->isolate()); | |
728 DartApiScope apiScope; | |
729 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
730 | |
731 Dart_Handle ret; | |
732 ASSERT(Dart_IsInstance(handle)); | |
733 v8::String::Utf8Value stringName(name); | |
734 const char* data = *stringName; | |
735 | |
736 // Looking up a map key instead of a regular property... as regular dart pro perty names | |
737 // cannot start with these symbols. | |
738 if (data[0] == ':' || data[0] == '#') | |
739 return v8Integer(0, info.GetIsolate()); | |
740 | |
741 ret = Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::S tring::New("get:"), name)), 0, 0); | |
742 if (Dart_IsError(ret)) { | |
743 if (name->Equals(v8::String::NewSymbol("__proto__"))) | |
744 return v8Integer(0, info.GetIsolate()); | |
745 return v8::Handle<v8::Integer>(); | |
746 } | |
747 return v8Integer(0, info.GetIsolate()); | |
748 } | |
749 | |
750 static v8::Handle<v8::Array> objectPropertyEnumerator(const v8::AccessorInfo& in fo) | |
751 { | |
752 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
753 ASSERT(scriptValue->isIsolateAlive()); | |
754 DartIsolateScope scope(scriptValue->isolate()); | |
755 DartApiScope apiScope; | |
756 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
757 | |
758 ASSERT(Dart_IsInstance(handle)); | |
759 | |
760 Dart_Handle typeHandle; | |
761 if (Dart_IsInstance(handle)) | |
762 typeHandle = Dart_InstanceGetClass(handle); | |
763 else | |
764 typeHandle = handle; | |
765 | |
766 v8::Local<v8::Array> properties = v8::Array::New(); | |
767 intptr_t count = 0; | |
768 | |
769 Dart_Handle mapKeys = getEncodedMapKeyList(handle); | |
770 if (Dart_IsList(mapKeys)) { | |
771 // If the object has map keys, add them all as properties at the start | |
772 // of the list. This aids for debugging although it risks confusing | |
773 // users. | |
774 intptr_t length = 0; | |
775 Dart_ListLength(mapKeys, &length); | |
776 for (intptr_t i = 0; i < length; i++) { | |
777 properties->Set(count, V8Converter::stringToV8(Dart_ListGetAt(mapKey s, i))); | |
778 count++; | |
779 } | |
780 } | |
781 | |
782 Dart_Handle instanceFields = Dart_GetInstanceFields(handle); | |
783 intptr_t length = 0; | |
784 Dart_ListLength(instanceFields, &length); | |
785 for (intptr_t i = 0; i < length; i += 2) { | |
786 properties->Set(count, DartHandleProxy::create( | |
787 Dart_ListGetAt(instanceFields, i))); | |
788 count++; | |
789 } | |
790 | |
791 while (!Dart_IsError(typeHandle) && !Dart_IsNull(typeHandle)) { | |
792 intptr_t interfaceCount = 0; | |
793 Dart_ClassGetInterfaceCount(typeHandle, &interfaceCount); | |
794 for (intptr_t i = 0; i < interfaceCount; i++) { | |
795 addFunctionNames(Dart_ClassGetInterfaceAt(typeHandle, i), | |
796 properties, &count, true, true); | |
797 } | |
798 // TODO(jacobr): is this duplicated work? | |
799 addFunctionNames(typeHandle, properties, &count, true, true); | |
800 typeHandle = Dart_GetSuperclass(typeHandle); | |
801 } | |
802 return properties; | |
803 } | |
804 | |
805 static v8::Handle<v8::Value> indexedGetter(uint32_t index, const v8::AccessorInf o& info) | |
806 { | |
807 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
808 ASSERT(scriptValue->isIsolateAlive()); | |
809 DartIsolateScope scope(scriptValue->isolate()); | |
810 DartApiScope apiScope; | |
811 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
812 | |
813 Dart_Handle ret = 0; | |
814 if (Dart_IsList(handle)) | |
815 ret = Dart_ListGetAt(handle, index); | |
816 else | |
817 ret = Dart_Null(); | |
818 | |
819 return convertResult(ret); | |
820 } | |
821 | |
822 static v8::Handle<v8::Value> indexedSetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info) | |
823 { | |
824 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
825 ASSERT(scriptValue->isIsolateAlive()); | |
826 DartIsolateScope scope(scriptValue->isolate()); | |
827 DartApiScope apiScope; | |
828 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
829 | |
830 Dart_Handle ret = 0; | |
831 if (Dart_IsList(handle)) | |
832 ret = Dart_ListSetAt(handle, index, unwrapValue(value)); | |
833 else | |
834 ret = Dart_Null(); | |
835 | |
836 return convertResult(ret); | |
837 } | |
838 | |
839 static v8::Handle<v8::Array> indexedEnumerator(const v8::AccessorInfo& info) | |
840 { | |
841 DartScriptValue* scriptValue = readPointerFromProxy(info.This()); | |
842 ASSERT(scriptValue->isIsolateAlive()); | |
843 DartIsolateScope scope(scriptValue->isolate()); | |
844 DartApiScope apiScope; | |
845 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); | |
846 | |
847 intptr_t length = 0; | |
848 if (Dart_IsList(handle)) | |
849 Dart_ListLength(handle, &length); | |
850 | |
851 v8::Local<v8::Array> indexes = v8::Array::New(length); | |
852 for (int i = 0; i < length; i++) | |
853 indexes->Set(i, v8::Integer::New(i)); | |
854 | |
855 return indexes; | |
856 } | |
857 | |
858 static v8::Local<v8::ObjectTemplate> setupInstanceTemplate(v8::Persistent<v8::Fu nctionTemplate> proxyTemplate) | |
859 { | |
860 v8::Local<v8::ObjectTemplate> instanceTemplate = proxyTemplate->InstanceTemp late(); | |
861 instanceTemplate->SetInternalFieldCount(1); | |
862 return instanceTemplate; | |
863 } | |
864 | |
865 static v8::Persistent<v8::FunctionTemplate> objectProxyTemplate(Dart_Handle inst ance) | |
866 { | |
867 DEFINE_STATIC_LOCAL(FunctionTemplateMap, map, ()); | |
868 // FIXME: we should switch to Dart_InstanceGetType when possible. | |
869 Dart_Handle dartType = Dart_InstanceGetClass(instance); | |
870 ASSERT(!Dart_IsError(dartType)); | |
871 Dart_Handle classNameHandle = Dart_ClassName(dartType); | |
872 ASSERT(!Dart_IsError(classNameHandle)); | |
873 if (Dart_IsError(classNameHandle)) | |
874 classNameHandle = Dart_NewStringFromCString("MYSTERY DART CLAZZ XXX"); | |
875 ASSERT(!Dart_IsError(classNameHandle)); | |
876 v8::Handle<v8::String> classNameV8 = V8Converter::stringToV8(classNameHandle ); | |
877 String className = toWebCoreString(classNameV8); | |
878 v8::Persistent<v8::FunctionTemplate> proxyTemplate = map.get(className); | |
879 | |
880 if (proxyTemplate.IsEmpty()) { | |
881 proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::G etCurrent(), v8::FunctionTemplate::New()); | |
882 proxyTemplate->SetClassName(classNameV8); | |
883 map.set(className, proxyTemplate); | |
884 v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(p roxyTemplate); | |
885 instanceTemplate->SetIndexedPropertyHandler(&indexedGetter, &indexedSett er, 0, 0, &indexedEnumerator); | |
886 instanceTemplate->SetNamedPropertyHandler(&namedPropertyGetter, &namedPr opertySetter, &objectQueryProperty, 0, &objectPropertyEnumerator); | |
887 } | |
888 return proxyTemplate; | |
889 } | |
890 | |
891 static v8::Persistent<v8::FunctionTemplate> functionProxyTemplate() | |
892 { | |
893 static v8::Persistent<v8::FunctionTemplate> proxyTemplate; | |
894 if (proxyTemplate.IsEmpty()) { | |
895 proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::G etCurrent(), v8::FunctionTemplate::New()); | |
896 proxyTemplate->SetClassName(v8::String::New("[Dart Function]")); | |
897 v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(p roxyTemplate); | |
898 instanceTemplate->SetNamedPropertyHandler(&functionNamedPropertyGetter, &functionNamedPropertySetter); | |
899 instanceTemplate->SetCallAsFunctionHandler(&functionInvocationCallback); | |
900 } | |
901 return proxyTemplate; | |
902 } | |
903 | |
904 static v8::Persistent<v8::FunctionTemplate> libraryProxyTemplate() | |
905 { | |
906 static v8::Persistent<v8::FunctionTemplate> proxyTemplate; | |
907 if (proxyTemplate.IsEmpty()) { | |
908 proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::G etCurrent(), v8::FunctionTemplate::New()); | |
909 proxyTemplate->SetClassName(v8::String::New("[Dart Library]")); | |
910 v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(p roxyTemplate); | |
911 instanceTemplate->SetNamedPropertyHandler(&libraryNamedPropertyGetter, & libraryNamedPropertySetter, &libraryQueryProperty, 0, &libraryPropertyEnumerator ); | |
912 } | |
913 return proxyTemplate; | |
914 } | |
915 | |
916 static v8::Persistent<v8::FunctionTemplate> classProxyTemplate(Dart_Handle clazz ) | |
917 { | |
918 DEFINE_STATIC_LOCAL(FunctionTemplateMap, map, ()); | |
919 Dart_Handle classNameHandle = Dart_ClassName(clazz); | |
920 ASSERT(!Dart_IsError(classNameHandle)); | |
921 v8::Handle<v8::String> classNameV8 = V8Converter::stringToV8(classNameHandle ); | |
922 String className = toWebCoreString(classNameV8); | |
923 | |
924 v8::Persistent<v8::FunctionTemplate> proxyTemplate = map.get(className); | |
925 if (proxyTemplate.IsEmpty()) { | |
926 proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::G etCurrent(), v8::FunctionTemplate::New()); | |
927 proxyTemplate->SetClassName(classNameV8); | |
928 v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(p roxyTemplate); | |
929 instanceTemplate->SetNamedPropertyHandler(&classNamedPropertyGetter, &cl assNamedPropertySetter, &classQueryProperty, 0, &classPropertyEnumerator); | |
930 instanceTemplate->SetCallAsFunctionHandler(&classProxyConstructorInvocat ionCallback); | |
931 map.set(className, proxyTemplate); | |
932 } | |
933 return proxyTemplate; | |
934 } | |
935 | |
936 static v8::Persistent<v8::FunctionTemplate> frameProxyTemplate() | |
937 { | |
938 static v8::Persistent<v8::FunctionTemplate> proxyTemplate; | |
939 if (proxyTemplate.IsEmpty()) { | |
940 proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::G etCurrent(), v8::FunctionTemplate::New()); | |
941 proxyTemplate->SetClassName(v8::String::New("[Dart Frame]")); | |
942 v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(p roxyTemplate); | |
943 instanceTemplate->SetNamedPropertyHandler(&frameNamedPropertyGetter, &fr ameNamedPropertySetter, &frameQueryProperty, 0, &framePropertyEnumerator); | |
944 } | |
945 return proxyTemplate; | |
946 } | |
947 | |
55 v8::Handle<v8::Value> DartHandleProxy::create(Dart_Handle value) | 948 v8::Handle<v8::Value> DartHandleProxy::create(Dart_Handle value) |
56 { | 949 { |
57 v8::Context::Scope scope(DartUtilities::currentV8Context()); | 950 v8::Context::Scope scope(DartUtilities::currentV8Context()); |
58 | 951 |
59 if (Dart_IsNull(value)) | 952 if (Dart_IsNull(value)) |
60 return v8::Null(); | 953 return v8::Null(); |
61 if (Dart_IsString(value)) | 954 if (Dart_IsString(value)) |
62 return V8Converter::stringToV8(value); | 955 return V8Converter::stringToV8(value); |
63 if (Dart_IsBoolean(value)) | 956 if (Dart_IsBoolean(value)) |
64 return V8Converter::booleanToV8(value); | 957 return V8Converter::booleanToV8(value); |
65 if (Dart_IsNumber(value)) | 958 if (Dart_IsNumber(value)) |
66 return V8Converter::numberToV8(value); | 959 return V8Converter::numberToV8(value); |
67 | 960 v8::Local<v8::Object> proxy; |
68 v8::Local<v8::Object> proxy = proxyTemplate()->InstanceTemplate()->NewInstan ce(); | 961 // TODO(jacobr): could optimize the order of these checks. |
69 proxy->SetAlignedPointerInInternalField(0, new DartScriptValue(value)); | 962 if (Dart_IsFunction(value) || Dart_IsClosure(value)) |
70 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 963 proxy = functionProxyTemplate()->InstanceTemplate()->NewInstance(); |
71 v8::Persistent<v8::Object> persistentHandle = v8::Persistent<v8::Object>::Ne w(isolate, proxy); | 964 else if (Dart_IsInstance(value)) |
72 persistentHandle.MakeWeak<v8::Object, void>(0, &weakCallback); | 965 proxy = objectProxyTemplate(value)->InstanceTemplate()->NewInstance(); |
73 proxy->Set(v8::String::New("isProxy"), v8::Boolean::New(true)); | 966 else { |
967 ASSERT(Dart_IsClass(value)); | |
968 proxy = classProxyTemplate(value)->InstanceTemplate()->NewInstance(); | |
969 } | |
970 setDartHandleInternalField(proxy, value); | |
971 proxy->SetHiddenValue(v8::String::NewSymbol("dartProxy"), v8::Boolean::New(t rue)); | |
972 | |
74 return proxy; | 973 return proxy; |
75 } | 974 } |
76 | 975 |
77 v8::Handle<v8::Value> DartHandleProxy::createForLibrary(intptr_t libraryId) | 976 bool DartHandleProxy::isDartProxy(v8::Handle<v8::Value> value) |
78 { | 977 { |
79 Dart_Handle libraryURL = Dart_GetLibraryURL(libraryId); | 978 if (value->IsObject()) { |
80 ASSERT(!Dart_IsError(libraryURL)); | 979 v8::Local<v8::Value> hiddenValue = value.As<v8::Object>()->GetHiddenValu e(v8::String::NewSymbol("dartProxy")); |
81 Dart_Handle library = Dart_LookupLibrary(libraryURL); | 980 return *hiddenValue && hiddenValue->IsBoolean(); |
82 v8::Handle<v8::Object> libraryProxy = create(library)->ToObject(); | 981 } |
83 libraryProxy->SetHiddenValue(v8::String::New("libraryId"), v8::Number::New(l ibraryId)); | 982 return false; |
84 return libraryProxy; | 983 } |
85 } | 984 |
86 | 985 const char* DartHandleProxy::getType(v8::Handle<v8::Value> value) { |
87 class DartReceiverScope { | 986 DartScriptValue* scriptValue = readPointerFromProxy(value); |
88 public: | 987 ASSERT(scriptValue->isIsolateAlive()); |
89 DartReceiverScope(const v8::Arguments& args) | 988 DartIsolateScope scope(scriptValue->isolate()); |
90 : m_receiver(readPointerFromProxy(args[0])) | 989 DartApiScope apiScope; |
91 , m_isolateScope(m_receiver->isolate()) | 990 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); |
92 , m_apiScope() | 991 |
93 { | 992 if (Dart_IsInstance(handle)) { |
94 } | 993 if (Dart_IsList(handle)) |
95 | 994 return "array"; |
96 Dart_Handle receiver() { return Dart_HandleFromPersistent(m_receiver->value( )); } | 995 |
97 | 996 Dart_Handle exception = 0; |
98 private: | 997 if (DartUtilities::dartToBool(isNode(handle), exception)) |
99 DartScriptValue* m_receiver; | 998 return "node"; |
100 DartIsolateScope m_isolateScope; | 999 ASSERT(!exception); |
101 DartApiScope m_apiScope; | 1000 } |
102 }; | 1001 |
103 | 1002 return 0; |
104 static v8::Persistent<v8::FunctionTemplate> proxyTemplate() | 1003 } |
105 { | 1004 |
106 static v8::Persistent<v8::FunctionTemplate> proxyTemplate; | 1005 Node* DartHandleProxy::toNativeNode(v8::Handle<v8::Value> value) { |
107 if (proxyTemplate.IsEmpty()) { | 1006 DartScriptValue* scriptValue = readPointerFromProxy(value); |
108 proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::G etCurrent(), v8::FunctionTemplate::New()); | 1007 ASSERT(scriptValue->isIsolateAlive()); |
109 v8::Local<v8::ObjectTemplate> instanceTemplate = proxyTemplate->Instance Template(); | 1008 DartIsolateScope scope(scriptValue->isolate()); |
110 instanceTemplate->SetInternalFieldCount(1); | 1009 DartApiScope apiScope; |
111 } | 1010 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value()); |
112 return proxyTemplate; | |
113 } | |
114 | |
115 static Dart_Handle unwrapValue(v8::Handle<v8::Value> value) | |
116 { | |
117 if (proxyTemplate()->HasInstance(value)) | |
118 return Dart_HandleFromPersistent(readPointerFromProxy(value)->value()); | |
119 Dart_Handle exception = 0; | 1011 Dart_Handle exception = 0; |
120 Dart_Handle handle = V8Converter::toDart(value, exception); | 1012 Node* node = DartNode::toNative(handle, exception); |
121 ASSERT(!exception); | 1013 ASSERT(!exception); |
122 return handle; | 1014 return node; |
123 } | 1015 } |
124 | 1016 |
125 static v8::Handle<v8::Value> convertResult(Dart_Handle result) | 1017 /** |
126 { | 1018 * Creates a proxy for a Dart library. |
127 if (Dart_IsError(result)) { | 1019 * If a string prefix is specified, we similuate that all requests to the librar y start with |
128 // Consider wrapping not as a string, but as dedicated | 1020 * the specified prefix. |
129 // exception wrapper. | 1021 */ |
130 return v8::String::New("<Exception thrown>"); | 1022 v8::Handle<v8::Value> DartHandleProxy::createLibraryProxy(Dart_Handle value, int 32_t libraryId, Dart_Handle prefix) |
131 } | 1023 { |
Jacob
2013/07/11 18:52:27
why do I have to keep around both a handle to a li
| |
132 return DartHandleProxy::create(result); | 1024 v8::Context::Scope scope(DartUtilities::currentV8Context()); |
133 } | 1025 ASSERT(Dart_IsLibrary(value)); |
134 | 1026 v8::Local<v8::Object> proxy = libraryProxyTemplate()->InstanceTemplate()->Ne wInstance(); |
135 // --- Objects ---- | 1027 setDartHandleInternalField(proxy, value); |
136 | 1028 proxy->SetHiddenValue(v8::String::NewSymbol("libraryId"), v8::Number::New(li braryId)); |
137 static v8::Handle<v8::Value> instanceGetClass(const v8::Arguments& args) | 1029 if (Dart_IsString(prefix)) |
138 { | 1030 proxy->SetHiddenValue(v8::String::NewSymbol("prefix"), V8Converter::stri ngToV8(prefix)); |
139 DartReceiverScope scope(args); | 1031 |
140 return convertResult(Dart_InstanceGetClass(scope.receiver())); | 1032 proxy->SetHiddenValue(v8::String::NewSymbol("dartProxy"), v8::Boolean::New(t rue)); |
141 } | 1033 return proxy; |
142 | 1034 } |
143 // --- Lists --- | 1035 |
144 | 1036 v8::Handle<v8::Value> DartHandleProxy::createLocalScopeProxy(Dart_Handle localVa riables) |
145 static v8::Handle<v8::Value> isList(const v8::Arguments& args) | 1037 { |
146 { | 1038 v8::Local<v8::Object> proxy = frameProxyTemplate()->InstanceTemplate()->NewI nstance(); |
147 DartReceiverScope scope(args); | 1039 setDartHandleInternalField(proxy, localVariables); |
148 return v8::Boolean::New(Dart_IsList(scope.receiver())); | 1040 proxy->SetHiddenValue(v8::String::NewSymbol("dartProxy"), v8::Boolean::New(t rue)); |
149 } | 1041 return proxy; |
150 | 1042 } |
151 static v8::Handle<v8::Value> listGetAt(const v8::Arguments& args) | 1043 |
152 { | 1044 } |
153 DartReceiverScope scope(args); | |
154 return convertResult(Dart_ListGetAt(scope.receiver(), args[1]->Int32Value()) ); | |
155 } | |
156 | |
157 static v8::Handle<v8::Value> listSetAt(const v8::Arguments& args) | |
158 { | |
159 DartReceiverScope scope(args); | |
160 return convertResult(Dart_ListSetAt(scope.receiver(), args[1]->Int32Value(), unwrapValue(args[2]))); | |
161 } | |
162 | |
163 // --- Classes and Interfaces --- | |
164 | |
165 static v8::Handle<v8::Value> className(const v8::Arguments& args) | |
166 { | |
167 DartReceiverScope scope(args); | |
168 return convertResult(Dart_ClassName(scope.receiver())); | |
169 } | |
170 | |
171 static v8::Handle<v8::Value> classGetLibrary(const v8::Arguments& args) | |
172 { | |
173 DartReceiverScope scope(args); | |
174 return convertResult(Dart_ClassGetLibrary(scope.receiver())); | |
175 } | |
176 | |
177 static v8::Handle<v8::Value> getSuperclass(const v8::Arguments& args) | |
178 { | |
179 DartReceiverScope scope(args); | |
180 return convertResult(Dart_GetSuperclass(scope.receiver())); | |
181 } | |
182 | |
183 // --- Function and Variable Declarations --- | |
184 | |
185 static v8::Handle<v8::Value> getFunctionNames(const v8::Arguments& args) | |
186 { | |
187 DartReceiverScope scope(args); | |
188 return V8Converter::listToV8(Dart_GetFunctionNames(scope.receiver())); | |
189 } | |
190 | |
191 static v8::Handle<v8::Value> getClassNames(const v8::Arguments& args) | |
192 { | |
193 DartReceiverScope scope(args); | |
194 Dart_Handle classNames = Dart_LibraryGetClassNames(scope.receiver()); | |
195 ASSERT(!Dart_IsError(classNames) && !Dart_IsNull(classNames)); | |
196 return V8Converter::listToV8(classNames); | |
197 } | |
198 | |
199 static v8::Handle<v8::Value> lookupClass(const v8::Arguments& args) | |
200 { | |
201 DartReceiverScope scope(args); | |
202 return convertResult(Dart_GetClass(scope.receiver(), V8Converter::stringToDa rt(args[1]))); | |
203 } | |
204 | |
205 static v8::Handle<v8::Value> lookupFunction(const v8::Arguments& args) | |
206 { | |
207 DartReceiverScope scope(args); | |
208 | |
209 Dart_Handle function = Dart_LookupFunction(scope.receiver(), V8Converter::st ringToDart(args[1])); | |
210 ASSERT(!Dart_IsError(function) && !Dart_IsNull(function)); | |
211 | |
212 Dart_Handle result; | |
213 UNUSED_PARAM(result); | |
214 | |
215 bool isAbstract; | |
216 result = Dart_FunctionIsAbstract(function, &isAbstract); | |
217 ASSERT(!Dart_IsError(result)); | |
218 bool isStatic; | |
219 result = Dart_FunctionIsStatic(function, &isStatic); | |
220 ASSERT(!Dart_IsError(result)); | |
221 bool isConstructor; | |
222 result = Dart_FunctionIsConstructor(function, &isConstructor); | |
223 ASSERT(!Dart_IsError(result)); | |
224 bool isGetter; | |
225 result = Dart_FunctionIsGetter(function, &isGetter); | |
226 ASSERT(!Dart_IsError(result)); | |
227 bool isSetter; | |
228 result = Dart_FunctionIsSetter(function, &isSetter); | |
229 ASSERT(!Dart_IsError(result)); | |
230 int64_t fixedParameterCount; | |
231 int64_t optionalParamerterCount; | |
232 result = Dart_FunctionParameterCounts(function, &fixedParameterCount, &optio nalParamerterCount); | |
233 ASSERT(!Dart_IsError(result)); | |
234 | |
235 v8::Handle<v8::Object> description = v8::Object::New(); | |
236 description->Set(v8::String::New("isAbstract"), v8::Boolean::New(isAbstract) ); | |
237 description->Set(v8::String::New("isStatic"), v8::Boolean::New(isStatic)); | |
238 description->Set(v8::String::New("isConstructor"), v8::Boolean::New(isConstr uctor)); | |
239 description->Set(v8::String::New("isGetter"), v8::Boolean::New(isGetter)); | |
240 description->Set(v8::String::New("isSetter"), v8::Boolean::New(isSetter)); | |
241 description->Set(v8::String::New("fixedParameterCount"), v8::Integer::New(fi xedParameterCount)); | |
242 description->Set(v8::String::New("optionalParamerterCount"), v8::Integer::Ne w(optionalParamerterCount)); | |
243 return description; | |
244 } | |
245 | |
246 static v8::Handle<v8::Value> getVariableNames(const v8::Arguments& args) | |
247 { | |
248 DartReceiverScope scope(args); | |
249 return V8Converter::listToV8(Dart_GetVariableNames(scope.receiver())); | |
250 } | |
251 | |
252 static v8::Handle<v8::Value> lookupVariable(const v8::Arguments& args) | |
253 { | |
254 DartReceiverScope scope(args); | |
255 Dart_Handle variable = Dart_LookupVariable(scope.receiver(), V8Converter::st ringToDart(args[1])); | |
256 ASSERT(!Dart_IsError(variable) && !Dart_IsNull(variable)); | |
257 | |
258 Dart_Handle result; | |
259 UNUSED_PARAM(result); | |
260 | |
261 bool isStatic; | |
262 result = Dart_VariableIsStatic(variable, &isStatic); | |
263 ASSERT(!Dart_IsError(result)); | |
264 bool isFinal; | |
265 result = Dart_VariableIsFinal(variable, &isFinal); | |
266 ASSERT(!Dart_IsError(result)); | |
267 | |
268 v8::Local<v8::Object> description = v8::Object::New(); | |
269 description->Set(v8::String::New("isStatic"), v8::Boolean::New(isStatic)); | |
270 description->Set(v8::String::New("isFinal"), v8::Boolean::New(isFinal)); | |
271 return description; | |
272 } | |
273 | |
274 // --- Constructors, Methods, and Fields --- | |
275 | |
276 static v8::Handle<v8::Value> invoke(const v8::Arguments& args) | |
277 { | |
278 DartReceiverScope scope(args); | |
279 Vector<Dart_Handle> dartFunctionArgs; | |
280 v8::Handle<v8::Array> v8FunctionArgs = args[2].As<v8::Array>(); | |
281 for (uint32_t i = 0; i < v8FunctionArgs->Length(); ++i) | |
282 dartFunctionArgs.append(unwrapValue(v8FunctionArgs->Get(i))); | |
283 return convertResult(Dart_Invoke(scope.receiver(), V8Converter::stringToDart (args[1]), dartFunctionArgs.size(), dartFunctionArgs.data())); | |
284 } | |
285 | |
286 static v8::Handle<v8::Value> dartNew(const v8::Arguments& args) | |
287 { | |
288 DartReceiverScope scope(args); | |
289 Vector<Dart_Handle> dartConstructorArgs; | |
290 v8::Handle<v8::Array> v8ConstructorArgs = args[2].As<v8::Array>(); | |
291 for (uint32_t i = 0; i < v8ConstructorArgs->Length(); ++i) | |
292 dartConstructorArgs.append(unwrapValue(v8ConstructorArgs->Get(i))); | |
293 return convertResult(Dart_New(scope.receiver(), V8Converter::stringToDart(ar gs[1]), dartConstructorArgs.size(), dartConstructorArgs.data())); | |
294 } | |
295 | |
296 static v8::Handle<v8::Value> getField(const v8::Arguments& args) | |
297 { | |
298 DartReceiverScope scope(args); | |
299 | |
300 return convertResult(Dart_GetField(scope.receiver(), V8Converter::stringToDa rt(args[1]))); | |
301 } | |
302 | |
303 static v8::Handle<v8::Value> setField(const v8::Arguments& args) | |
304 { | |
305 DartReceiverScope scope(args); | |
306 v8::Handle<v8::Array> v8FunctionArgs = args[2].As<v8::Array>(); | |
307 ASSERT(v8FunctionArgs->Length() == 1); | |
308 return convertResult(Dart_SetField(scope.receiver(), V8Converter::stringToDa rt(args[1]), unwrapValue(v8FunctionArgs->Get(0)))); | |
309 } | |
310 | |
311 // --- Scripts and Libraries --- | |
312 | |
313 static v8::Handle<v8::Value> libraryName(const v8::Arguments& args) | |
314 { | |
315 DartReceiverScope scope(args); | |
316 return convertResult(Dart_LibraryName(scope.receiver())); | |
317 } | |
318 | |
319 static v8::Handle<v8::Value> libraryUrl(const v8::Arguments& args) | |
320 { | |
321 DartReceiverScope scope(args); | |
322 return convertResult(Dart_LibraryUrl(scope.receiver())); | |
323 } | |
324 | |
325 static v8::Handle<v8::Value> libraryImports(const v8::Arguments& args) | |
326 { | |
327 DartReceiverScope scope(args); | |
328 int32_t libraryId = args[0].As<v8::Object>()->GetHiddenValue(v8::String::New ("libraryId"))->Int32Value(); | |
329 Dart_Handle imports = Dart_GetLibraryImports(libraryId); | |
330 ASSERT(!Dart_IsError(imports)); | |
331 intptr_t length = 0; | |
332 Dart_ListLength(imports, &length); | |
333 v8::Handle<v8::Array> result = v8::Array::New(); | |
334 for (intptr_t i = 0; i < length; i += 2) { | |
335 Dart_Handle prefix = Dart_ListGetAt(imports, i); | |
336 result->Set(i, DartHandleProxy::create(prefix)); | |
337 Dart_Handle importedLibraryIdHandle = Dart_ListGetAt(imports, i + 1); | |
338 ASSERT(Dart_IsInteger(importedLibraryIdHandle)); | |
339 int64_t importedLibraryId; | |
340 Dart_IntegerToInt64(importedLibraryIdHandle, &importedLibraryId); | |
341 result->Set(i + 1, DartHandleProxy::createForLibrary(importedLibraryId)) ; | |
342 } | |
343 return result; | |
344 } | |
345 | |
346 void DartHandleProxy::getMirrorAPI(v8::Handle<v8::Object> container) | |
347 { | |
348 V8Scope v8scope; | |
349 container->Set(v8::String::New("instanceGetClass"), v8::FunctionTemplate::Ne w(&instanceGetClass)->GetFunction()); | |
350 container->Set(v8::String::New("isList"), v8::FunctionTemplate::New(&isList) ->GetFunction()); | |
351 container->Set(v8::String::New("listGetAt"), v8::FunctionTemplate::New(&list GetAt)->GetFunction()); | |
352 container->Set(v8::String::New("listSetAt"), v8::FunctionTemplate::New(&list SetAt)->GetFunction()); | |
353 container->Set(v8::String::New("className"), v8::FunctionTemplate::New(&clas sName)->GetFunction()); | |
354 container->Set(v8::String::New("classGetLibrary"), v8::FunctionTemplate::New (&classGetLibrary)->GetFunction()); | |
355 container->Set(v8::String::New("getSuperclass"), v8::FunctionTemplate::New(& getSuperclass)->GetFunction()); | |
356 container->Set(v8::String::New("getFunctionNames"), v8::FunctionTemplate::Ne w(&getFunctionNames)->GetFunction()); | |
357 container->Set(v8::String::New("getClassNames"), v8::FunctionTemplate::New(& getClassNames)->GetFunction()); | |
358 container->Set(v8::String::New("lookupFunction"), v8::FunctionTemplate::New( &lookupFunction)->GetFunction()); | |
359 container->Set(v8::String::New("lookupClass"), v8::FunctionTemplate::New(&lo okupClass)->GetFunction()); | |
360 container->Set(v8::String::New("getVariableNames"), v8::FunctionTemplate::Ne w(&getVariableNames)->GetFunction()); | |
361 container->Set(v8::String::New("lookupVariable"), v8::FunctionTemplate::New( &lookupVariable)->GetFunction()); | |
362 container->Set(v8::String::New("invoke"), v8::FunctionTemplate::New(&invoke) ->GetFunction()); | |
363 container->Set(v8::String::New("dartNew"), v8::FunctionTemplate::New(&dartNe w)->GetFunction()); | |
364 container->Set(v8::String::New("getField"), v8::FunctionTemplate::New(&getFi eld)->GetFunction()); | |
365 container->Set(v8::String::New("setField"), v8::FunctionTemplate::New(&setFi eld)->GetFunction()); | |
366 container->Set(v8::String::New("libraryName"), v8::FunctionTemplate::New(&li braryName)->GetFunction()); | |
367 container->Set(v8::String::New("libraryUrl"), v8::FunctionTemplate::New(&lib raryUrl)->GetFunction()); | |
368 container->Set(v8::String::New("libraryImports"), v8::FunctionTemplate::New( &libraryImports)->GetFunction()); | |
369 } | |
370 | |
371 } | |
OLD | NEW |