OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 12 matching lines...) Expand all Loading... |
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 } | |
OLD | NEW |