| OLD | NEW |
| (Empty) |
| 1 // Copyright 2011, Google Inc. | |
| 2 // All rights reserved. | |
| 3 // | |
| 4 // Redistribution and use in source and binary forms, with or without | |
| 5 // modification, are permitted provided that the following conditions are | |
| 6 // met: | |
| 7 // | |
| 8 // * Redistributions of source code must retain the above copyright | |
| 9 // notice, this list of conditions and the following disclaimer. | |
| 10 // * Redistributions in binary form must reproduce the above | |
| 11 // copyright notice, this list of conditions and the following disclaimer | |
| 12 // in the documentation and/or other materials provided with the | |
| 13 // distribution. | |
| 14 // * Neither the name of Google Inc. nor the names of its | |
| 15 // contributors may be used to endorse or promote products derived from | |
| 16 // this software without specific prior written permission. | |
| 17 // | |
| 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 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. | |
| 29 | |
| 30 #include "config.h" | |
| 31 #include "bindings/core/dart/DartUtilities.h" | |
| 32 | |
| 33 #if OS(ANDROID) | |
| 34 #include <sys/system_properties.h> | |
| 35 #endif | |
| 36 | |
| 37 #include "core/FetchInitiatorTypeNames.h" | |
| 38 #include "bindings/core/dart/DartBlob.h" | |
| 39 #include "bindings/core/dart/DartController.h" | |
| 40 #include "bindings/core/dart/DartDOMData.h" | |
| 41 #include "bindings/core/dart/DartHTMLElement.h" | |
| 42 #include "bindings/core/dart/DartImageData.h" | |
| 43 #include "bindings/core/dart/DartMessagePort.h" | |
| 44 #include "bindings/core/dart/DartScriptDebugServer.h" | |
| 45 #include "bindings/core/dart/DartScriptPromise.h" | |
| 46 #include "bindings/core/dart/DartScriptState.h" | |
| 47 #include "bindings/core/dart/V8Converter.h" | |
| 48 #include "bindings/core/v8/ScriptController.h" | |
| 49 #include "bindings/core/v8/SerializedScriptValue.h" | |
| 50 #include "bindings/core/v8/V8Binding.h" | |
| 51 #include "bindings/core/v8/V8ExceptionState.h" | |
| 52 #include "bindings/core/v8/V8PerIsolateData.h" | |
| 53 #include "bindings/modules/dart/DartIDBKeyRange.h" | |
| 54 #include "core/dom/Document.h" | |
| 55 #include "core/events/ErrorEvent.h" | |
| 56 #include "core/fetch/ResourceFetcher.h" | |
| 57 #include "core/frame/LocalDOMWindow.h" | |
| 58 #include "core/frame/LocalFrame.h" | |
| 59 #include "core/html/canvas/DataView.h" | |
| 60 #include "core/inspector/ScriptArguments.h" | |
| 61 #include "core/inspector/ScriptCallStack.h" | |
| 62 #include "core/loader/FrameLoader.h" | |
| 63 #include "modules/webdatabase/sqlite/SQLValue.h" | |
| 64 #include "platform/SharedBuffer.h" | |
| 65 #include "platform/network/ResourceRequest.h" | |
| 66 | |
| 67 #include "wtf/ArrayBufferView.h" | |
| 68 #include "wtf/Float32Array.h" | |
| 69 #include "wtf/Float64Array.h" | |
| 70 #include "wtf/Int16Array.h" | |
| 71 #include "wtf/Int32Array.h" | |
| 72 #include "wtf/Int8Array.h" | |
| 73 #include "wtf/RefCounted.h" | |
| 74 #include "wtf/Uint16Array.h" | |
| 75 #include "wtf/Uint32Array.h" | |
| 76 #include "wtf/Uint8Array.h" | |
| 77 #include "wtf/Uint8ClampedArray.h" | |
| 78 #include "wtf/text/AtomicString.h" | |
| 79 #include "wtf/text/CString.h" | |
| 80 #include "wtf/text/WTFString.h" | |
| 81 | |
| 82 namespace blink { | |
| 83 | |
| 84 // FIXMEDART: Why aren't these being linked into webkit_unit_tests? | |
| 85 class GarbageCollectedScriptWrappable; | |
| 86 class RefCountedScriptWrappable; | |
| 87 template<> | |
| 88 Dart_Handle toDartNoInline(blink::GarbageCollectedScriptWrappable* impl, DartDOM
Data* domData) { return 0; } | |
| 89 template<> | |
| 90 Dart_Handle toDartNoInline(blink::RefCountedScriptWrappable* impl, DartDOMData*
domData) { return 0; } | |
| 91 | |
| 92 V8Scope::V8Scope(DartDOMData* dartDOMData, v8::Handle<v8::Context> context) | |
| 93 : m_v8Isolate(v8::Isolate::GetCurrent()) | |
| 94 , m_dartDOMData(dartDOMData) | |
| 95 , m_handleScope(m_v8Isolate) | |
| 96 , m_contextScope(context) | |
| 97 , m_recursionScope(m_v8Isolate, DartUtilities::scriptExecutionContext()) | |
| 98 { | |
| 99 if (m_dartDOMData) | |
| 100 (*m_dartDOMData->recursion())++; | |
| 101 } | |
| 102 | |
| 103 V8Scope::V8Scope(DartDOMData* dartDOMData) | |
| 104 : m_v8Isolate(v8::Isolate::GetCurrent()) | |
| 105 , m_dartDOMData(dartDOMData) | |
| 106 , m_handleScope(m_v8Isolate) | |
| 107 , m_contextScope(DartUtilities::currentV8Context()) | |
| 108 , m_recursionScope(m_v8Isolate, DartUtilities::scriptExecutionContext()) | |
| 109 { | |
| 110 if (m_dartDOMData) | |
| 111 (*m_dartDOMData->recursion())++; | |
| 112 } | |
| 113 | |
| 114 V8Scope::~V8Scope() | |
| 115 { | |
| 116 if (m_dartDOMData) | |
| 117 (*m_dartDOMData->recursion())--; | |
| 118 } | |
| 119 | |
| 120 DartStringPeer* DartStringPeer::nullString() | |
| 121 { | |
| 122 DEFINE_STATIC_LOCAL(DartStringPeer, empty, ()); | |
| 123 return ∅ | |
| 124 } | |
| 125 | |
| 126 DartStringPeer* DartStringPeer::emptyString() | |
| 127 { | |
| 128 DEFINE_STATIC_LOCAL(DartStringPeer, empty, (StringImpl::empty())); | |
| 129 return ∅ | |
| 130 } | |
| 131 | |
| 132 | |
| 133 static void stringFinalizer(void* peer) | |
| 134 { | |
| 135 ASSERT(reinterpret_cast<DartStringPeer*>(peer) != DartStringPeer::nullString
()); | |
| 136 delete reinterpret_cast<DartStringPeer*>(peer); | |
| 137 } | |
| 138 | |
| 139 template <typename T> DartStringPeer* convertAndExternalize(Dart_Handle string,
intptr_t length) | |
| 140 { | |
| 141 if (!length) | |
| 142 return new DartStringPeer(StringImpl::empty()); | |
| 143 #ifndef NDEBUG | |
| 144 { | |
| 145 intptr_t storageSize = 0; | |
| 146 Dart_StringStorageSize(string, &storageSize); | |
| 147 ASSERT(length * intptr_t(sizeof(T)) == storageSize); | |
| 148 } | |
| 149 #endif | |
| 150 T* buffer = 0; | |
| 151 DartStringPeer* peer = new DartStringPeer(StringImpl::createUninitialized(le
ngth, buffer)); | |
| 152 Dart_Handle ALLOW_UNUSED r = Dart_MakeExternalString(string, buffer, length
* sizeof(T), peer, stringFinalizer); | |
| 153 ASSERT(!Dart_IsError(r)); | |
| 154 return peer; | |
| 155 } | |
| 156 | |
| 157 DartStringPeer* DartUtilities::toStringImpl(Dart_Handle object, intptr_t charsiz
e, intptr_t strlength) | |
| 158 { | |
| 159 ASSERT(Dart_IsString(object) && !Dart_IsExternalString(object)); | |
| 160 return (charsize == 1) ? convertAndExternalize<LChar>(object, strlength) : c
onvertAndExternalize<UChar>(object, strlength); | |
| 161 } | |
| 162 | |
| 163 | |
| 164 Dart_Handle DartUtilities::stringImplToDartString(StringImpl* stringImpl) | |
| 165 { | |
| 166 if (!stringImpl) { | |
| 167 DartDOMData* domData = DartDOMData::current(); | |
| 168 return domData->emptyString(); | |
| 169 } | |
| 170 | |
| 171 DartStringPeer* peer = new DartStringPeer(stringImpl); | |
| 172 if (stringImpl->is8Bit()) { | |
| 173 // FIXME: maybe it makes sense only externalize strings longer than cert
ain threshold, such as 5 symbols. | |
| 174 return Dart_NewExternalLatin1String(reinterpret_cast<const uint8_t*>(str
ingImpl->characters8()), | |
| 175 stringImpl->length(), peer, stringFinalizer); | |
| 176 } else { | |
| 177 // FIXME: maybe it makes sense only externalize strings longer than cert
ain threshold, such as 5 symbols. | |
| 178 return Dart_NewExternalUTF16String(reinterpret_cast<const uint16_t*>(str
ingImpl->characters16()), | |
| 179 stringImpl->length(), peer, stringFinalizer); | |
| 180 } | |
| 181 } | |
| 182 | |
| 183 Dart_Handle DartUtilities::stringToDartString(const String& str) | |
| 184 { | |
| 185 return stringImplToDartString(str.impl()); | |
| 186 } | |
| 187 | |
| 188 Dart_Handle DartUtilities::stringToDartString(const AtomicString& str) | |
| 189 { | |
| 190 return stringImplToDartString(str.impl()); | |
| 191 } | |
| 192 | |
| 193 | |
| 194 Dart_Handle DartUtilities::safeStringImplToDartString(StringImpl* stringImpl) | |
| 195 { | |
| 196 if (!stringImpl) { | |
| 197 DartDOMData* domData = DartDOMData::current(); | |
| 198 return domData->emptyString(); | |
| 199 } | |
| 200 | |
| 201 if (stringImpl->is8Bit()) { | |
| 202 return Dart_NewStringFromUTF8( | |
| 203 reinterpret_cast<const uint8_t*>(stringImpl->characters8()), | |
| 204 stringImpl->length()); | |
| 205 } else { | |
| 206 return Dart_NewStringFromUTF16( | |
| 207 reinterpret_cast<const uint16_t*>(stringImpl->characters16()), | |
| 208 stringImpl->length()); | |
| 209 } | |
| 210 } | |
| 211 | |
| 212 Dart_Handle DartUtilities::safeStringToDartString(const String& str) | |
| 213 { | |
| 214 return safeStringImplToDartString(str.impl()); | |
| 215 } | |
| 216 | |
| 217 Dart_Handle DartUtilities::safeStringToDartString(const AtomicString& str) | |
| 218 { | |
| 219 return safeStringImplToDartString(str.impl()); | |
| 220 } | |
| 221 | |
| 222 template <typename Trait> | |
| 223 typename Trait::nativeType convert(Dart_Handle object, Dart_Handle& exception) | |
| 224 { | |
| 225 typename Trait::nativeType value; | |
| 226 Dart_Handle result = Trait::convert(object, &value); | |
| 227 if (Dart_IsError(result)) { | |
| 228 exception = Dart_NewStringFromCString(Dart_GetError(result)); | |
| 229 return typename Trait::nativeType(); | |
| 230 } | |
| 231 return value; | |
| 232 } | |
| 233 | |
| 234 struct IntegerTrait { | |
| 235 typedef int64_t nativeType; | |
| 236 static Dart_Handle convert(Dart_Handle object, int64_t* value) | |
| 237 { | |
| 238 return Dart_IntegerToInt64(object, value); | |
| 239 // FIXME: support bigints. | |
| 240 } | |
| 241 }; | |
| 242 | |
| 243 int64_t DartUtilities::toInteger(Dart_Handle object, Dart_Handle& exception) | |
| 244 { | |
| 245 return convert<IntegerTrait>(object, exception); | |
| 246 } | |
| 247 | |
| 248 String DartUtilities::toString(Dart_Handle object) | |
| 249 { | |
| 250 Dart_Handle exception = 0; | |
| 251 String string = dartToString(object, exception); | |
| 252 ASSERT(!exception); | |
| 253 return string; | |
| 254 } | |
| 255 | |
| 256 struct DoubleTrait { | |
| 257 typedef double nativeType; | |
| 258 static Dart_Handle convert(Dart_Handle object, double* value) | |
| 259 { | |
| 260 if (Dart_IsDouble(object)) | |
| 261 return Dart_DoubleValue(object, value); | |
| 262 | |
| 263 if (Dart_IsInteger(object)) { | |
| 264 int64_t v = 0; | |
| 265 Dart_Handle result = Dart_IntegerToInt64(object, &v); | |
| 266 if (!Dart_IsError(result)) { | |
| 267 *value = static_cast<double>(v); | |
| 268 return result; | |
| 269 } | |
| 270 } | |
| 271 | |
| 272 if (Dart_IsNumber(object)) { | |
| 273 object = Dart_Invoke(object, Dart_NewStringFromCString("toDouble"),
0, 0); | |
| 274 if (Dart_IsError(object)) | |
| 275 return object; | |
| 276 } | |
| 277 | |
| 278 // For non-Number objects, use the error message returned by Dart_Double
Value. | |
| 279 return Dart_DoubleValue(object, value); | |
| 280 } | |
| 281 }; | |
| 282 | |
| 283 double DartUtilities::dartToDouble(Dart_Handle object, Dart_Handle& exception) | |
| 284 { | |
| 285 return convert<DoubleTrait>(object, exception); | |
| 286 } | |
| 287 | |
| 288 struct BoolTrait { | |
| 289 typedef bool nativeType; | |
| 290 static Dart_Handle convert(Dart_Handle object, bool* value) | |
| 291 { | |
| 292 if (Dart_IsNull(object)) { | |
| 293 *value = false; | |
| 294 return Dart_Null(); | |
| 295 } | |
| 296 return Dart_BooleanValue(object, value); | |
| 297 } | |
| 298 }; | |
| 299 | |
| 300 bool DartUtilities::dartToBool(Dart_Handle object, Dart_Handle& exception) | |
| 301 { | |
| 302 return convert<BoolTrait>(object, exception); | |
| 303 } | |
| 304 | |
| 305 DartStringAdapter DartUtilities::dartToStringImpl(Dart_Handle object, Dart_Handl
e& exception, bool autoDartScope) | |
| 306 { | |
| 307 if (!Dart_IsError(object) && !Dart_IsNull(object)) { | |
| 308 ASSERT(Dart_IsString(object) && !Dart_IsExternalString(object)); | |
| 309 intptr_t charsize = Dart_IsStringLatin1(object) ? 1 : 2; | |
| 310 intptr_t strlength; | |
| 311 Dart_StringLength(object, &strlength); | |
| 312 if (autoDartScope) | |
| 313 return DartStringAdapter(toStringImpl(object, charsize, strlength)); | |
| 314 DartApiScope apiScope; | |
| 315 return DartStringAdapter(toStringImpl(object, charsize, strlength)); | |
| 316 } | |
| 317 if (!autoDartScope) { | |
| 318 DartApiScope apiScope; | |
| 319 DartDOMData* domData = DartDOMData::current(); | |
| 320 Dart_Handle excp = Dart_NewStringFromCString("String expected"); | |
| 321 Dart_SetPersistentHandle(domData->currentException(), excp); | |
| 322 exception = domData->currentException(); | |
| 323 } else { | |
| 324 exception = Dart_NewStringFromCString("String expected"); | |
| 325 } | |
| 326 return DartStringAdapter(DartStringPeer::nullString()); | |
| 327 } | |
| 328 | |
| 329 void DartUtilities::extractMapElements(Dart_Handle map, Dart_Handle& exception,
HashMap<String, Dart_Handle>& elements) | |
| 330 { | |
| 331 ASSERT(elements.isEmpty()); | |
| 332 Dart_Handle list = DartUtilities::invokeUtilsMethod("convertMapToList", 1, &
map); | |
| 333 if (!DartUtilities::checkResult(list, exception)) | |
| 334 return; | |
| 335 ASSERT(Dart_IsList(list)); | |
| 336 | |
| 337 intptr_t length = 0; | |
| 338 Dart_ListLength(list, &length); | |
| 339 ASSERT(length % 2 == 0); | |
| 340 | |
| 341 for (intptr_t i = 0; i < length; i += 2) { | |
| 342 Dart_Handle key = Dart_ListGetAt(list, i); | |
| 343 ASSERT(!Dart_IsError(key) && Dart_IsString(key)); | |
| 344 Dart_Handle value = Dart_ListGetAt(list, i+1); | |
| 345 ASSERT(!Dart_IsError(value)); | |
| 346 String keyString = DartUtilities::dartToString(key, exception); | |
| 347 if (exception) | |
| 348 return; | |
| 349 elements.add(keyString, value); | |
| 350 } | |
| 351 } | |
| 352 | |
| 353 Dart_Handle DartUtilities::toList(const Vector<Dart_Handle>& elements, Dart_Hand
le& exception) | |
| 354 { | |
| 355 Dart_Handle ret = Dart_NewList(elements.size()); | |
| 356 if (Dart_IsError(ret)) { | |
| 357 exception = ret; | |
| 358 return Dart_Null(); | |
| 359 } | |
| 360 for (size_t i = 0; i < elements.size(); i++) { | |
| 361 Dart_ListSetAt(ret, i, elements[i]); | |
| 362 } | |
| 363 return ret; | |
| 364 } | |
| 365 | |
| 366 void DartUtilities::extractListElements(Dart_Handle list, Dart_Handle& exception
, Vector<Dart_Handle>& elements) | |
| 367 { | |
| 368 ASSERT(elements.isEmpty()); | |
| 369 list = DartUtilities::invokeUtilsMethod("convertToList", 1, &list); | |
| 370 if (!DartUtilities::checkResult(list, exception)) | |
| 371 return; | |
| 372 ASSERT(Dart_IsList(list)); | |
| 373 | |
| 374 intptr_t length = 0; | |
| 375 Dart_ListLength(list, &length); | |
| 376 elements.reserveCapacity(length); | |
| 377 for (intptr_t i = 0; i < length; i++) { | |
| 378 Dart_Handle element = Dart_ListGetAt(list, i); | |
| 379 ASSERT(!Dart_IsError(element)); | |
| 380 elements.append(element); | |
| 381 } | |
| 382 } | |
| 383 | |
| 384 v8::Local<v8::Context> DartUtilities::currentV8Context() | |
| 385 { | |
| 386 LocalFrame* frame = DartUtilities::domWindowForCurrentIsolate()->frame(); | |
| 387 v8::Local<v8::Context> context = toV8Context(frame, DOMWrapperWorld::mainWor
ld()); | |
| 388 ASSERT(!context.IsEmpty()); | |
| 389 return context; | |
| 390 } | |
| 391 | |
| 392 int DartUtilities::dartToInt(Dart_Handle object, Dart_Handle& exception) | |
| 393 { | |
| 394 int64_t value = toInteger(object, exception); | |
| 395 if (exception) | |
| 396 return 0; | |
| 397 if (value < INT_MIN || value > INT_MAX) { | |
| 398 exception = Dart_NewStringFromCString("value out of range"); | |
| 399 return 0; | |
| 400 } | |
| 401 return value; | |
| 402 } | |
| 403 | |
| 404 unsigned DartUtilities::dartToUnsigned(Dart_Handle object, Dart_Handle& exceptio
n) | |
| 405 { | |
| 406 int64_t value = toInteger(object, exception); | |
| 407 if (exception) | |
| 408 return 0; | |
| 409 if (value < 0 || value > UINT_MAX) { | |
| 410 exception = Dart_NewStringFromCString("value out of range"); | |
| 411 return 0; | |
| 412 } | |
| 413 return value; | |
| 414 } | |
| 415 | |
| 416 long long DartUtilities::dartToLongLong(Dart_Handle object, Dart_Handle& excepti
on) | |
| 417 { | |
| 418 // FIXME: proper processing of longer integer values. | |
| 419 return toInteger(object, exception); | |
| 420 } | |
| 421 | |
| 422 unsigned long long DartUtilities::dartToUnsignedLongLong(Dart_Handle object, Dar
t_Handle& exception) | |
| 423 { | |
| 424 // FIXME: proper processing of longer integer values. | |
| 425 int64_t value = toInteger(object, exception); | |
| 426 if (exception) | |
| 427 return 0; | |
| 428 if (value < 0) { | |
| 429 exception = Dart_NewStringFromCString("value out of range"); | |
| 430 return 0; | |
| 431 } | |
| 432 return value; | |
| 433 } | |
| 434 | |
| 435 Dart_Handle DartUtilities::numberToDart(double value) | |
| 436 { | |
| 437 // JS can store integer values that are no greater than 2^53 - 1. | |
| 438 if (-kJSMaxInteger <= value && value <= kJSMaxInteger) { | |
| 439 int64_t intValue = static_cast<int64_t>(value); | |
| 440 if (value == intValue) | |
| 441 return intToDart(intValue); | |
| 442 } | |
| 443 return doubleToDart(value); | |
| 444 } | |
| 445 | |
| 446 ScriptValue DartUtilities::dartToScriptValue(Dart_Handle object) | |
| 447 { | |
| 448 return ScriptValue(DartScriptValue::create(currentScriptState(), object)); | |
| 449 } | |
| 450 | |
| 451 Dart_Handle DartUtilities::scriptValueToDart(const ScriptValue& value) | |
| 452 { | |
| 453 if (value.isEmpty()) { | |
| 454 return Dart_Null(); | |
| 455 } | |
| 456 AbstractScriptValue* scriptValue = value.scriptValue(); | |
| 457 if (scriptValue->isDart()) { | |
| 458 DartScriptValue* dartScriptValue = static_cast<DartScriptValue*>(scriptV
alue); | |
| 459 return dartScriptValue->dartValue(); | |
| 460 } | |
| 461 // FIXMEMULTIVM: Should not be converting from V8 values. Major culprit is I
DB. | |
| 462 // FIXME: better error handling. | |
| 463 Dart_Handle exception = 0; | |
| 464 return V8Converter::toDart(value.v8Value(), exception); | |
| 465 } | |
| 466 | |
| 467 Dart_Handle DartUtilities::scriptPromiseToDart(const ScriptPromise& promise) | |
| 468 { | |
| 469 AbstractScriptPromise* scriptPromise = promise.scriptPromise().get(); | |
| 470 if (scriptPromise->isDartScriptPromise()) { | |
| 471 DartScriptPromise* dartScriptPromise = static_cast<DartScriptPromise*>(s
criptPromise); | |
| 472 return dartScriptPromise->dartValue(); | |
| 473 } | |
| 474 ASSERT_NOT_REACHED(); | |
| 475 return Dart_NewStringFromCString("Internal error: Expected Dart promise"); | |
| 476 } | |
| 477 | |
| 478 PassRefPtr<SerializedScriptValue> DartUtilities::toSerializedScriptValue(Dart_Ha
ndle value, MessagePortArray* ports, ArrayBufferArray* arrayBuffers, Dart_Handle
& exception) | |
| 479 { | |
| 480 v8::Handle<v8::Value> v8Value = V8Converter::toV8(value, exception); | |
| 481 if (exception) | |
| 482 return nullptr; | |
| 483 | |
| 484 V8TrackExceptionState exceptionState; | |
| 485 RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(v8Valu
e, ports, arrayBuffers, exceptionState, v8::Isolate::GetCurrent()); | |
| 486 if (exceptionState.hadException()) { | |
| 487 // FIXME: better exception here. We should match the exception v8 would
throw. | |
| 488 exception = Dart_NewStringFromCString("Failed to create SerializedScript
Value"); | |
| 489 return nullptr; | |
| 490 } | |
| 491 | |
| 492 return message.release(); | |
| 493 } | |
| 494 | |
| 495 Dart_Handle DartUtilities::dateToDart(double date) | |
| 496 { | |
| 497 Dart_Handle asDouble = DartUtilities::doubleToDart(date); | |
| 498 ASSERT(!Dart_IsError(asDouble)); | |
| 499 return DartUtilities::invokeUtilsMethod("doubleToDateTime", 1, &asDouble); | |
| 500 } | |
| 501 | |
| 502 double DartUtilities::dartToDate(Dart_Handle date, Dart_Handle& exception) | |
| 503 { | |
| 504 Dart_Handle asDouble = DartUtilities::invokeUtilsMethod("dateTimeToDouble",
1, &date); | |
| 505 if (!DartUtilities::checkResult(asDouble, exception)) | |
| 506 return 0.0; | |
| 507 | |
| 508 return DartUtilities::dartToDouble(asDouble, exception); | |
| 509 } | |
| 510 | |
| 511 double DartUtilities::dartToDate(Dart_NativeArguments args, int idx, Dart_Handle
& exception) | |
| 512 { | |
| 513 Dart_Handle object = Dart_GetNativeArgument(args, idx); | |
| 514 return dartToDate(object, exception); | |
| 515 } | |
| 516 | |
| 517 bool DartUtilities::isDateTime(DartDOMData* domData, Dart_Handle handle) | |
| 518 { | |
| 519 ASSERT(domData); | |
| 520 Dart_Handle type = DartDOMWrapper::dartClass(domData, _DateTimeClassId); | |
| 521 ASSERT(!Dart_IsError(type)); | |
| 522 return objectIsType(handle, type); | |
| 523 } | |
| 524 | |
| 525 bool DartUtilities::objectIsType(Dart_Handle handle, Dart_Handle type) | |
| 526 { | |
| 527 bool isType = false; | |
| 528 Dart_Handle result = Dart_ObjectIsType(handle, type, &isType); | |
| 529 if (Dart_IsError(result)) | |
| 530 return false; | |
| 531 return isType; | |
| 532 } | |
| 533 | |
| 534 bool DartUtilities::isTypeSubclassOf(Dart_Handle type, Dart_Handle library, cons
t char* typeName) | |
| 535 { | |
| 536 Dart_Handle other = Dart_GetType(library, Dart_NewStringFromCString(typeName
), 0, 0); | |
| 537 ASSERT(!Dart_IsError(other)); | |
| 538 | |
| 539 Dart_Handle args[2] = { type, other }; | |
| 540 Dart_Handle result = DartUtilities::invokeUtilsMethod("isTypeSubclassOf", 2,
args); | |
| 541 if (Dart_IsError(result)) { | |
| 542 ASSERT_NOT_REACHED(); | |
| 543 return false; | |
| 544 } | |
| 545 | |
| 546 Dart_Handle exception = 0; | |
| 547 bool boolResult = dartToBool(result, exception); | |
| 548 if (exception) | |
| 549 return false; | |
| 550 return boolResult; | |
| 551 } | |
| 552 | |
| 553 Dart_Handle DartUtilities::getAndValidateNativeType(Dart_Handle type, const Stri
ng& tagName) | |
| 554 { | |
| 555 Dart_Handle args[2] = { type, stringToDartString(tagName) }; | |
| 556 Dart_Handle result = DartUtilities::invokeUtilsMethod("getAndValidateNativeT
ype", 2, args); | |
| 557 ASSERT(!Dart_IsError(result)); | |
| 558 if (Dart_IsError(result)) { | |
| 559 ASSERT_NOT_REACHED(); | |
| 560 return Dart_Null(); | |
| 561 } | |
| 562 return result; | |
| 563 } | |
| 564 | |
| 565 bool DartUtilities::isFunction(DartDOMData* domData, Dart_Handle handle) | |
| 566 { | |
| 567 return DartUtilities::objectIsType(handle, domData->functionType()); | |
| 568 } | |
| 569 | |
| 570 static Dart_TypedData_Type typedDataTypeFromViewType(ArrayBufferView::ViewType t
ype) | |
| 571 { | |
| 572 switch (type) { | |
| 573 case ArrayBufferView::TypeInt8: | |
| 574 return Dart_TypedData_kInt8; | |
| 575 case ArrayBufferView::TypeUint8: | |
| 576 return Dart_TypedData_kUint8; | |
| 577 case ArrayBufferView::TypeUint8Clamped: | |
| 578 return Dart_TypedData_kUint8Clamped; | |
| 579 case ArrayBufferView::TypeInt16: | |
| 580 return Dart_TypedData_kInt16; | |
| 581 case ArrayBufferView::TypeUint16: | |
| 582 return Dart_TypedData_kUint16; | |
| 583 case ArrayBufferView::TypeInt32: | |
| 584 return Dart_TypedData_kInt32; | |
| 585 case ArrayBufferView::TypeUint32: | |
| 586 return Dart_TypedData_kUint32; | |
| 587 case ArrayBufferView::TypeFloat32: | |
| 588 return Dart_TypedData_kFloat32; | |
| 589 case ArrayBufferView::TypeFloat64: | |
| 590 return Dart_TypedData_kFloat64; | |
| 591 case ArrayBufferView::TypeDataView: | |
| 592 return Dart_TypedData_kByteData; | |
| 593 } | |
| 594 ASSERT_NOT_REACHED(); | |
| 595 return Dart_TypedData_kInvalid; | |
| 596 } | |
| 597 | |
| 598 static unsigned elementSizeFromViewType(Dart_TypedData_Type type) | |
| 599 { | |
| 600 switch (type) { | |
| 601 case Dart_TypedData_kByteData: | |
| 602 return sizeof(uint8_t); | |
| 603 case Dart_TypedData_kInt8: | |
| 604 return sizeof(int8_t); | |
| 605 case Dart_TypedData_kUint8: | |
| 606 return sizeof(uint8_t); | |
| 607 case Dart_TypedData_kUint8Clamped: | |
| 608 return sizeof(uint8_t); | |
| 609 case Dart_TypedData_kInt16: | |
| 610 return sizeof(int16_t); | |
| 611 case Dart_TypedData_kUint16: | |
| 612 return sizeof(uint16_t); | |
| 613 case Dart_TypedData_kInt32: | |
| 614 return sizeof(int32_t); | |
| 615 case Dart_TypedData_kUint32: | |
| 616 return sizeof(uint32_t); | |
| 617 case Dart_TypedData_kFloat32: | |
| 618 return sizeof(float); | |
| 619 case Dart_TypedData_kFloat64: | |
| 620 return sizeof(double); | |
| 621 case Dart_TypedData_kFloat32x4: | |
| 622 return 4 * sizeof(float); | |
| 623 default: | |
| 624 break; | |
| 625 } | |
| 626 ASSERT_NOT_REACHED(); | |
| 627 return 0; | |
| 628 } | |
| 629 | |
| 630 static unsigned elementSizeFromViewType(ArrayBufferView::ViewType type) | |
| 631 { | |
| 632 return elementSizeFromViewType(typedDataTypeFromViewType(type)); | |
| 633 } | |
| 634 | |
| 635 class TypedDataPeer { | |
| 636 public: | |
| 637 virtual ~TypedDataPeer() { }; | |
| 638 virtual bool isViewPeer() = 0; | |
| 639 }; | |
| 640 | |
| 641 class TypedBufferPeer : public TypedDataPeer { | |
| 642 public: | |
| 643 TypedBufferPeer(PassRefPtr<ArrayBuffer> buffer) : m_buffer(buffer) { } | |
| 644 virtual ~TypedBufferPeer() { } | |
| 645 | |
| 646 PassRefPtr<ArrayBuffer> buffer() | |
| 647 { | |
| 648 return m_buffer; | |
| 649 } | |
| 650 | |
| 651 virtual bool isViewPeer() | |
| 652 { | |
| 653 return false; | |
| 654 } | |
| 655 | |
| 656 private: | |
| 657 RefPtr<ArrayBuffer> m_buffer; | |
| 658 }; | |
| 659 | |
| 660 class TypedViewPeer : public TypedDataPeer { | |
| 661 public: | |
| 662 TypedViewPeer(PassRefPtr<ArrayBufferView> view) : m_view(view) { } | |
| 663 virtual ~TypedViewPeer() { } | |
| 664 | |
| 665 PassRefPtr<ArrayBufferView> view() | |
| 666 { | |
| 667 return m_view; | |
| 668 } | |
| 669 | |
| 670 virtual bool isViewPeer() | |
| 671 { | |
| 672 return true; | |
| 673 } | |
| 674 | |
| 675 private: | |
| 676 RefPtr<ArrayBufferView> m_view; | |
| 677 }; | |
| 678 | |
| 679 static void externalArrayBufferCallback(void* isolateCallbackData, Dart_WeakPers
istentHandle handle, void* peer) | |
| 680 { | |
| 681 delete reinterpret_cast<TypedDataPeer*>(peer); | |
| 682 } | |
| 683 | |
| 684 static Dart_Handle createExternalTypedData(Dart_TypedData_Type type, void* data,
intptr_t numberOfElements, TypedDataPeer* peer, intptr_t peerSize, Dart_WeakPer
sistentHandleFinalizer callback) | |
| 685 { | |
| 686 Dart_Handle newInstance = Dart_NewExternalTypedData(type, data, numberOfElem
ents); | |
| 687 Dart_Handle result = Dart_SetPeer(newInstance, peer); | |
| 688 if (Dart_IsError(result)) | |
| 689 return result; | |
| 690 Dart_NewWeakPersistentHandle(newInstance, peer, peerSize, callback); | |
| 691 return newInstance; | |
| 692 } | |
| 693 | |
| 694 Dart_Handle DartUtilities::arrayBufferToDart(WTF::ArrayBuffer* buffer) | |
| 695 { | |
| 696 void* data = buffer->data(); | |
| 697 unsigned byteLength = buffer->byteLength(); | |
| 698 TypedBufferPeer* peer = new TypedBufferPeer(buffer); | |
| 699 Dart_Handle typedData = createExternalTypedData(Dart_TypedData_kUint8, data
, byteLength, peer, byteLength, externalArrayBufferCallback); | |
| 700 ASSERT(!Dart_IsError(typedData)); | |
| 701 return Dart_NewByteBuffer(typedData); | |
| 702 } | |
| 703 | |
| 704 static bool externalTypedDataGetPeer(Dart_Handle handle, void** peer) | |
| 705 { | |
| 706 *peer = 0; | |
| 707 Dart_Handle getPeerResult = Dart_GetPeer(handle, peer); | |
| 708 if (!Dart_IsError(getPeerResult) && *peer) { | |
| 709 return true; | |
| 710 } | |
| 711 return false; | |
| 712 } | |
| 713 | |
| 714 static PassRefPtr<WTF::ArrayBuffer> dartToArrayBufferHelper(Dart_Handle array, D
art_Handle& exception, bool externalize) | |
| 715 { | |
| 716 void* data = 0; | |
| 717 | |
| 718 // If a ByteBuffer is passed in extract the typed data first. | |
| 719 if (Dart_IsByteBuffer(array)) { | |
| 720 array = Dart_GetDataFromByteBuffer(array); | |
| 721 } | |
| 722 | |
| 723 // Check if the Dart array buffer object is external and has an | |
| 724 // ArrayBuffer peer. | |
| 725 if (externalTypedDataGetPeer(array, &data) && !reinterpret_cast<TypedDataPee
r*>(data)->isViewPeer()) { | |
| 726 return reinterpret_cast<TypedBufferPeer*>(data)->buffer(); | |
| 727 } | |
| 728 | |
| 729 Dart_TypedData_Type type; | |
| 730 intptr_t elementLength = 0; | |
| 731 intptr_t byteLength = 0; | |
| 732 | |
| 733 // Check if the Dart object is a typed data object by acquiring its data. | |
| 734 // If it is, create a thin ArrayBuffer wrapper around the data in the dart | |
| 735 // heap. | |
| 736 Dart_Handle result = Dart_TypedDataAcquireData(array, &type, &data, &element
Length); | |
| 737 if (Dart_IsError(result)) { | |
| 738 exception = Dart_NewStringFromCString("Typed data object expected"); | |
| 739 return nullptr; | |
| 740 } | |
| 741 // FIXME: we really shouldn't release the data until we are done with it. | |
| 742 Dart_TypedDataReleaseData(array); | |
| 743 byteLength = elementLength * elementSizeFromViewType(type); | |
| 744 return externalize ? ArrayBuffer::create(data, byteLength) : ArrayBuffer::cr
eateNoCopy(data, byteLength); | |
| 745 } | |
| 746 | |
| 747 PassRefPtr<WTF::ArrayBuffer> DartUtilities::dartToArrayBuffer(Dart_Handle array,
Dart_Handle& exception) | |
| 748 { | |
| 749 return dartToArrayBufferHelper(array, exception, false); | |
| 750 } | |
| 751 | |
| 752 PassRefPtr<WTF::ArrayBuffer> DartUtilities::dartToExternalizedArrayBuffer(Dart_H
andle array, Dart_Handle& exception) | |
| 753 { | |
| 754 return dartToArrayBufferHelper(array, exception, true); | |
| 755 } | |
| 756 | |
| 757 // FIXME: This mapping to dart objects loses object identity for | |
| 758 // the buffer part of views. If we have two views on the same buffer | |
| 759 // in C++ and we create dart wrappers we will get two different dart | |
| 760 // buffer objects. Additionally, this means that neutering will not work. | |
| 761 Dart_Handle DartUtilities::arrayBufferViewToDart(WTF::ArrayBufferView* view) | |
| 762 { | |
| 763 ArrayBufferView::ViewType type = view->type(); | |
| 764 void* address = view->baseAddress(); | |
| 765 unsigned byteLength = view->byteLength(); | |
| 766 unsigned length = byteLength / elementSizeFromViewType(type); | |
| 767 TypedViewPeer* peer = new TypedViewPeer(view); | |
| 768 return createExternalTypedData(typedDataTypeFromViewType(type), address, len
gth, peer, byteLength, externalArrayBufferCallback); | |
| 769 } | |
| 770 | |
| 771 | |
| 772 // FIXME: Again, this breaks the view-buffer relationship. | |
| 773 static PassRefPtr<WTF::ArrayBufferView> dartToArrayBufferViewHelper(Dart_Handle
array, Dart_Handle& exception, bool externalize) | |
| 774 { | |
| 775 void* data = 0; | |
| 776 | |
| 777 // Check if the array is external and has an ArrayBufferView peer. | |
| 778 if (externalTypedDataGetPeer(array, &data)) { | |
| 779 if (!reinterpret_cast<TypedDataPeer*>(data)->isViewPeer()) { | |
| 780 exception = Dart_NewStringFromCString("Typed data view expected"); | |
| 781 return nullptr; | |
| 782 } | |
| 783 return reinterpret_cast<TypedViewPeer*>(data)->view(); | |
| 784 } | |
| 785 | |
| 786 // Check if the dart object is an internal typed data object and get | |
| 787 // the data from it. | |
| 788 Dart_TypedData_Type type; | |
| 789 intptr_t elementLength = 0; | |
| 790 Dart_Handle result = Dart_TypedDataAcquireData(array, &type, &data, &element
Length); | |
| 791 if (Dart_IsError(result)) { | |
| 792 exception = Dart_NewStringFromCString("Typed data object expected"); | |
| 793 return nullptr; | |
| 794 } | |
| 795 intptr_t byteLength = elementLength * elementSizeFromViewType(type); | |
| 796 // FIXME: we really shouldn't release the data until we are done with it. | |
| 797 Dart_TypedDataReleaseData(array); | |
| 798 RefPtr<ArrayBuffer> buffer = externalize ? ArrayBuffer::create(data, byteLen
gth) : ArrayBuffer::createNoCopy(data, byteLength); | |
| 799 | |
| 800 switch (type) { | |
| 801 case Dart_TypedData_kByteData: | |
| 802 return DataView::create(buffer, 0, elementLength); | |
| 803 case Dart_TypedData_kInt8: | |
| 804 return Int8Array::create(buffer, 0, elementLength); | |
| 805 case Dart_TypedData_kUint8: | |
| 806 return Uint8Array::create(buffer, 0, elementLength); | |
| 807 case Dart_TypedData_kUint8Clamped: | |
| 808 return Uint8ClampedArray::create(buffer, 0, elementLength); | |
| 809 case Dart_TypedData_kInt16: | |
| 810 return Uint16Array::create(buffer, 0, elementLength); | |
| 811 case Dart_TypedData_kUint16: | |
| 812 return Uint16Array::create(buffer, 0, elementLength); | |
| 813 case Dart_TypedData_kInt32: | |
| 814 return Int32Array::create(buffer, 0, elementLength); | |
| 815 case Dart_TypedData_kUint32: | |
| 816 return Uint32Array::create(buffer, 0, elementLength); | |
| 817 case Dart_TypedData_kFloat32: | |
| 818 return Float32Array::create(buffer, 0, elementLength); | |
| 819 case Dart_TypedData_kFloat64: | |
| 820 return Float64Array::create(buffer, 0, elementLength); | |
| 821 case Dart_TypedData_kFloat32x4: | |
| 822 return Float32Array::create(buffer, 0, elementLength * sizeof(float)); | |
| 823 default: | |
| 824 break; | |
| 825 } | |
| 826 ASSERT_NOT_REACHED(); | |
| 827 return nullptr; | |
| 828 } | |
| 829 | |
| 830 PassRefPtr<WTF::ArrayBufferView> DartUtilities::dartToArrayBufferView(Dart_Handl
e array, Dart_Handle& exception) | |
| 831 { | |
| 832 return dartToArrayBufferViewHelper(array, exception, false); | |
| 833 } | |
| 834 | |
| 835 PassRefPtr<WTF::ArrayBufferView> DartUtilities::dartToExternalizedArrayBufferVie
w(Dart_Handle array, Dart_Handle& exception) | |
| 836 { | |
| 837 return dartToArrayBufferViewHelper(array, exception, true); | |
| 838 } | |
| 839 | |
| 840 PassRefPtr<WTF::Int8Array> DartUtilities::dartToInt8ArrayWithNullCheck(Dart_Hand
le handle, Dart_Handle& exception) | |
| 841 { | |
| 842 return Dart_IsNull(handle) ? nullptr : dartToInt8Array(handle, exception); | |
| 843 } | |
| 844 | |
| 845 PassRefPtr<WTF::Int8Array> DartUtilities::dartToInt8Array(Dart_Handle handle, Da
rt_Handle& exception) | |
| 846 { | |
| 847 RefPtr<ArrayBufferView> view = DartUtilities::dartToArrayBufferView(handle,
exception); | |
| 848 if (exception) | |
| 849 return nullptr; | |
| 850 if (view->type() == ArrayBufferView::TypeInt8) | |
| 851 return reinterpret_cast<Int8Array*>(view.get()); | |
| 852 exception = Dart_NewStringFromCString("Int8List expected"); | |
| 853 return nullptr; | |
| 854 } | |
| 855 | |
| 856 PassRefPtr<WTF::Int8Array> DartUtilities::dartToInt8ArrayWithNullCheck(Dart_Nati
veArguments args, int idx, Dart_Handle& exception) | |
| 857 { | |
| 858 Dart_Handle object = Dart_GetNativeArgument(args, idx); | |
| 859 return dartToInt8ArrayWithNullCheck(object, exception); | |
| 860 } | |
| 861 | |
| 862 PassRefPtr<WTF::Int8Array> DartUtilities::dartToInt8Array(Dart_NativeArguments a
rgs, int idx, Dart_Handle& exception) | |
| 863 { | |
| 864 Dart_Handle object = Dart_GetNativeArgument(args, idx); | |
| 865 return dartToInt8Array(object, exception); | |
| 866 } | |
| 867 | |
| 868 PassRefPtr<WTF::Int32Array> DartUtilities::dartToInt32ArrayWithNullCheck(Dart_Ha
ndle handle, Dart_Handle& exception) | |
| 869 { | |
| 870 return Dart_IsNull(handle) ? nullptr : dartToInt32Array(handle, exception); | |
| 871 } | |
| 872 | |
| 873 PassRefPtr<WTF::Int32Array> DartUtilities::dartToInt32Array(Dart_Handle handle,
Dart_Handle& exception) | |
| 874 { | |
| 875 RefPtr<ArrayBufferView> view = DartUtilities::dartToArrayBufferView(handle,
exception); | |
| 876 if (exception) | |
| 877 return nullptr; | |
| 878 if (view->type() == ArrayBufferView::TypeInt32) | |
| 879 return reinterpret_cast<Int32Array*>(view.get()); | |
| 880 exception = Dart_NewStringFromCString("Int32List expected"); | |
| 881 return nullptr; | |
| 882 } | |
| 883 | |
| 884 PassRefPtr<WTF::Int32Array> DartUtilities::dartToInt32ArrayWithNullCheck(Dart_Na
tiveArguments args, int idx, Dart_Handle& exception) | |
| 885 { | |
| 886 Dart_Handle object = Dart_GetNativeArgument(args, idx); | |
| 887 return dartToInt32ArrayWithNullCheck(object, exception); | |
| 888 } | |
| 889 | |
| 890 PassRefPtr<WTF::Int32Array> DartUtilities::dartToInt32Array(Dart_NativeArguments
args, int idx, Dart_Handle& exception) | |
| 891 { | |
| 892 Dart_Handle object = Dart_GetNativeArgument(args, idx); | |
| 893 return dartToInt32Array(object, exception); | |
| 894 } | |
| 895 | |
| 896 PassRefPtr<WTF::Uint8ClampedArray> DartUtilities::dartToUint8ClampedArrayWithNul
lCheck(Dart_Handle handle, Dart_Handle& exception) | |
| 897 { | |
| 898 return Dart_IsNull(handle) ? nullptr : dartToUint8ClampedArray(handle, excep
tion); | |
| 899 } | |
| 900 | |
| 901 PassRefPtr<WTF::Uint8ClampedArray> DartUtilities::dartToUint8ClampedArray(Dart_H
andle handle, Dart_Handle& exception) | |
| 902 { | |
| 903 RefPtr<ArrayBufferView> view = DartUtilities::dartToArrayBufferView(handle,
exception); | |
| 904 if (exception) | |
| 905 return nullptr; | |
| 906 if (view->type() == ArrayBufferView::TypeUint8Clamped) | |
| 907 return reinterpret_cast<Uint8ClampedArray*>(view.get()); | |
| 908 exception = Dart_NewStringFromCString("Uint8ClampedList expected"); | |
| 909 return nullptr; | |
| 910 } | |
| 911 | |
| 912 PassRefPtr<WTF::Uint8ClampedArray> DartUtilities::dartToUint8ClampedArrayWithNul
lCheck(Dart_NativeArguments args, int idx, Dart_Handle& exception) | |
| 913 { | |
| 914 Dart_Handle object = Dart_GetNativeArgument(args, idx); | |
| 915 return dartToUint8ClampedArrayWithNullCheck(object, exception); | |
| 916 } | |
| 917 | |
| 918 PassRefPtr<WTF::Uint8ClampedArray> DartUtilities::dartToUint8ClampedArray(Dart_N
ativeArguments args, int idx, Dart_Handle& exception) | |
| 919 { | |
| 920 Dart_Handle object = Dart_GetNativeArgument(args, idx); | |
| 921 return dartToUint8ClampedArray(object, exception); | |
| 922 } | |
| 923 | |
| 924 PassRefPtr<WTF::Uint8Array> DartUtilities::dartToUint8ArrayWithNullCheck(Dart_Ha
ndle handle, Dart_Handle& exception) | |
| 925 { | |
| 926 return Dart_IsNull(handle) ? nullptr : dartToUint8Array(handle, exception); | |
| 927 } | |
| 928 | |
| 929 PassRefPtr<WTF::Uint8Array> DartUtilities::dartToUint8Array(Dart_Handle handle,
Dart_Handle& exception) | |
| 930 { | |
| 931 RefPtr<ArrayBufferView> view = DartUtilities::dartToArrayBufferView(handle,
exception); | |
| 932 if (exception) | |
| 933 return nullptr; | |
| 934 if (view->type() == ArrayBufferView::TypeUint8) | |
| 935 return reinterpret_cast<Uint8Array*>(view.get()); | |
| 936 exception = Dart_NewStringFromCString("Uint8List expected"); | |
| 937 return nullptr; | |
| 938 } | |
| 939 | |
| 940 PassRefPtr<WTF::Uint8Array> DartUtilities::dartToUint8ArrayWithNullCheck(Dart_Na
tiveArguments args, int idx, Dart_Handle& exception) | |
| 941 { | |
| 942 Dart_Handle object = Dart_GetNativeArgument(args, idx); | |
| 943 return dartToUint8ArrayWithNullCheck(object, exception); | |
| 944 } | |
| 945 | |
| 946 PassRefPtr<WTF::Uint8Array> DartUtilities::dartToUint8Array(Dart_NativeArguments
args, int idx, Dart_Handle& exception) | |
| 947 { | |
| 948 Dart_Handle object = Dart_GetNativeArgument(args, idx); | |
| 949 return dartToUint8Array(object, exception); | |
| 950 } | |
| 951 | |
| 952 PassRefPtr<WTF::Float32Array> DartUtilities::dartToFloat32ArrayWithNullCheck(Dar
t_Handle handle, Dart_Handle& exception) | |
| 953 { | |
| 954 return Dart_IsNull(handle) ? nullptr : dartToFloat32Array(handle, exception)
; | |
| 955 } | |
| 956 | |
| 957 PassRefPtr<WTF::Float32Array> DartUtilities::dartToFloat32Array(Dart_Handle hand
le, Dart_Handle& exception) | |
| 958 { | |
| 959 RefPtr<ArrayBufferView> view = DartUtilities::dartToArrayBufferView(handle,
exception); | |
| 960 if (exception) | |
| 961 return nullptr; | |
| 962 if (view->type() == ArrayBufferView::TypeFloat32) | |
| 963 return reinterpret_cast<Float32Array*>(view.get()); | |
| 964 exception = Dart_NewStringFromCString("Float32List expected"); | |
| 965 return nullptr; | |
| 966 } | |
| 967 | |
| 968 PassRefPtr<WTF::Float32Array> DartUtilities::dartToFloat32ArrayWithNullCheck(Dar
t_NativeArguments args, int idx, Dart_Handle& exception) | |
| 969 { | |
| 970 Dart_Handle object = Dart_GetNativeArgument(args, idx); | |
| 971 return dartToFloat32ArrayWithNullCheck(object, exception); | |
| 972 } | |
| 973 | |
| 974 PassRefPtr<WTF::Float32Array> DartUtilities::dartToFloat32Array(Dart_NativeArgum
ents args, int idx, Dart_Handle& exception) | |
| 975 { | |
| 976 Dart_Handle object = Dart_GetNativeArgument(args, idx); | |
| 977 return dartToFloat32Array(object, exception); | |
| 978 } | |
| 979 | |
| 980 bool DartUtilities::isUint8Array(Dart_Handle object) | |
| 981 { | |
| 982 return Dart_GetTypeOfTypedData(object) == Dart_TypedData_kUint8; | |
| 983 } | |
| 984 | |
| 985 bool DartUtilities::isUint8ClampedArray(Dart_Handle object) | |
| 986 { | |
| 987 return Dart_GetTypeOfTypedData(object) == Dart_TypedData_kUint8Clamped; | |
| 988 } | |
| 989 | |
| 990 SQLValue DartUtilities::toSQLValue(Dart_Handle object, Dart_Handle& exception) | |
| 991 { | |
| 992 if (Dart_IsNull(object)) | |
| 993 return SQLValue(); | |
| 994 | |
| 995 if (Dart_IsNumber(object)) | |
| 996 return SQLValue(DartUtilities::dartToDouble(object, exception)); | |
| 997 | |
| 998 return SQLValue(DartUtilities::dartToString(object, exception)); | |
| 999 } | |
| 1000 | |
| 1001 PassRefPtr<SerializedScriptValue> DartUtilities::dartToSerializedScriptValue(Dar
t_Handle object, Dart_Handle& exception) | |
| 1002 { | |
| 1003 return toSerializedScriptValue(object, 0, 0, exception); | |
| 1004 } | |
| 1005 | |
| 1006 Dart_Handle DartUtilities::serializedScriptValueToDart(PassRefPtr<SerializedScri
ptValue> value) | |
| 1007 { | |
| 1008 // FIXME: better error handling. | |
| 1009 Dart_Handle exception = 0; | |
| 1010 return V8Converter::toDart(value->deserialize(), exception); | |
| 1011 } | |
| 1012 | |
| 1013 // FIXME: this function requires better testing. Currently blocking as new Messa
geChannel hasn't been implemented yet. | |
| 1014 void DartUtilities::toMessagePortArray(Dart_Handle value, MessagePortArray& port
s, ArrayBufferArray& arrayBuffers, Dart_Handle& exception) | |
| 1015 { | |
| 1016 Vector<Dart_Handle> elements; | |
| 1017 DartUtilities::extractListElements(value, exception, elements); | |
| 1018 if (exception) | |
| 1019 return; | |
| 1020 | |
| 1021 DartDOMData* domData = DartDOMData::current(); | |
| 1022 for (size_t i = 0; i < elements.size(); i++) { | |
| 1023 Dart_Handle element = elements[i]; | |
| 1024 if (DartDOMWrapper::instanceOf<DartMessagePort>(domData, element)) { | |
| 1025 MessagePort* messagePort = DartMessagePort::toNative(element, except
ion); | |
| 1026 ASSERT(!exception); | |
| 1027 ASSERT(messagePort); | |
| 1028 ports.append(messagePort); | |
| 1029 continue; | |
| 1030 } | |
| 1031 | |
| 1032 if (Dart_IsByteBuffer(element)) { | |
| 1033 element = Dart_GetDataFromByteBuffer(element); | |
| 1034 RefPtr<ArrayBuffer> arrayBuffer = DartUtilities::dartToExternalizedA
rrayBuffer(element, exception); | |
| 1035 ASSERT(!exception); | |
| 1036 ASSERT(arrayBuffer); | |
| 1037 arrayBuffers.append(arrayBuffer); | |
| 1038 continue; | |
| 1039 } | |
| 1040 | |
| 1041 exception = Dart_NewStringFromCString("TransferArray argument must conta
in only Transferables"); | |
| 1042 return; | |
| 1043 } | |
| 1044 } | |
| 1045 | |
| 1046 Dictionary DartUtilities::dartToDictionary(Dart_Handle object, Dart_Handle& exce
ption) | |
| 1047 { | |
| 1048 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent(); | |
| 1049 v8::Local<v8::Value> value = v8::Local<v8::Value>::New(v8Isolate, V8Converte
r::toV8(object, exception)); | |
| 1050 if (exception) | |
| 1051 return Dictionary(); | |
| 1052 return Dictionary(value, v8Isolate); | |
| 1053 } | |
| 1054 | |
| 1055 Dictionary DartUtilities::dartToDictionaryWithNullCheck(Dart_Handle object, Dart
_Handle& exception) | |
| 1056 { | |
| 1057 if (Dart_IsNull(object)) | |
| 1058 return Dictionary(); | |
| 1059 return dartToDictionary(object, exception); | |
| 1060 } | |
| 1061 | |
| 1062 Dictionary DartUtilities::dartToDictionary(Dart_NativeArguments args, int idx, D
art_Handle& exception) | |
| 1063 { | |
| 1064 Dart_Handle object = Dart_GetNativeArgument(args, idx); | |
| 1065 return dartToDictionary(object, exception); | |
| 1066 } | |
| 1067 | |
| 1068 Dictionary DartUtilities::dartToDictionaryWithNullCheck(Dart_NativeArguments arg
s, int idx, Dart_Handle& exception) | |
| 1069 { | |
| 1070 Dart_Handle object = Dart_GetNativeArgument(args, idx); | |
| 1071 return dartToDictionaryWithNullCheck(object, exception); | |
| 1072 } | |
| 1073 | |
| 1074 LocalDOMWindow* DartUtilities::domWindowForCurrentIsolate() | |
| 1075 { | |
| 1076 DartDOMData* domData = DartDOMData::current(); | |
| 1077 ASSERT(domData->scriptExecutionContext()->isDocument()); | |
| 1078 Document* document = static_cast<Document*>(domData->scriptExecutionContext(
)); | |
| 1079 return document->domWindow(); | |
| 1080 } | |
| 1081 | |
| 1082 V8ScriptState* DartUtilities::v8ScriptStateForCurrentIsolate() | |
| 1083 { | |
| 1084 return V8ScriptState::forMainWorld(domWindowForCurrentIsolate()->frame()); | |
| 1085 } | |
| 1086 | |
| 1087 ExecutionContext* DartUtilities::scriptExecutionContext() | |
| 1088 { | |
| 1089 if (Dart_CurrentIsolate()) | |
| 1090 return DartDOMData::current()->scriptExecutionContext(); | |
| 1091 return 0; | |
| 1092 } | |
| 1093 | |
| 1094 bool DartUtilities::processingUserGesture() | |
| 1095 { | |
| 1096 // FIXME: implement this. | |
| 1097 return false; | |
| 1098 } | |
| 1099 | |
| 1100 intptr_t DartUtilities::libraryHandleToLibraryId(Dart_Handle library) | |
| 1101 { | |
| 1102 intptr_t libraryId = -1; | |
| 1103 Dart_Handle ALLOW_UNUSED result = Dart_LibraryId(library, &libraryId); | |
| 1104 ASSERT(!Dart_IsError(result)); | |
| 1105 return libraryId; | |
| 1106 } | |
| 1107 | |
| 1108 DartScriptState* DartUtilities::currentScriptState() | |
| 1109 { | |
| 1110 DartDOMData* dartDOMData = DartDOMData::current(); | |
| 1111 if (!dartDOMData->rootScriptState()) { | |
| 1112 DartController* controller = DartController::retrieve(dartDOMData->scrip
tExecutionContext()); | |
| 1113 intptr_t libraryId = DartUtilities::libraryHandleToLibraryId(Dart_RootLi
brary()); | |
| 1114 DartScriptState* scriptState = controller->lookupScriptState(Dart_Curren
tIsolate(), currentV8Context(), libraryId); | |
| 1115 dartDOMData->setRootScriptState(scriptState); | |
| 1116 return scriptState; | |
| 1117 } | |
| 1118 return dartDOMData->rootScriptState(); | |
| 1119 } | |
| 1120 | |
| 1121 PassRefPtr<ScriptArguments> DartUtilities::createScriptArguments(Dart_Handle arg
ument, Dart_Handle& exception) | |
| 1122 { | |
| 1123 Vector<ScriptValue> arguments; | |
| 1124 arguments.append(DartUtilities::dartToScriptValue(argument)); | |
| 1125 return ScriptArguments::create(DartUtilities::currentScriptState(), argument
s); | |
| 1126 } | |
| 1127 | |
| 1128 static PassRefPtr<ScriptCallStack> createScriptCallStackFromStackTrace(Dart_Stac
kTrace stackTrace) | |
| 1129 { | |
| 1130 uintptr_t frameCount = 0; | |
| 1131 Dart_Handle result = Dart_StackTraceLength(stackTrace, reinterpret_cast<intp
tr_t*>(&frameCount)); | |
| 1132 if (Dart_IsError(result)) | |
| 1133 return nullptr; | |
| 1134 | |
| 1135 if (frameCount > ScriptCallStack::maxCallStackSizeToCapture) | |
| 1136 frameCount = ScriptCallStack::maxCallStackSizeToCapture; | |
| 1137 | |
| 1138 Dart_Isolate isolate = Dart_CurrentIsolate(); | |
| 1139 Vector<ScriptCallFrame> scriptCallStackFrames; | |
| 1140 for (uintptr_t frameIndex = 0; frameIndex < frameCount; frameIndex++) { | |
| 1141 Dart_ActivationFrame frame = 0; | |
| 1142 result = Dart_GetActivationFrame(stackTrace, frameIndex, &frame); | |
| 1143 if (Dart_IsError(result)) { | |
| 1144 return nullptr; | |
| 1145 } | |
| 1146 ASSERT(frame); | |
| 1147 | |
| 1148 Dart_Handle dartFunctionName; | |
| 1149 Dart_Handle dartScriptUrl; | |
| 1150 intptr_t lineNumber = 0; | |
| 1151 intptr_t columnNumber = 0; | |
| 1152 result = Dart_ActivationFrameInfo(frame, &dartFunctionName, &dartScriptU
rl, &lineNumber, &columnNumber); | |
| 1153 if (Dart_IsError(result)) { | |
| 1154 return nullptr; | |
| 1155 } | |
| 1156 | |
| 1157 // This skips frames where source is unavailable. WebKit code for the | |
| 1158 // console assumes that console.log et al. are implemented directly | |
| 1159 // as natives, i.e. that the top-of-stack will be the caller of | |
| 1160 // console.log. The Dart implementation involves intermediate Dart | |
| 1161 // calls, which are skipped by this clause. | |
| 1162 if (columnNumber == -1) | |
| 1163 continue; | |
| 1164 | |
| 1165 String functionName = DartUtilities::toString(dartFunctionName); | |
| 1166 String scriptUrl = DartUtilities::toString(dartScriptUrl); | |
| 1167 | |
| 1168 scriptCallStackFrames.append(ScriptCallFrame(functionName, DartScriptDeb
ugServer::shared().getScriptId(scriptUrl, isolate), scriptUrl, lineNumber, colum
nNumber)); | |
| 1169 } | |
| 1170 if (scriptCallStackFrames.isEmpty()) | |
| 1171 scriptCallStackFrames.append(ScriptCallFrame("undefined", "undefined", "
undefined", 0, 0)); | |
| 1172 | |
| 1173 return ScriptCallStack::create(scriptCallStackFrames); | |
| 1174 } | |
| 1175 | |
| 1176 ScriptCallFrame DartUtilities::getTopFrame(Dart_StackTrace stackTrace, Dart_Hand
le& exception) | |
| 1177 { | |
| 1178 { | |
| 1179 uintptr_t frameCount = 0; | |
| 1180 Dart_Handle result = Dart_StackTraceLength(stackTrace, reinterpret_cast<
intptr_t*>(&frameCount)); | |
| 1181 if (Dart_IsError(result)) { | |
| 1182 exception = result; | |
| 1183 goto fail; | |
| 1184 } | |
| 1185 if (!frameCount) { | |
| 1186 exception = Dart_NewStringFromCString("Empty stack trace"); | |
| 1187 goto fail; | |
| 1188 } | |
| 1189 Dart_ActivationFrame frame = 0; | |
| 1190 result = Dart_GetActivationFrame(stackTrace, 0, &frame); | |
| 1191 if (Dart_IsError(result)) { | |
| 1192 exception = result; | |
| 1193 goto fail; | |
| 1194 } | |
| 1195 ASSERT(frame); | |
| 1196 return toScriptCallFrame(frame, exception); | |
| 1197 } | |
| 1198 fail: | |
| 1199 return ScriptCallFrame("undefined", "undefined", "undefined", 0, 0); | |
| 1200 } | |
| 1201 | |
| 1202 ScriptCallFrame DartUtilities::toScriptCallFrame(Dart_ActivationFrame frame, Dar
t_Handle& exception) | |
| 1203 { | |
| 1204 ASSERT(frame); | |
| 1205 Dart_Handle functionName; | |
| 1206 Dart_Handle scriptUrl; | |
| 1207 intptr_t lineNumber = 0; | |
| 1208 intptr_t columnNumber = 0; | |
| 1209 Dart_Handle result = Dart_ActivationFrameInfo(frame, &functionName, &scriptU
rl, &lineNumber, &columnNumber); | |
| 1210 if (Dart_IsError(result)) { | |
| 1211 exception = result; | |
| 1212 return ScriptCallFrame("undefined", "undefined", "undefined", 0, 0); | |
| 1213 } | |
| 1214 return ScriptCallFrame(DartUtilities::toString(functionName), "undefined", D
artUtilities::toString(scriptUrl), lineNumber, columnNumber); | |
| 1215 } | |
| 1216 | |
| 1217 PassRefPtr<ScriptCallStack> DartUtilities::createScriptCallStack() | |
| 1218 { | |
| 1219 Dart_StackTrace trace = 0; | |
| 1220 Dart_Handle ALLOW_UNUSED result = Dart_GetStackTrace(&trace); | |
| 1221 ASSERT(!Dart_IsError(result)); | |
| 1222 ASSERT(!Dart_IsNull(result)); | |
| 1223 ASSERT(trace); | |
| 1224 return createScriptCallStackFromStackTrace(trace); | |
| 1225 } | |
| 1226 | |
| 1227 const uint8_t* DartUtilities::fullSnapshot(LocalFrame* frame) | |
| 1228 { | |
| 1229 static const uint8_t snapshotBuffer[] = { | |
| 1230 // DartSnapshot.bytes is generated by build system. | |
| 1231 #include "bindings/dart/DartSnapshot.bytes" | |
| 1232 }; | |
| 1233 return snapshotBuffer; | |
| 1234 } | |
| 1235 | |
| 1236 Dart_Handle DartUtilities::canonicalizeUrl(Dart_Handle library, Dart_Handle urlH
andle, String url) | |
| 1237 { | |
| 1238 DEFINE_STATIC_LOCAL(String, dartPrefix, ("dart:")); | |
| 1239 DEFINE_STATIC_LOCAL(String, packagePrefix, ("package:")); | |
| 1240 | |
| 1241 if (url.startsWith(dartPrefix) || url.startsWith(packagePrefix)) | |
| 1242 // Not a relative URL. | |
| 1243 return urlHandle; | |
| 1244 | |
| 1245 Dart_Handle libraryURLHandle = Dart_LibraryUrl(library); | |
| 1246 ASSERT(!Dart_IsError(libraryURLHandle)); | |
| 1247 String libraryURL = DartUtilities::toString(libraryURLHandle); | |
| 1248 | |
| 1249 String result; | |
| 1250 if (libraryURL.startsWith(packagePrefix) && !libraryURL.startsWith("package:
//")) { | |
| 1251 // KURL expects a URL with an authority. If the library URL is | |
| 1252 // "package:<path>", we convert to "package://_/<path>" for resolution | |
| 1253 // and convert back. | |
| 1254 DEFINE_STATIC_LOCAL(String, resolvePrefix, ("package://_/")); | |
| 1255 | |
| 1256 libraryURL = resolvePrefix + libraryURL.substring(packagePrefix.length()
); | |
| 1257 result = KURL(KURL(KURL(), libraryURL), url).string(); | |
| 1258 if (result.startsWith(resolvePrefix)) | |
| 1259 result = packagePrefix + result.substring(resolvePrefix.length()); | |
| 1260 } else { | |
| 1261 result = KURL(KURL(KURL(), libraryURL), url).string(); | |
| 1262 } | |
| 1263 | |
| 1264 return DartUtilities::stringToDartString(result); | |
| 1265 } | |
| 1266 | |
| 1267 void DartUtilities::reportProblem(ExecutionContext* context, const String& error
, int line, int col) | |
| 1268 { | |
| 1269 String sourceURL = context->url().string(); | |
| 1270 | |
| 1271 // FIXME: Pass in stack trace. | |
| 1272 if (context && context->isDocument()) { | |
| 1273 static_cast<Document*>(context)->reportException(ErrorEvent::create(erro
r, sourceURL, line, col, 0), nullptr, NotSharableCrossOrigin); | |
| 1274 } | |
| 1275 } | |
| 1276 | |
| 1277 void DartUtilities::reportProblem(ExecutionContext* context, Dart_Handle result) | |
| 1278 { | |
| 1279 // FIXME: provide sourceURL. | |
| 1280 String sourceURL = "FIXME"; | |
| 1281 reportProblem(context, result, sourceURL); | |
| 1282 } | |
| 1283 | |
| 1284 void DartUtilities::reportProblem(ExecutionContext* context, Dart_Handle result,
const String& sourceURL) | |
| 1285 { | |
| 1286 ASSERT(Dart_IsError(result)); | |
| 1287 ASSERT(!sourceURL.isEmpty()); | |
| 1288 | |
| 1289 const String internalErrorPrefix("Internal error: "); | |
| 1290 | |
| 1291 String errorMessage; | |
| 1292 // FIXME: line number info. | |
| 1293 int lineNumber = 0; | |
| 1294 // FIXME: call stack info. | |
| 1295 RefPtr<ScriptCallStack> callStack; | |
| 1296 | |
| 1297 if (!Dart_ErrorHasException(result)) { | |
| 1298 errorMessage = internalErrorPrefix + Dart_GetError(result); | |
| 1299 } else { | |
| 1300 // Print the exception. | |
| 1301 Dart_Handle exception = Dart_ErrorGetException(result); | |
| 1302 ASSERT(!Dart_IsError(exception)); | |
| 1303 | |
| 1304 exception = Dart_ToString(exception); | |
| 1305 if (Dart_IsError(exception)) | |
| 1306 errorMessage = String("Error: ") + Dart_GetError(exception); | |
| 1307 else | |
| 1308 errorMessage = String("Exception: ") + DartUtilities::toString(excep
tion); | |
| 1309 | |
| 1310 // Print the stack trace. | |
| 1311 Dart_StackTrace stacktrace; | |
| 1312 Dart_Handle ALLOW_UNUSED traceResult = Dart_GetStackTraceFromError(resul
t, &stacktrace); | |
| 1313 ASSERT(!Dart_IsError(traceResult)); | |
| 1314 callStack = createScriptCallStackFromStackTrace(stacktrace); | |
| 1315 } | |
| 1316 | |
| 1317 if (context && context->isDocument()) { | |
| 1318 static_cast<Document*>(context)->reportException(ErrorEvent::create(erro
rMessage, sourceURL, lineNumber, 0, 0), callStack, NotSharableCrossOrigin); | |
| 1319 } | |
| 1320 } | |
| 1321 | |
| 1322 Dart_Handle DartUtilities::toDartCoreException(const String& className, const St
ring& message) | |
| 1323 { | |
| 1324 DartApiScope apiScope; | |
| 1325 DartDOMData* domData = DartDOMData::current(); | |
| 1326 Dart_Handle coreLib = Dart_LookupLibrary(Dart_NewStringFromCString("dart:cor
e")); | |
| 1327 Dart_Handle errorClass = Dart_GetType(coreLib, stringToDart(className), 0, 0
); | |
| 1328 Dart_Handle dartMessage = stringToDart(message); | |
| 1329 Dart_Handle error = Dart_New(errorClass, Dart_NewStringFromCString(""), 1, &
dartMessage); | |
| 1330 Dart_SetPersistentHandle(domData->currentException(), error); | |
| 1331 return domData->currentException(); | |
| 1332 } | |
| 1333 | |
| 1334 Dart_Handle DartUtilities::coreArgumentErrorException(const String& message) | |
| 1335 { | |
| 1336 return DartUtilities::toDartCoreException("ArgumentError", message); | |
| 1337 } | |
| 1338 | |
| 1339 Dart_Handle DartUtilities::notImplementedException(const char* fileName, int lin
eNumber) | |
| 1340 { | |
| 1341 Dart_Handle args[2] = { Dart_NewStringFromCString(fileName), Dart_NewInteger
(lineNumber) }; | |
| 1342 Dart_Handle result = DartUtilities::invokeUtilsMethod("makeUnimplementedErro
r", 2, args); | |
| 1343 ASSERT(!Dart_IsError(result)); | |
| 1344 return result; | |
| 1345 } | |
| 1346 | |
| 1347 Dart_Handle DartUtilities::newResolvedPromise(Dart_Handle value) | |
| 1348 { | |
| 1349 Dart_Handle asyncLib = Dart_LookupLibrary(Dart_NewStringFromCString("dart:as
ync")); | |
| 1350 Dart_Handle futureClass = Dart_GetType(asyncLib, Dart_NewStringFromCString("
Future"), 0, 0); | |
| 1351 return Dart_New(futureClass, Dart_NewStringFromCString("value"), 1, &value); | |
| 1352 } | |
| 1353 | |
| 1354 Dart_Handle DartUtilities::newSmashedPromise(Dart_Handle error) | |
| 1355 { | |
| 1356 Dart_Handle asyncLib = Dart_LookupLibrary(Dart_NewStringFromCString("dart:as
ync")); | |
| 1357 Dart_Handle futureClass = Dart_GetType(asyncLib, Dart_NewStringFromCString("
Future"), 0, 0); | |
| 1358 return Dart_New(futureClass, Dart_NewStringFromCString("error"), 1, &error); | |
| 1359 } | |
| 1360 | |
| 1361 Dart_Handle DartUtilities::newResolver() | |
| 1362 { | |
| 1363 Dart_Handle asyncLib = Dart_LookupLibrary(Dart_NewStringFromCString("dart:as
ync")); | |
| 1364 Dart_Handle futureClass = Dart_GetType(asyncLib, Dart_NewStringFromCString("
Completer"), 0, 0); | |
| 1365 return Dart_New(futureClass, Dart_EmptyString(), 0, 0); | |
| 1366 } | |
| 1367 | |
| 1368 Dart_Handle DartUtilities::newArgumentError(const String& message) | |
| 1369 { | |
| 1370 Dart_Handle asyncLib = Dart_LookupLibrary(Dart_NewStringFromCString("dart:co
re")); | |
| 1371 Dart_Handle futureClass = Dart_GetType(asyncLib, Dart_NewStringFromCString("
ArgumentError"), 0, 0); | |
| 1372 Dart_Handle dartMessage = stringToDart(message); | |
| 1373 return Dart_New(futureClass, Dart_EmptyString(), 1, &dartMessage); | |
| 1374 } | |
| 1375 | |
| 1376 Dart_Handle DartUtilities::invokeUtilsMethod(const char* methodName, int argCoun
t, Dart_Handle* args) | |
| 1377 { | |
| 1378 DartDOMData* domData = DartDOMData::current(); | |
| 1379 ASSERT(domData); | |
| 1380 Dart_PersistentHandle library = domData->htmlLibrary(); | |
| 1381 ASSERT(!Dart_IsError(library)); | |
| 1382 | |
| 1383 Dart_Handle utilsClass = Dart_GetType(library, Dart_NewStringFromCString("_U
tils"), 0, 0); | |
| 1384 ASSERT(!Dart_IsError(utilsClass)); | |
| 1385 | |
| 1386 return Dart_Invoke(utilsClass, Dart_NewStringFromCString(methodName), argCou
nt, args); | |
| 1387 } | |
| 1388 | |
| 1389 | |
| 1390 int DartUtilities::getProp(const char* name, char* value, int valueLen) | |
| 1391 { | |
| 1392 #if OS(ANDROID) | |
| 1393 return __system_property_get(name, value); | |
| 1394 #else | |
| 1395 char* v = getenv(name); | |
| 1396 if (!v) { | |
| 1397 return 0; | |
| 1398 } | |
| 1399 ASSERT(valueLen > 0 && static_cast<size_t>(valueLen) > strlen(v)); | |
| 1400 strncpy(value, v, valueLen); | |
| 1401 value[valueLen - 1] = '\0'; | |
| 1402 return strlen(value); | |
| 1403 #endif | |
| 1404 } | |
| 1405 } | |
| OLD | NEW |