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

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

Powered by Google App Engine
This is Rietveld 408576698