Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Side by Side Diff: Source/bindings/dart/DartHandleProxy.cpp

Issue 18169002: Improve Dart Debugger performance and robustness by creating Dart wrappers using the standard SetNa… (Closed) Base URL: svn://svn.chromium.org/multivm/trunk/webkit
Patch Set: code review fixes Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 12 matching lines...) Expand all
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 "bindings/dart/DartHandleProxy.h" 31 #include "bindings/dart/DartHandleProxy.h"
32 32
33 #include "DartNode.h"
33 #include "bindings/dart/DartScriptValue.h" 34 #include "bindings/dart/DartScriptValue.h"
34 #include "bindings/dart/DartUtilities.h" 35 #include "bindings/dart/DartUtilities.h"
35 #include "bindings/dart/V8Converter.h" 36 #include "bindings/dart/V8Converter.h"
37 #include "bindings/v8/PageScriptDebugServer.h"
38 #include "bindings/v8/ScriptController.h"
39 #include "bindings/v8/ScriptState.h"
40 #include "bindings/v8/V8Binding.h"
41
42 #include "wtf/StdLibExtras.h"
36 43
37 #include <dart_debugger_api.h> 44 #include <dart_debugger_api.h>
38 45
39 namespace WebCore { 46 namespace WebCore {
40 47
41 static v8::Persistent<v8::FunctionTemplate> proxyTemplate(); 48 typedef HashMap<String, v8::Persistent<v8::FunctionTemplate> > FunctionTemplateM ap;
42 49
43 static DartScriptValue* readPointerFromProxy(v8::Handle<v8::Value> proxy) 50 static v8::Persistent<v8::FunctionTemplate> objectProxyTemplate(Dart_Handle inst ance);
51 static v8::Persistent<v8::FunctionTemplate> functionProxyTemplate();
52 static v8::Persistent<v8::FunctionTemplate> libraryProxyTemplate();
53 static v8::Persistent<v8::FunctionTemplate> classProxyTemplate(Dart_Handle clazz );
54 static v8::Persistent<v8::FunctionTemplate> frameProxyTemplate();
55
56 DartScriptValue* readPointerFromProxy(v8::Handle<v8::Value> proxy)
44 { 57 {
45 void* pointer = proxy.As<v8::Object>()->GetAlignedPointerFromInternalField(0 ); 58 void* pointer = proxy.As<v8::Object>()->GetAlignedPointerFromInternalField(0 );
46 return static_cast<DartScriptValue*>(pointer); 59 return static_cast<DartScriptValue*>(pointer);
47 } 60 }
48 61
49 static void weakCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* proxy , void*) 62 static void weakCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* proxy , void*)
50 { 63 {
51 delete readPointerFromProxy(*proxy); 64 delete readPointerFromProxy(*proxy);
52 proxy->Dispose(isolate); 65 proxy->Dispose(isolate);
53 } 66 }
54 67
68 static Dart_Handle unwrapValue(v8::Handle<v8::Value> value)
69 {
70 if (DartHandleProxy::isDartProxy(value))
71 return Dart_HandleFromPersistent(readPointerFromProxy(value)->value());
72
73 Dart_Handle exception = 0;
74 Dart_Handle handle = V8Converter::toDart(value, exception);
75 ASSERT(!exception);
76 return handle;
77 }
78
79 bool libraryHasMember(Dart_Handle library, Dart_Handle name)
80 {
81 return !Dart_IsError(Dart_GetField(library, name))
82 || !Dart_IsError(Dart_GetClass(library, name))
83 || Dart_IsFunction(Dart_LookupFunction(library, name));
84 }
85
86 bool classHasMember(Dart_Handle clazz, Dart_Handle name)
87 {
88 return !Dart_IsError(Dart_GetField(clazz, name)) || Dart_IsFunction(Dart_Loo kupFunction(clazz, name));
89 }
90
91 Dart_Handle getEncodedMapKeyList(Dart_Handle object)
92 {
93 return DartUtilities::invokeUtilsMethod("getEncodedMapKeyList", 1, &object);
94 }
95
96 Dart_Handle stripTrailingDot(Dart_Handle str)
97 {
98 return DartUtilities::invokeUtilsMethod("stripTrailingDot", 1, &str);
99 }
100
101 Dart_Handle addTrailingDot(Dart_Handle str)
102 {
103 return DartUtilities::invokeUtilsMethod("addTrailingDot", 1, &str);
104 }
105
106 Dart_Handle lookupValueForEncodedMapKey(Dart_Handle object, Dart_Handle key)
107 {
108 Dart_Handle args[] = {object, key};
109 return DartUtilities::invokeUtilsMethod("lookupValueForEncodedMapKey", 2, ar gs);
110 }
111
112 Dart_Handle buildConstructorName(Dart_Handle className, Dart_Handle constructorN ame)
113 {
114 Dart_Handle args[] = {className, constructorName};
115 return DartUtilities::invokeUtilsMethod("buildConstructorName", 2, args);
116 }
117
118 Dart_Handle stripClassName(Dart_Handle str, Dart_Handle className)
119 {
120 Dart_Handle args[] = {str, className};
121 return DartUtilities::invokeUtilsMethod("stripClassName", 2, args);
122 }
123
124 bool isNode(Dart_Handle clazz)
125 {
126 // We have to check that toNativeNode does not return null because
127 // non-native classes can implement the Node interface.
128 Dart_Handle exception = 0;
129 bool ret = DartUtilities::dartToBool(DartUtilities::invokeUtilsMethod("isNod e", 1, &clazz), exception)
130 && DartNode::toNative(clazz, exception);
131 ASSERT(!exception);
132 return ret;
133 }
134
135 Dart_Handle createLocalVariablesMap(Dart_Handle localVariablesList)
136 {
137 return DartUtilities::invokeUtilsMethod("createLocalVariablesMap", 1, &local VariablesList);
138 }
139
140 Dart_Handle getMapKeyList(Dart_Handle localVariablesMap)
141 {
142 return DartUtilities::invokeUtilsMethod("getMapKeyList", 1, &localVariablesM ap);
143 }
144
145 bool mapContainsKey(Dart_Handle map, Dart_Handle key)
146 {
147 Dart_Handle exception = 0;
148 return DartUtilities::dartToBool(Dart_Invoke(map, Dart_NewStringFromCString( "containsKey"), 1, &key), exception);
149 }
150
151 void addFunctionNames(Dart_Handle handle, v8::Local<v8::Array>& properties, intp tr_t* count, bool isInstance, bool noMethods)
152 {
153 intptr_t length = 0;
154 Dart_Handle functionNames = Dart_GetFunctionNames(handle);
155 ASSERT(!Dart_IsError(functionNames));
156 bool isLibrary = Dart_IsLibrary(handle);
157 Dart_ListLength(functionNames, &length);
158 for (intptr_t i = 0; i < length; i++) {
159 Dart_Handle functionName = Dart_ListGetAt(functionNames, i);
160 Dart_Handle function = Dart_LookupFunction(handle, functionName);
161 bool isStatic = false;
162 Dart_FunctionIsStatic(function, &isStatic);
163
164 bool isConstructor = false;
165 Dart_FunctionIsConstructor(function, &isConstructor);
166
167 if (!isLibrary) {
168 if (isInstance && (isStatic || isConstructor))
169 continue;
170
171 bool isSetter = false;
172 Dart_FunctionIsSetter(function, &isSetter);
173 bool isGetter = false;
174 Dart_FunctionIsGetter(function, &isGetter);
175
176 if (noMethods && !isSetter && !isGetter)
177 continue;
178
179 if (isInstance && (isSetter || isStatic || isConstructor))
180 continue;
181 }
182
183 // Strip off the leading classname from constructor name.
184 if (isConstructor)
185 functionName = stripClassName(functionName, Dart_ClassName(handle));
186
187 properties->Set(*count, V8Converter::stringToV8(functionName));
188 *count = *count + 1;
189 }
190 }
191
192 void addClassNames(Dart_Handle library, v8::Local<v8::Array>& properties, intptr _t* count)
193 {
194 intptr_t length = 0;
195 Dart_Handle classNames = Dart_LibraryGetClassNames(library);
196 ASSERT(!Dart_IsNull(classNames));
197 ASSERT(Dart_IsList(classNames));
198 Dart_ListLength(classNames, &length);
199 for (intptr_t i = 0; i < length; i++) {
200 Dart_Handle className = Dart_ListGetAt(classNames, i);
201 properties->Set(*count, V8Converter::stringToV8(className));
202 *count = *count + 1;
203 }
204 }
205
206 void addFieldNames(intptr_t libraryId, v8::Local<v8::Array>& properties, intptr_ t* count)
207 {
208 intptr_t length = 0;
209 Dart_Handle fieldNames = Dart_GetLibraryFields(libraryId);
210 ASSERT(!Dart_IsNull(fieldNames));
211 ASSERT(Dart_IsList(fieldNames));
212 Dart_ListLength(fieldNames, &length);
213 for (intptr_t i = 0; i < length; i += 2) {
214 Dart_Handle fieldName = Dart_ListGetAt(fieldNames, i);
215 properties->Set(*count, V8Converter::stringToV8(fieldName));
216 *count = *count + 1;
217 }
218 }
219
220 static v8::Handle<v8::Value> convertResult(Dart_Handle result)
221 {
222 if (Dart_IsError(result)) {
223 // FIXME: we would really prefer to call the following however it has
224 // bad unintended consequences as then JS cannot catch the thrown except ion.
225 // DartUtilities::reportProblem(DartUtilities::scriptExecutionContext(), result);
226 // return v8::Undefined();
227
228 return v8::ThrowException(v8::String::New(Dart_GetError(result)));
229 }
230 return DartHandleProxy::create(result);
231 }
232
233 void setDartHandleInternalField(v8::Local<v8::Object> proxy, Dart_Handle value)
234 {
235 proxy->SetAlignedPointerInInternalField(0, new DartScriptValue(value));
236 v8::Isolate* isolate = v8::Isolate::GetCurrent();
237 v8::Persistent<v8::Object> persistentHandle = v8::Persistent<v8::Object>::Ne w(isolate, proxy);
238 persistentHandle.MakeWeak<v8::Object, void>(0, &weakCallback);
239 }
240
241 intptr_t getLibraryId(v8::Local<v8::Object> proxy)
242 {
243 return (intptr_t)proxy.As<v8::Object>()->GetHiddenValue(v8::String::NewSymbo l("libraryId"))->Int32Value();
244 }
245
246 // Returns a String of the library prefix or Dart_Null if no prefix is found.
247 Dart_Handle getLibraryPrefix(v8::Local<v8::Object> proxy)
248 {
249 v8::Local<v8::Value> prefix = proxy.As<v8::Object>()->GetHiddenValue(v8::Str ing::NewSymbol("prefix"));
250 if (*prefix && prefix->IsString())
251 return V8Converter::stringToDart(prefix);
252 return Dart_Null();
253 }
254
255 static v8::Handle<v8::Value> functionNamedPropertyGetter(v8::Local<v8::String> n ame, const v8::AccessorInfo& info)
256 {
257 DartScriptValue* scriptValue = readPointerFromProxy(info.This());
258 ASSERT(scriptValue->isIsolateAlive());
259 DartIsolateScope scope(scriptValue->isolate());
260 DartApiScope apiScope;
261 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
262
263 Dart_Handle ret;
264 ASSERT(Dart_IsFunction(handle) || Dart_IsClosure(handle));
265
266 ret = Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::S tring::New("get:"), name)), 0, 0);
267 if (Dart_IsError(ret) && name->Equals(v8::String::NewSymbol("__proto__")))
268 return v8::Undefined();
269
270 return convertResult(ret);
271 }
272
273 static v8::Handle<v8::Value> functionNamedPropertySetter(v8::Local<v8::String> p roperty, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
274 {
275 return throwError(v8ReferenceError, "Dart functions do not have writeable pr operties", v8::Isolate::GetCurrent());
276 }
277
278 static v8::Handle<v8::Value> functionInvocationCallback(v8::Arguments const& arg s)
279 {
280 DartScriptValue* scriptValue = readPointerFromProxy(args.Holder());
281 ASSERT(scriptValue->isIsolateAlive());
282 DartIsolateScope scope(scriptValue->isolate());
283 DartApiScope apiScope;
284 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
285
286 ASSERT(Dart_IsFunction(handle) || Dart_IsClosure(handle));
287 bool isConstructor = false;
288 Dart_FunctionIsConstructor(handle, &isConstructor);
289 if (args.IsConstructCall() != isConstructor) {
290 return throwError(v8ReferenceError,
291 isConstructor ? "Constructor called without new" : "Regular function called as constructor",
292 v8::Isolate::GetCurrent());
293 }
294
295 Vector<Dart_Handle> dartFunctionArgs;
296 for (uint32_t i = 0; i < args.Length(); ++i)
297 dartFunctionArgs.append(unwrapValue(args[i]));
298
299 if (Dart_IsClosure(handle))
300 return convertResult(Dart_InvokeClosure(handle, dartFunctionArgs.size(), dartFunctionArgs.data()));
301 Dart_Handle clazz = Dart_FunctionOwner(handle);
302 if (isConstructor)
303 // FIXME: this seems like an overly complex way to have to invoke a cons tructor.
304 return convertResult(
305 Dart_New(clazz, stripClassName(Dart_FunctionName(handle), Dart_Class Name(clazz)),
306 dartFunctionArgs.size(), dartFunctionArgs.data()));
307 else
308 return convertResult(
309 Dart_Invoke(clazz, Dart_FunctionName(handle), dartFunctionArgs.size( ), dartFunctionArgs.data()));
310 }
311
312 static v8::Handle<v8::Value> classProxyConstructorInvocationCallback(v8::Argumen ts const& args)
313 {
314 DartScriptValue* scriptValue = readPointerFromProxy(args.Holder());
315 ASSERT(scriptValue->isIsolateAlive());
316 DartIsolateScope scope(scriptValue->isolate());
317 DartApiScope apiScope;
318 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
319
320 ASSERT(Dart_IsClass(handle));
321
322 if (!args.IsConstructCall())
323 return throwError(v8SyntaxError, "Constructors can only be invoked with 'new'", v8::Isolate::GetCurrent());
324
325 Vector<Dart_Handle> dartFunctionArgs;
326 for (uint32_t i = 0; i < args.Length(); ++i)
327 dartFunctionArgs.append(unwrapValue(args[i]));
328
329 return convertResult(Dart_New(handle, Dart_Null(), dartFunctionArgs.size(), dartFunctionArgs.data()));
330 }
331
332 void getImportedLibrariesMatchingPrefix(int32_t libraryId, Dart_Handle prefix, V ector<std::pair<Dart_Handle, intptr_t> >* libraries)
333 {
334 Dart_Handle imports = Dart_GetLibraryImports(libraryId);
335 ASSERT(!Dart_IsError(imports));
336 // Unfortunately dart_debugger_api.h adds a trailing dot to import prefixes.
337 if (!Dart_IsNull(prefix))
338 prefix = addTrailingDot(prefix);
339 intptr_t length = 0;
340 Dart_ListLength(imports, &length);
341 for (intptr_t i = 0; i < length; i += 2) {
342 Dart_Handle importPrefix = Dart_ListGetAt(imports, i);
343 ASSERT(Dart_IsNull(importPrefix) || Dart_IsString(importPrefix));
344 bool equals = false;
345 Dart_Handle result = Dart_ObjectEquals(prefix, importPrefix, &equals);
346 ASSERT(!Dart_IsError(result));
347 if (equals) {
348 Dart_Handle importedLibraryIdHandle = Dart_ListGetAt(imports, i + 1) ;
349 ASSERT(Dart_IsInteger(importedLibraryIdHandle));
350 int64_t importedLibraryId;
351 Dart_IntegerToInt64(importedLibraryIdHandle, &importedLibraryId);
352 Dart_Handle libraryURL = Dart_GetLibraryURL(importedLibraryId);
353 ASSERT(!Dart_IsError(libraryURL));
354 Dart_Handle library = Dart_LookupLibrary(libraryURL);
355 ASSERT(Dart_IsLibrary(library));
356 libraries->append(std::pair<Dart_Handle, intptr_t>(library, imported LibraryId));
357 }
358 }
359 }
360
361 static v8::Handle<v8::Value> libraryNamedPropertyGetterHelper(Dart_Handle librar y, Dart_Handle dartName, bool* handled)
362 {
363 Dart_Handle ret;
364 ret = Dart_GetField(library, dartName);
365 if (!Dart_IsApiError(ret)) {
366 *handled = true;
367 return convertResult(ret);
368 }
369
370 ret = Dart_GetClass(library, dartName);
371 if (!Dart_IsError(ret)) {
372 *handled = true;
373 return convertResult(ret);
374 }
375
376 ret = Dart_LookupFunction(library, dartName);
377 if (!Dart_IsNull(ret) && !Dart_IsError(ret)) {
378 *handled = true;
379 return convertResult(ret);
380 }
381 return v8::Undefined();
382 }
383
384 static v8::Handle<v8::Value> libraryNamedPropertyGetterHelper(v8::Local<v8::Stri ng> name,
385 const v8::AccessorInfo& info, bool* handled)
386 {
387 DartScriptValue* scriptValue = readPointerFromProxy(info.This());
388 ASSERT(scriptValue->isIsolateAlive());
389 DartIsolateScope scope(scriptValue->isolate());
390 DartApiScope apiScope;
391 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
392
393 Dart_Handle ret;
394 ASSERT(Dart_IsLibrary(handle));
395 intptr_t libraryId = getLibraryId(info.This());
396 Dart_Handle dartName = V8Converter::stringToDart(name);
397 Dart_Handle prefix = getLibraryPrefix(info.This());
398 bool hasLibraryPrefix = !Dart_IsNull(prefix) && Dart_IsString(prefix);
399
400 if (hasLibraryPrefix) {
401 Vector<std::pair<Dart_Handle, intptr_t> > libraries;
402 getImportedLibrariesMatchingPrefix(libraryId, prefix, &libraries);
403 for (size_t i = 0; i < libraries.size(); i++) {
404 v8::Handle<v8::Value> returnValue = libraryNamedPropertyGetterHelper (libraries[i].first, dartName, handled);
405 if (*handled)
406 return returnValue;
407 }
408 } else {
409 v8::Handle<v8::Value> returnValue = libraryNamedPropertyGetterHelper(han dle, dartName, handled);
410 if (*handled)
411 return returnValue;
412
413 // Check whether there is at least one library imported with the specifi ed prefix.
414 Vector<std::pair<Dart_Handle, intptr_t> > libraries;
415 getImportedLibrariesMatchingPrefix(libraryId, dartName, &libraries);
416 if (libraries.size() > 0) {
417 *handled = true;
418 return DartHandleProxy::createLibraryProxy(handle, libraryId, dartNa me);
419 }
420 }
421
422 if (name->Equals(v8::String::NewSymbol("__proto__"))) {
423 *handled = true;
424 return v8::Null();
425 }
426 return v8::Undefined();
427 }
428
429 static v8::Handle<v8::Value> libraryNamedPropertyGetter(v8::Local<v8::String> na me, const v8::AccessorInfo& info)
430 {
431 bool handled = false;
432 v8::Handle<v8::Value> ret = libraryNamedPropertyGetterHelper(name, info, &ha ndled);
433 if (handled)
434 return ret;
435 return v8::ThrowException(v8::Exception::ReferenceError(v8::String::Concat(n ame, v8::String::New(" is not defined"))));
436 }
437
438 // FIXME: we need to handle prefixes when setting library properties as well
439 // for completness. Postponing implementing this for now as we hope Dart_Invoke
440 // can just be fixed to handle libraries correctly.
441 static v8::Handle<v8::Value> libraryNamedPropertySetter(v8::Local<v8::String> pr operty, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
442 {
443 DartScriptValue* scriptValue = readPointerFromProxy(info.This());
444 ASSERT(scriptValue->isIsolateAlive());
445 DartIsolateScope scope(scriptValue->isolate());
446 DartApiScope apiScope;
447 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
448
449 Dart_Handle ret;
450 ASSERT(Dart_IsLibrary(handle));
451 Dart_Handle dartValue = unwrapValue(value);
452 ret = Dart_SetField(handle, V8Converter::stringToDart(property), dartValue);
453 return convertResult(ret);
454 }
455
456 static v8::Handle<v8::Integer> libraryQueryProperty(v8::Local<v8::String> name, const v8::AccessorInfo& info)
457 {
458 bool handled = false;
459 libraryNamedPropertyGetterHelper(name, info, &handled);
460 return handled ? v8Integer(0, info.GetIsolate()) : v8::Handle<v8::Integer>() ;
461 }
462
463 void libraryEnumerateHelper(Dart_Handle library, intptr_t libraryId, v8::Local<v 8::Array> properties, intptr_t* count)
464 {
465 addFunctionNames(library, properties, count, false, false);
466 addClassNames(library, properties, count);
467 addFieldNames(libraryId, properties, count);
468 }
469
470 static v8::Handle<v8::Array> libraryPropertyEnumerator(const v8::AccessorInfo& i nfo)
471 {
472 DartScriptValue* scriptValue = readPointerFromProxy(info.This());
473 ASSERT(scriptValue->isIsolateAlive());
474 DartIsolateScope scope(scriptValue->isolate());
475 DartApiScope apiScope;
476 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
477
478 intptr_t libraryId = getLibraryId(info.This());
479 ASSERT(Dart_IsLibrary(handle));
480 v8::Local<v8::Array> cachedProperties = info.This().As<v8::Object>()->GetHid denValue(v8::String::NewSymbol("cache")).As<v8::Array>();
481 if (*cachedProperties)
482 return cachedProperties;
483
484 Dart_Handle prefix = getLibraryPrefix(info.This());
485 bool hasLibraryPrefix = Dart_IsString(prefix);
486
487 v8::Local<v8::Array> properties = v8::Array::New();
488 intptr_t count = 0;
489
490 if (hasLibraryPrefix) {
491 Vector<std::pair<Dart_Handle, intptr_t> > libraries;
492 getImportedLibrariesMatchingPrefix(libraryId, prefix, &libraries);
493 for (intptr_t i = 0; i < libraries.size(); i++)
494 libraryEnumerateHelper(libraries[i].first, libraries[i].second, prop erties, &count);
495 } else {
496 libraryEnumerateHelper(handle, libraryId, properties, &count);
497 // Add all library prefixes of imports to the library.
498 Dart_Handle imports = Dart_GetLibraryImports(libraryId);
499 ASSERT(!Dart_IsError(imports));
500 intptr_t length = 0;
501 Dart_ListLength(imports, &length);
502 for (intptr_t i = 0; i < length; i += 2) {
503 Dart_Handle importPrefix = Dart_ListGetAt(imports, i);
504 if (!Dart_IsNull(importPrefix)) {
505 ASSERT(Dart_IsString(importPrefix));
506 properties->Set(count, V8Converter::stringToV8(
507 stripTrailingDot(importPrefix)));
508 count++;
509 }
510 bool equals = false;
511 }
512 }
513 info.This()->SetHiddenValue(v8::String::NewSymbol("cache"), properties);
514 return properties;
515 }
516
517 static v8::Handle<v8::Value> classNamedPropertyGetter(v8::Local<v8::String> name , const v8::AccessorInfo& info)
518 {
519 DartScriptValue* scriptValue = readPointerFromProxy(info.This());
520 ASSERT(scriptValue->isIsolateAlive());
521 DartIsolateScope scope(scriptValue->isolate());
522 DartApiScope apiScope;
523 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
524
525 Dart_Handle ret;
526 ASSERT(Dart_IsClass(handle));
527 // FIXME: we have to check for "dynamic" explicitly due to dartbug.com/11807
528 bool isDynamic = false;
529 Dart_ObjectEquals(Dart_ClassName(handle), Dart_NewStringFromCString("dynamic "), &isDynamic);
530
531 if (!Dart_ClassIsTypedef(handle) && !Dart_ClassIsFunctionType(handle) && !is Dynamic) {
532
533 Dart_Handle dartName = V8Converter::stringToDart(name);
534 ret = Dart_GetField(handle, dartName);
535 if (!Dart_IsError(ret))
536 return convertResult(ret);
537 ret = Dart_LookupFunction(handle, dartName);
538 if (!Dart_IsNull(ret) && !Dart_IsError(ret))
539 return convertResult(ret);
540
541 Dart_Handle className = Dart_ClassName(handle);
542 ASSERT(Dart_IsString(className));
543 Dart_Handle constructorName = buildConstructorName(className, V8Converte r::stringToDart(name));
544 ret = Dart_LookupFunction(handle, constructorName);
545 if (!Dart_IsNull(ret) && !Dart_IsError(ret))
546 return convertResult(ret);
547 }
548
549 if (name->Equals(v8::String::NewSymbol("__proto__"))) {
550 Dart_Handle superclass = Dart_GetSuperclass(handle);
551 if (!Dart_IsError(superclass))
552 return DartHandleProxy::create(superclass);
553 return v8::Undefined();
554 }
555 return v8::ThrowException(v8::Exception::ReferenceError(v8::String::Concat(n ame, v8::String::New(" is not defined"))));
556 }
557
558 static v8::Handle<v8::Value> classNamedPropertySetter(v8::Local<v8::String> prop erty, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
559 {
560 DartScriptValue* scriptValue = readPointerFromProxy(info.This());
561 ASSERT(scriptValue->isIsolateAlive());
562 DartIsolateScope scope(scriptValue->isolate());
563 DartApiScope apiScope;
564 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
565
566 Dart_Handle ret;
567 ASSERT(Dart_IsClass(handle));
568 Dart_Handle dartValue = unwrapValue(value);
569 ret = Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::S tring::New("set:"), property)), 1, &dartValue);
570 return convertResult(ret);
571 }
572
573 static v8::Handle<v8::Integer> classQueryProperty(v8::Local<v8::String> name, co nst v8::AccessorInfo& info)
574 {
575 DartScriptValue* scriptValue = readPointerFromProxy(info.This());
576 ASSERT(scriptValue->isIsolateAlive());
577 DartIsolateScope scope(scriptValue->isolate());
578 DartApiScope apiScope;
579 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
580
581 Dart_Handle ret;
582 ASSERT(Dart_IsClass(handle));
583 if (classHasMember(handle, V8Converter::stringToDart(name)))
584 return v8Integer(0, info.GetIsolate());
585 return v8::Handle<v8::Integer>();
586 }
587
588 static v8::Handle<v8::Array> classPropertyEnumerator(const v8::AccessorInfo& inf o)
589 {
590 DartScriptValue* scriptValue = readPointerFromProxy(info.This());
591 ASSERT(scriptValue->isIsolateAlive());
592 DartIsolateScope scope(scriptValue->isolate());
593 DartApiScope apiScope;
594 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
595
596 ASSERT(Dart_IsClass(handle));
597
598 v8::Local<v8::Array> properties = v8::Array::New();
599 intptr_t count = 0;
600 addFunctionNames(handle, properties, &count, false, false);
601 return properties;
602 }
603
604 static v8::Handle<v8::Value> frameNamedPropertyGetter(v8::Local<v8::String> name , const v8::AccessorInfo& info)
605 {
606 DartScriptValue* scriptValue = readPointerFromProxy(info.This());
607 ASSERT(scriptValue->isIsolateAlive());
608 DartIsolateScope scope(scriptValue->isolate());
609 DartApiScope apiScope;
610 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
611
612 Dart_Handle dartName = dartName;
613 if (mapContainsKey(handle, V8Converter::stringToDart(name))) {
614 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
615 Dart_Handle indexedGetterOperator = Dart_NewStringFromCString("[]");
616 Dart_Handle dartName = V8Converter::stringToDart(name);
617 return convertResult(Dart_Invoke(handle, indexedGetterOperator, 1, &dart Name));
618 }
619 if (name->Equals(v8::String::NewSymbol("this")))
620 return v8::Undefined();
621 return v8::ThrowException(v8::Exception::ReferenceError(v8::String::Concat(n ame, v8::String::New(" is not defined"))));
622 }
623
624 static v8::Handle<v8::Value> frameNamedPropertySetter(v8::Local<v8::String> prop erty, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
625 {
626 return throwError(v8ReferenceError, "Dart does not yet provide a debugger ap i for setting local fields", v8::Isolate::GetCurrent());
627 }
628
629 static v8::Handle<v8::Integer> frameQueryProperty(v8::Local<v8::String> name, co nst v8::AccessorInfo& info)
630 {
631 DartScriptValue* scriptValue = readPointerFromProxy(info.This());
632 ASSERT(scriptValue->isIsolateAlive());
633 DartIsolateScope scope(scriptValue->isolate());
634 DartApiScope apiScope;
635 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
636
637 return mapContainsKey(handle, V8Converter::stringToDart(name)) ? v8Integer(0 , info.GetIsolate()) : v8::Handle<v8::Integer>();
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 keyList = getMapKeyList(Dart_HandleFromPersistent(scriptValue->v alue()));
647 ASSERT(!Dart_IsError(keyList));
648 ASSERT(Dart_IsList(keyList));
649
650 intptr_t length = 0;
651 Dart_ListLength(keyList, &length);
652 v8::Local<v8::Array> properties = v8::Array::New(length);
653 for (intptr_t i = 0; i < length; i ++)
654 properties->Set(i, V8Converter::stringToV8(Dart_ListGetAt(keyList, i)));
655 return properties;
656 }
657
658 static v8::Handle<v8::Value> namedPropertyGetter(v8::Local<v8::String> name, con st v8::AccessorInfo& info)
659 {
660 DartScriptValue* scriptValue = readPointerFromProxy(info.This());
661 ASSERT(scriptValue->isIsolateAlive());
662 DartIsolateScope scope(scriptValue->isolate());
663 DartApiScope apiScope;
664 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
665
666 Dart_Handle ret;
667 ASSERT(Dart_IsInstance(handle));
668 v8::String::Utf8Value stringName(name);
669 const char* data = *stringName;
670 if (data[0] == ':' || data[0] == '#') {
671 // Look up a map key instead of a regular property as regular dart prope rty names
672 // cannot start with these symbols.
673 return convertResult(
674 lookupValueForEncodedMapKey(handle, V8Converter::stringToDart(name)) );
675 }
676
677 ret = Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::S tring::New("get:"), name)), 0, 0);
678 if (Dart_IsError(ret) && name->Equals(v8::String::NewSymbol("__proto__")))
679 return DartHandleProxy::create(Dart_GetObjClass(handle));
680
681 return convertResult(ret);
682 }
683
684 static v8::Handle<v8::Value> namedPropertySetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
685 {
686 DartScriptValue* scriptValue = readPointerFromProxy(info.This());
687 ASSERT(scriptValue->isIsolateAlive());
688 DartIsolateScope scope(scriptValue->isolate());
689 DartApiScope apiScope;
690 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
691
692 Dart_Handle dartValue = unwrapValue(value);
693 return convertResult(Dart_Invoke(handle, V8Converter::stringToDart(v8::Strin g::Concat(v8::String::New("set:"), property)), 1, &dartValue));
694 }
695
696 static v8::Handle<v8::Integer> objectQueryProperty(v8::Local<v8::String> name, c onst v8::AccessorInfo& info)
697 {
698 DartScriptValue* scriptValue = readPointerFromProxy(info.This());
699 ASSERT(scriptValue->isIsolateAlive());
700 DartIsolateScope scope(scriptValue->isolate());
701 DartApiScope apiScope;
702 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
703
704 Dart_Handle ret;
705 ASSERT(Dart_IsInstance(handle));
706 v8::String::Utf8Value stringName(name);
707 const char* data = *stringName;
708
709 // Looking up a map key instead of a regular property... as regular dart pro perty names
710 // cannot start with these symbols.
711 if (data[0] == ':' || data[0] == '#')
712 return v8Integer(0, info.GetIsolate());
713
714 ret = Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::S tring::New("get:"), name)), 0, 0);
715 if (Dart_IsError(ret)) {
716 if (name->Equals(v8::String::NewSymbol("__proto__")))
717 return v8Integer(0, info.GetIsolate());
718 return v8::Handle<v8::Integer>();
719 }
720 return v8Integer(0, info.GetIsolate());
721 }
722
723 static v8::Handle<v8::Array> objectPropertyEnumerator(const v8::AccessorInfo& in fo)
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 ASSERT(Dart_IsInstance(handle));
732
733 Dart_Handle typeHandle;
734 if (Dart_IsInstance(handle))
735 typeHandle = Dart_InstanceGetClass(handle);
736 else
737 typeHandle = handle;
738
739 v8::Local<v8::Array> properties = v8::Array::New();
740 intptr_t count = 0;
741
742 Dart_Handle mapKeys = getEncodedMapKeyList(handle);
743 if (Dart_IsList(mapKeys)) {
744 // If the object has map keys, add them all as properties at the start
745 // of the list. This aids for debugging although it risks confusing
746 // users.
747 intptr_t length = 0;
748 Dart_ListLength(mapKeys, &length);
749 for (intptr_t i = 0; i < length; i++) {
750 properties->Set(count, V8Converter::stringToV8(Dart_ListGetAt(mapKey s, i)));
751 count++;
752 }
753 }
754
755 Dart_Handle instanceFields = Dart_GetInstanceFields(handle);
756 intptr_t length = 0;
757 Dart_ListLength(instanceFields, &length);
758 for (intptr_t i = 0; i < length; i += 2) {
759 properties->Set(count, DartHandleProxy::create(
760 Dart_ListGetAt(instanceFields, i)));
761 count++;
762 }
763
764 while (!Dart_IsError(typeHandle) && !Dart_IsNull(typeHandle)) {
765 intptr_t interfaceCount = 0;
766 Dart_ClassGetInterfaceCount(typeHandle, &interfaceCount);
767 for (intptr_t i = 0; i < interfaceCount; i++) {
768 addFunctionNames(Dart_ClassGetInterfaceAt(typeHandle, i),
769 properties, &count, true, true);
770 }
771 // FIXME: do we have to add this here?
772 addFunctionNames(typeHandle, properties, &count, true, true);
773 typeHandle = Dart_GetSuperclass(typeHandle);
774 }
775 return properties;
776 }
777
778 static v8::Handle<v8::Value> indexedGetter(uint32_t index, const v8::AccessorInf o& info)
779 {
780 DartScriptValue* scriptValue = readPointerFromProxy(info.This());
781 ASSERT(scriptValue->isIsolateAlive());
782 DartIsolateScope scope(scriptValue->isolate());
783 DartApiScope apiScope;
784 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
785
786 Dart_Handle ret = 0;
787 if (Dart_IsList(handle))
788 ret = Dart_ListGetAt(handle, index);
789 else
790 ret = Dart_Null();
791
792 return convertResult(ret);
793 }
794
795 static v8::Handle<v8::Value> indexedSetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
796 {
797 DartScriptValue* scriptValue = readPointerFromProxy(info.This());
798 ASSERT(scriptValue->isIsolateAlive());
799 DartIsolateScope scope(scriptValue->isolate());
800 DartApiScope apiScope;
801 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
802
803 Dart_Handle ret = 0;
804 if (Dart_IsList(handle))
805 ret = Dart_ListSetAt(handle, index, unwrapValue(value));
806 else
807 ret = Dart_Null();
808
809 return convertResult(ret);
810 }
811
812 static v8::Handle<v8::Array> indexedEnumerator(const v8::AccessorInfo& info)
813 {
814 DartScriptValue* scriptValue = readPointerFromProxy(info.This());
815 ASSERT(scriptValue->isIsolateAlive());
816 DartIsolateScope scope(scriptValue->isolate());
817 DartApiScope apiScope;
818 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
819
820 intptr_t length = 0;
821 if (Dart_IsList(handle))
822 Dart_ListLength(handle, &length);
823
824 v8::Local<v8::Array> indexes = v8::Array::New(length);
825 for (int i = 0; i < length; i++)
826 indexes->Set(i, v8::Integer::New(i));
827
828 return indexes;
829 }
830
831 static v8::Local<v8::ObjectTemplate> setupInstanceTemplate(v8::Persistent<v8::Fu nctionTemplate> proxyTemplate)
832 {
833 v8::Local<v8::ObjectTemplate> instanceTemplate = proxyTemplate->InstanceTemp late();
834 instanceTemplate->SetInternalFieldCount(1);
835 return instanceTemplate;
836 }
837
838 static v8::Persistent<v8::FunctionTemplate> objectProxyTemplate(Dart_Handle inst ance)
839 {
840 DEFINE_STATIC_LOCAL(FunctionTemplateMap, map, ());
841 // FIXME: we should switch to Dart_InstanceGetType when possible.
842 Dart_Handle dartType = Dart_InstanceGetClass(instance);
843 ASSERT(!Dart_IsError(dartType));
844 Dart_Handle classNameHandle = Dart_ClassName(dartType);
845 ASSERT(!Dart_IsError(classNameHandle));
846 v8::Handle<v8::String> classNameV8 = V8Converter::stringToV8(classNameHandle );
847 String className = toWebCoreString(classNameV8);
848 v8::Persistent<v8::FunctionTemplate> proxyTemplate = map.get(className);
849
850 if (proxyTemplate.IsEmpty()) {
851 proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::G etCurrent(), v8::FunctionTemplate::New());
852 proxyTemplate->SetClassName(classNameV8);
853 map.set(className, proxyTemplate);
854 v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(p roxyTemplate);
855 instanceTemplate->SetIndexedPropertyHandler(&indexedGetter, &indexedSett er, 0, 0, &indexedEnumerator);
856 instanceTemplate->SetNamedPropertyHandler(&namedPropertyGetter, &namedPr opertySetter, &objectQueryProperty, 0, &objectPropertyEnumerator);
857 }
858 return proxyTemplate;
859 }
860
861 static v8::Persistent<v8::FunctionTemplate> functionProxyTemplate()
862 {
863 static v8::Persistent<v8::FunctionTemplate> proxyTemplate;
864 if (proxyTemplate.IsEmpty()) {
865 proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::G etCurrent(), v8::FunctionTemplate::New());
866 proxyTemplate->SetClassName(v8::String::New("[Dart Function]"));
867 v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(p roxyTemplate);
868 instanceTemplate->SetNamedPropertyHandler(&functionNamedPropertyGetter, &functionNamedPropertySetter);
869 instanceTemplate->SetCallAsFunctionHandler(&functionInvocationCallback);
870 }
871 return proxyTemplate;
872 }
873
874 static v8::Persistent<v8::FunctionTemplate> libraryProxyTemplate()
875 {
876 static v8::Persistent<v8::FunctionTemplate> proxyTemplate;
877 if (proxyTemplate.IsEmpty()) {
878 proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::G etCurrent(), v8::FunctionTemplate::New());
879 proxyTemplate->SetClassName(v8::String::New("[Dart Library]"));
880 v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(p roxyTemplate);
881 instanceTemplate->SetNamedPropertyHandler(&libraryNamedPropertyGetter, & libraryNamedPropertySetter, &libraryQueryProperty, 0, &libraryPropertyEnumerator );
882 }
883 return proxyTemplate;
884 }
885
886 static v8::Persistent<v8::FunctionTemplate> classProxyTemplate(Dart_Handle clazz )
887 {
888 DEFINE_STATIC_LOCAL(FunctionTemplateMap, map, ());
889 Dart_Handle classNameHandle = Dart_ClassName(clazz);
890 ASSERT(!Dart_IsError(classNameHandle));
891 v8::Handle<v8::String> classNameV8 = V8Converter::stringToV8(classNameHandle );
892 String className = toWebCoreString(classNameV8);
893
894 v8::Persistent<v8::FunctionTemplate> proxyTemplate = map.get(className);
895 if (proxyTemplate.IsEmpty()) {
896 proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::G etCurrent(), v8::FunctionTemplate::New());
897 proxyTemplate->SetClassName(classNameV8);
898 v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(p roxyTemplate);
899 instanceTemplate->SetNamedPropertyHandler(&classNamedPropertyGetter, &cl assNamedPropertySetter, &classQueryProperty, 0, &classPropertyEnumerator);
900 instanceTemplate->SetCallAsFunctionHandler(&classProxyConstructorInvocat ionCallback);
901 map.set(className, proxyTemplate);
902 }
903 return proxyTemplate;
904 }
905
906 static v8::Persistent<v8::FunctionTemplate> frameProxyTemplate()
907 {
908 static v8::Persistent<v8::FunctionTemplate> proxyTemplate;
909 if (proxyTemplate.IsEmpty()) {
910 proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::G etCurrent(), v8::FunctionTemplate::New());
911 proxyTemplate->SetClassName(v8::String::New("[Dart Frame]"));
912 v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(p roxyTemplate);
913 instanceTemplate->SetNamedPropertyHandler(&frameNamedPropertyGetter, &fr ameNamedPropertySetter, &frameQueryProperty, 0, &framePropertyEnumerator);
914 }
915 return proxyTemplate;
916 }
917
55 v8::Handle<v8::Value> DartHandleProxy::create(Dart_Handle value) 918 v8::Handle<v8::Value> DartHandleProxy::create(Dart_Handle value)
56 { 919 {
57 v8::Context::Scope scope(DartUtilities::currentV8Context()); 920 v8::Context::Scope scope(DartUtilities::currentV8Context());
58 921
59 if (Dart_IsNull(value)) 922 if (Dart_IsNull(value))
60 return v8::Null(); 923 return v8::Null();
61 if (Dart_IsString(value)) 924 if (Dart_IsString(value))
62 return V8Converter::stringToV8(value); 925 return V8Converter::stringToV8(value);
63 if (Dart_IsBoolean(value)) 926 if (Dart_IsBoolean(value))
64 return V8Converter::booleanToV8(value); 927 return V8Converter::booleanToV8(value);
65 if (Dart_IsNumber(value)) 928 if (Dart_IsNumber(value))
66 return V8Converter::numberToV8(value); 929 return V8Converter::numberToV8(value);
67 930 v8::Local<v8::Object> proxy;
68 v8::Local<v8::Object> proxy = proxyTemplate()->InstanceTemplate()->NewInstan ce(); 931
69 proxy->SetAlignedPointerInInternalField(0, new DartScriptValue(value)); 932 if (Dart_IsFunction(value) || Dart_IsClosure(value))
70 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 933 proxy = functionProxyTemplate()->InstanceTemplate()->NewInstance();
71 v8::Persistent<v8::Object> persistentHandle = v8::Persistent<v8::Object>::Ne w(isolate, proxy); 934 else if (Dart_IsInstance(value))
72 persistentHandle.MakeWeak<v8::Object, void>(0, &weakCallback); 935 proxy = objectProxyTemplate(value)->InstanceTemplate()->NewInstance();
73 proxy->Set(v8::String::New("isProxy"), v8::Boolean::New(true)); 936 else {
937 ASSERT(Dart_IsClass(value));
938 proxy = classProxyTemplate(value)->InstanceTemplate()->NewInstance();
939 }
940 setDartHandleInternalField(proxy, value);
941 proxy->SetHiddenValue(v8::String::NewSymbol("dartProxy"), v8::Boolean::New(t rue));
942
74 return proxy; 943 return proxy;
75 } 944 }
76 945
77 v8::Handle<v8::Value> DartHandleProxy::createForLibrary(intptr_t libraryId) 946 bool DartHandleProxy::isDartProxy(v8::Handle<v8::Value> value)
78 { 947 {
79 Dart_Handle libraryURL = Dart_GetLibraryURL(libraryId); 948 if (value->IsObject()) {
80 ASSERT(!Dart_IsError(libraryURL)); 949 v8::Local<v8::Value> hiddenValue = value.As<v8::Object>()->GetHiddenValu e(v8::String::NewSymbol("dartProxy"));
81 Dart_Handle library = Dart_LookupLibrary(libraryURL); 950 return *hiddenValue && hiddenValue->IsBoolean();
82 v8::Handle<v8::Object> libraryProxy = create(library)->ToObject(); 951 }
83 libraryProxy->SetHiddenValue(v8::String::New("libraryId"), v8::Number::New(l ibraryId)); 952 return false;
84 return libraryProxy; 953 }
85 } 954
86 955 const char* DartHandleProxy::getType(v8::Handle<v8::Value> value)
87 class DartReceiverScope { 956 {
88 public: 957 DartScriptValue* scriptValue = readPointerFromProxy(value);
89 DartReceiverScope(const v8::Arguments& args) 958 ASSERT(scriptValue->isIsolateAlive());
90 : m_receiver(readPointerFromProxy(args[0])) 959 DartIsolateScope scope(scriptValue->isolate());
91 , m_isolateScope(m_receiver->isolate()) 960 DartApiScope apiScope;
92 , m_apiScope() 961 Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
93 { 962
94 } 963 if (Dart_IsInstance(handle)) {
95 964 if (Dart_IsList(handle))
96 Dart_Handle receiver() { return Dart_HandleFromPersistent(m_receiver->value( )); } 965 return "array";
97 966
98 private: 967 if (isNode(handle))
99 DartScriptValue* m_receiver; 968 return "node";
100 DartIsolateScope m_isolateScope; 969 }
101 DartApiScope m_apiScope; 970
102 }; 971 return 0;
103 972 }
104 static v8::Persistent<v8::FunctionTemplate> proxyTemplate() 973
105 { 974 Node* DartHandleProxy::toNativeNode(v8::Handle<v8::Value> value)
106 static v8::Persistent<v8::FunctionTemplate> proxyTemplate; 975 {
107 if (proxyTemplate.IsEmpty()) { 976 DartScriptValue* scriptValue = readPointerFromProxy(value);
108 proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::G etCurrent(), v8::FunctionTemplate::New()); 977 ASSERT(scriptValue->isIsolateAlive());
109 v8::Local<v8::ObjectTemplate> instanceTemplate = proxyTemplate->Instance Template(); 978 DartIsolateScope scope(scriptValue->isolate());
110 instanceTemplate->SetInternalFieldCount(1); 979 DartApiScope apiScope;
111 } 980 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; 981 Dart_Handle exception = 0;
120 Dart_Handle handle = V8Converter::toDart(value, exception); 982 Node* node = DartNode::toNative(handle, exception);
121 ASSERT(!exception); 983 ASSERT(!exception);
122 return handle; 984 return node;
123 } 985 }
124 986
125 static v8::Handle<v8::Value> convertResult(Dart_Handle result) 987 /**
126 { 988 * Creates a proxy for a Dart library.
127 if (Dart_IsError(result)) { 989 * 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 990 * the specified prefix.
129 // exception wrapper. 991 */
130 return v8::String::New("<Exception thrown>"); 992 v8::Handle<v8::Value> DartHandleProxy::createLibraryProxy(Dart_Handle value, int 32_t libraryId, Dart_Handle prefix)
131 } 993 {
132 return DartHandleProxy::create(result); 994 v8::Context::Scope scope(DartUtilities::currentV8Context());
133 } 995 ASSERT(Dart_IsLibrary(value));
134 996 v8::Local<v8::Object> proxy = libraryProxyTemplate()->InstanceTemplate()->Ne wInstance();
135 // --- Objects ---- 997 setDartHandleInternalField(proxy, value);
136 998 proxy->SetHiddenValue(v8::String::NewSymbol("libraryId"), v8::Number::New(li braryId));
137 static v8::Handle<v8::Value> instanceGetClass(const v8::Arguments& args) 999 if (Dart_IsString(prefix))
138 { 1000 proxy->SetHiddenValue(v8::String::NewSymbol("prefix"), V8Converter::stri ngToV8(prefix));
139 DartReceiverScope scope(args); 1001
140 return convertResult(Dart_InstanceGetClass(scope.receiver())); 1002 proxy->SetHiddenValue(v8::String::NewSymbol("dartProxy"), v8::Boolean::New(t rue));
141 } 1003 return proxy;
142 1004 }
143 // --- Lists --- 1005
144 1006 v8::Handle<v8::Value> DartHandleProxy::createLocalScopeProxy(Dart_Handle localVa riables)
145 static v8::Handle<v8::Value> isList(const v8::Arguments& args) 1007 {
146 { 1008 v8::Local<v8::Object> proxy = frameProxyTemplate()->InstanceTemplate()->NewI nstance();
147 DartReceiverScope scope(args); 1009 Dart_Handle localScopeVariableMap = createLocalVariablesMap(localVariables);
148 return v8::Boolean::New(Dart_IsList(scope.receiver())); 1010 ASSERT(!Dart_IsError(localScopeVariableMap));
149 } 1011 setDartHandleInternalField(proxy, localScopeVariableMap);
150 1012 proxy->SetHiddenValue(v8::String::NewSymbol("dartProxy"), v8::Boolean::New(t rue));
151 static v8::Handle<v8::Value> listGetAt(const v8::Arguments& args) 1013 return proxy;
152 { 1014 }
153 DartReceiverScope scope(args); 1015
154 return convertResult(Dart_ListGetAt(scope.receiver(), args[1]->Int32Value()) ); 1016 }
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698