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