| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 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 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 681 return wrapper.As<v8::ArrayBuffer>(); | 681 return wrapper.As<v8::ArrayBuffer>(); |
| 682 } | 682 } |
| 683 | 683 |
| 684 class Serializer { | 684 class Serializer { |
| 685 class StateBase; | 685 class StateBase; |
| 686 public: | 686 public: |
| 687 enum Status { | 687 enum Status { |
| 688 Success, | 688 Success, |
| 689 InputError, | 689 InputError, |
| 690 DataCloneError, | 690 DataCloneError, |
| 691 InvalidStateError, | |
| 692 JSException, | 691 JSException, |
| 693 JSFailure | 692 JSFailure |
| 694 }; | 693 }; |
| 695 | 694 |
| 696 Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray*
arrayBuffers, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, v8::I
solate* isolate) | 695 Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray*
arrayBuffers, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, v8::I
solate* isolate) |
| 697 : m_writer(writer) | 696 : m_writer(writer) |
| 698 , m_tryCatch(tryCatch) | 697 , m_tryCatch(tryCatch) |
| 699 , m_depth(0) | 698 , m_depth(0) |
| 700 , m_status(Success) | 699 , m_status(Success) |
| 701 , m_nextObjectReference(0) | 700 , m_nextObjectReference(0) |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1124 greyObject(object); | 1123 greyObject(object); |
| 1125 return 0; | 1124 return 0; |
| 1126 } | 1125 } |
| 1127 | 1126 |
| 1128 StateBase* writeArrayBuffer(v8::Handle<v8::Value> value, StateBase* next) | 1127 StateBase* writeArrayBuffer(v8::Handle<v8::Value> value, StateBase* next) |
| 1129 { | 1128 { |
| 1130 ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>(
)); | 1129 ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>(
)); |
| 1131 if (!arrayBuffer) | 1130 if (!arrayBuffer) |
| 1132 return 0; | 1131 return 0; |
| 1133 if (arrayBuffer->isNeutered()) | 1132 if (arrayBuffer->isNeutered()) |
| 1134 return handleError(InvalidStateError, next); | 1133 return handleError(DataCloneError, next); |
| 1135 ASSERT(!m_transferredArrayBuffers.contains(value.As<v8::Object>())); | 1134 ASSERT(!m_transferredArrayBuffers.contains(value.As<v8::Object>())); |
| 1136 m_writer.writeArrayBuffer(*arrayBuffer); | 1135 m_writer.writeArrayBuffer(*arrayBuffer); |
| 1137 return 0; | 1136 return 0; |
| 1138 } | 1137 } |
| 1139 | 1138 |
| 1140 StateBase* writeTransferredArrayBuffer(v8::Handle<v8::Value> value, uint32_t
index, StateBase* next) | 1139 StateBase* writeTransferredArrayBuffer(v8::Handle<v8::Value> value, uint32_t
index, StateBase* next) |
| 1141 { | 1140 { |
| 1142 ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>(
)); | 1141 ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>(
)); |
| 1143 if (!arrayBuffer) | 1142 if (!arrayBuffer) |
| 1144 return 0; | 1143 return 0; |
| (...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2214 Vector<v8::Handle<v8::Value> > m_objectPool; | 2213 Vector<v8::Handle<v8::Value> > m_objectPool; |
| 2215 Vector<uint32_t> m_openCompositeReferenceStack; | 2214 Vector<uint32_t> m_openCompositeReferenceStack; |
| 2216 MessagePortArray* m_transferredMessagePorts; | 2215 MessagePortArray* m_transferredMessagePorts; |
| 2217 ArrayBufferContentsArray* m_arrayBufferContents; | 2216 ArrayBufferContentsArray* m_arrayBufferContents; |
| 2218 Vector<v8::Handle<v8::Object> > m_arrayBuffers; | 2217 Vector<v8::Handle<v8::Object> > m_arrayBuffers; |
| 2219 uint32_t m_version; | 2218 uint32_t m_version; |
| 2220 }; | 2219 }; |
| 2221 | 2220 |
| 2222 } // namespace | 2221 } // namespace |
| 2223 | 2222 |
| 2223 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::V
alue> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, Exc
eptionState& exceptionState, v8::Isolate* isolate) |
| 2224 { |
| 2225 bool didThrow; |
| 2226 return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers,
didThrow, &exceptionState, isolate)); |
| 2227 } |
| 2228 |
| 2224 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::V
alue> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, boo
l& didThrow, v8::Isolate* isolate) | 2229 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::V
alue> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, boo
l& didThrow, v8::Isolate* isolate) |
| 2225 { | 2230 { |
| 2226 return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers,
didThrow, isolate)); | 2231 return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers,
didThrow, 0, isolate)); |
| 2227 } | 2232 } |
| 2228 | 2233 |
| 2229 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createAndSwallowExcepti
ons(v8::Handle<v8::Value> value, v8::Isolate* isolate) | 2234 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createAndSwallowExcepti
ons(v8::Handle<v8::Value> value, v8::Isolate* isolate) |
| 2230 { | 2235 { |
| 2231 bool didThrow; | 2236 bool didThrow; |
| 2232 return adoptRef(new SerializedScriptValue(value, 0, 0, didThrow, isolate, Do
NotThrowExceptions)); | 2237 return adoptRef(new SerializedScriptValue(value, 0, 0, didThrow, 0, isolate,
DoNotThrowExceptions)); |
| 2233 } | 2238 } |
| 2234 | 2239 |
| 2235 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const ScriptValu
e& value, bool& didThrow, ScriptState* state) | 2240 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const ScriptValu
e& value, bool& didThrow, ScriptState* state) |
| 2236 { | 2241 { |
| 2237 ScriptScope scope(state); | 2242 ScriptScope scope(state); |
| 2238 return adoptRef(new SerializedScriptValue(value.v8Value(), 0, 0, didThrow, s
tate->isolate())); | 2243 return adoptRef(new SerializedScriptValue(value.v8Value(), 0, 0, didThrow, 0
, state->isolate())); |
| 2239 } | 2244 } |
| 2240 | 2245 |
| 2241 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(const St
ring& data) | 2246 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(const St
ring& data) |
| 2242 { | 2247 { |
| 2243 return adoptRef(new SerializedScriptValue(data)); | 2248 return adoptRef(new SerializedScriptValue(data)); |
| 2244 } | 2249 } |
| 2245 | 2250 |
| 2246 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWireBytes(con
st Vector<uint8_t>& data) | 2251 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWireBytes(con
st Vector<uint8_t>& data) |
| 2247 { | 2252 { |
| 2248 // Decode wire data from big endian to host byte order. | 2253 // Decode wire data from big endian to host byte order. |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2329 { | 2334 { |
| 2330 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 2335 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
| 2331 Vector<DOMDataStore*>& allStores = V8PerIsolateData::from(isolate)->allStore
s(); | 2336 Vector<DOMDataStore*>& allStores = V8PerIsolateData::from(isolate)->allStore
s(); |
| 2332 for (size_t i = 0; i < allStores.size(); i++) { | 2337 for (size_t i = 0; i < allStores.size(); i++) { |
| 2333 v8::Handle<v8::Object> wrapper = allStores[i]->get<V8ArrayBufferView>(ob
ject, isolate); | 2338 v8::Handle<v8::Object> wrapper = allStores[i]->get<V8ArrayBufferView>(ob
ject, isolate); |
| 2334 if (!wrapper.IsEmpty()) | 2339 if (!wrapper.IsEmpty()) |
| 2335 wrapper->SetIndexedPropertiesToExternalArrayData(0, v8::kExternalByt
eArray, 0); | 2340 wrapper->SetIndexedPropertiesToExternalArrayData(0, v8::kExternalByt
eArray, 0); |
| 2336 } | 2341 } |
| 2337 } | 2342 } |
| 2338 | 2343 |
| 2339 PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValu
e::transferArrayBuffers(ArrayBufferArray& arrayBuffers, bool& didThrow, v8::Isol
ate* isolate) | 2344 PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValu
e::transferArrayBuffers(ArrayBufferArray& arrayBuffers, bool& didThrow, Exceptio
nState* exceptionState, v8::Isolate* isolate) |
| 2340 { | 2345 { |
| 2341 ASSERT(arrayBuffers.size()); | 2346 ASSERT(arrayBuffers.size()); |
| 2342 | 2347 |
| 2343 for (size_t i = 0; i < arrayBuffers.size(); i++) { | 2348 for (size_t i = 0; i < arrayBuffers.size(); i++) { |
| 2344 if (arrayBuffers[i]->isNeutered()) { | 2349 if (arrayBuffers[i]->isNeutered()) { |
| 2345 setDOMException(InvalidStateError, isolate); | 2350 if (exceptionState) |
| 2351 exceptionState->throwDOMException(DataCloneError, "ArrayBuffer a
t index " + String::number(i) + " is already neutered."); |
| 2352 else |
| 2353 setDOMException(DataCloneError, isolate); |
| 2346 didThrow = true; | 2354 didThrow = true; |
| 2347 return nullptr; | 2355 return nullptr; |
| 2348 } | 2356 } |
| 2349 } | 2357 } |
| 2350 | 2358 |
| 2351 OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContents
Array(arrayBuffers.size())); | 2359 OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContents
Array(arrayBuffers.size())); |
| 2352 | 2360 |
| 2353 HashSet<ArrayBuffer*> visited; | 2361 HashSet<ArrayBuffer*> visited; |
| 2354 for (size_t i = 0; i < arrayBuffers.size(); i++) { | 2362 for (size_t i = 0; i < arrayBuffers.size(); i++) { |
| 2355 Vector<RefPtr<ArrayBufferView> > neuteredViews; | 2363 Vector<RefPtr<ArrayBufferView> > neuteredViews; |
| 2356 | 2364 |
| 2357 if (visited.contains(arrayBuffers[i].get())) | 2365 if (visited.contains(arrayBuffers[i].get())) |
| 2358 continue; | 2366 continue; |
| 2359 visited.add(arrayBuffers[i].get()); | 2367 visited.add(arrayBuffers[i].get()); |
| 2360 | 2368 |
| 2361 bool result = arrayBuffers[i]->transfer(contents->at(i), neuteredViews); | 2369 bool result = arrayBuffers[i]->transfer(contents->at(i), neuteredViews); |
| 2362 if (!result) { | 2370 if (!result) { |
| 2363 setDOMException(InvalidStateError, isolate); | 2371 if (exceptionState) |
| 2372 exceptionState->throwDOMException(DataCloneError, "ArrayBuffer a
t index " + String::number(i) + " could not be transferred."); |
| 2373 else |
| 2374 setDOMException(DataCloneError, isolate); |
| 2364 didThrow = true; | 2375 didThrow = true; |
| 2365 return nullptr; | 2376 return nullptr; |
| 2366 } | 2377 } |
| 2367 | 2378 |
| 2368 neuterBinding(arrayBuffers[i].get()); | 2379 neuterBinding(arrayBuffers[i].get()); |
| 2369 for (size_t j = 0; j < neuteredViews.size(); j++) | 2380 for (size_t j = 0; j < neuteredViews.size(); j++) |
| 2370 neuterBinding(neuteredViews[j].get()); | 2381 neuterBinding(neuteredViews[j].get()); |
| 2371 } | 2382 } |
| 2372 return contents.release(); | 2383 return contents.release(); |
| 2373 } | 2384 } |
| 2374 | 2385 |
| 2375 SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, Messag
ePortArray* messagePorts, ArrayBufferArray* arrayBuffers, bool& didThrow, v8::Is
olate* isolate, ExceptionPolicy policy) | 2386 SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, Messag
ePortArray* messagePorts, ArrayBufferArray* arrayBuffers, bool& didThrow, Except
ionState* exceptionState, v8::Isolate* isolate, ExceptionPolicy policy) |
| 2376 : m_externallyAllocatedMemory(0) | 2387 : m_externallyAllocatedMemory(0) |
| 2377 { | 2388 { |
| 2378 didThrow = false; | 2389 didThrow = false; |
| 2379 Writer writer(isolate); | 2390 Writer writer(isolate); |
| 2380 Serializer::Status status; | 2391 Serializer::Status status; |
| 2381 { | 2392 { |
| 2382 v8::TryCatch tryCatch; | 2393 v8::TryCatch tryCatch; |
| 2383 Serializer serializer(writer, messagePorts, arrayBuffers, m_blobDataHand
les, tryCatch, isolate); | 2394 Serializer serializer(writer, messagePorts, arrayBuffers, m_blobDataHand
les, tryCatch, isolate); |
| 2384 status = serializer.serialize(value); | 2395 status = serializer.serialize(value); |
| 2385 if (status == Serializer::JSException) { | 2396 if (status == Serializer::JSException) { |
| 2386 didThrow = true; | 2397 didThrow = true; |
| 2387 // If there was a JS exception thrown, re-throw it. | 2398 // If there was a JS exception thrown, re-throw it. |
| 2388 if (policy == ThrowExceptions) | 2399 if (policy == ThrowExceptions) { |
| 2389 tryCatch.ReThrow(); | 2400 if (exceptionState) |
| 2401 exceptionState->setException(tryCatch.Exception()); |
| 2402 else |
| 2403 tryCatch.ReThrow(); |
| 2404 } |
| 2390 return; | 2405 return; |
| 2391 } | 2406 } |
| 2392 } | 2407 } |
| 2393 switch (status) { | 2408 switch (status) { |
| 2394 case Serializer::InputError: | 2409 case Serializer::InputError: |
| 2395 case Serializer::DataCloneError: | 2410 case Serializer::DataCloneError: |
| 2396 // If there was an input error, throw a new exception outside | 2411 // If there was an input error, throw a new exception outside |
| 2397 // of the TryCatch scope. | 2412 // of the TryCatch scope. |
| 2398 didThrow = true; | 2413 didThrow = true; |
| 2399 if (policy == ThrowExceptions) | 2414 if (policy == ThrowExceptions) { |
| 2400 setDOMException(DataCloneError, isolate); | 2415 if (exceptionState) { |
| 2401 return; | 2416 // FIXME possible to generate a better error messsage than this? |
| 2402 case Serializer::InvalidStateError: | 2417 exceptionState->throwDOMException(DataCloneError, "An object cou
ld not be cloned."); |
| 2403 didThrow = true; | 2418 } else { |
| 2404 if (policy == ThrowExceptions) | 2419 setDOMException(DataCloneError, isolate); |
| 2405 setDOMException(InvalidStateError, isolate); | 2420 } |
| 2421 } |
| 2406 return; | 2422 return; |
| 2407 case Serializer::JSFailure: | 2423 case Serializer::JSFailure: |
| 2408 // If there was a JS failure (but no exception), there's not | 2424 // If there was a JS failure (but no exception), there's not |
| 2409 // much we can do except for unwinding the C++ stack by | 2425 // much we can do except for unwinding the C++ stack by |
| 2410 // pretending there was a JS exception. | 2426 // pretending there was a JS exception. |
| 2411 didThrow = true; | 2427 didThrow = true; |
| 2412 return; | 2428 return; |
| 2413 case Serializer::Success: | 2429 case Serializer::Success: |
| 2414 m_data = writer.takeWireString(); | 2430 m_data = writer.takeWireString(); |
| 2415 ASSERT(m_data.impl()->hasOneRef()); | 2431 ASSERT(m_data.impl()->hasOneRef()); |
| 2416 if (arrayBuffers && arrayBuffers->size()) | 2432 if (arrayBuffers && arrayBuffers->size()) |
| 2417 m_arrayBufferContentsArray = transferArrayBuffers(*arrayBuffers, did
Throw, isolate); | 2433 m_arrayBufferContentsArray = transferArrayBuffers(*arrayBuffers, did
Throw, exceptionState, isolate); |
| 2418 return; | 2434 return; |
| 2419 case Serializer::JSException: | 2435 case Serializer::JSException: |
| 2420 // We should never get here because this case was handled above. | 2436 // We should never get here because this case was handled above. |
| 2421 break; | 2437 break; |
| 2422 } | 2438 } |
| 2423 ASSERT_NOT_REACHED(); | 2439 ASSERT_NOT_REACHED(); |
| 2424 } | 2440 } |
| 2425 | 2441 |
| 2426 SerializedScriptValue::SerializedScriptValue(const String& wireData) | 2442 SerializedScriptValue::SerializedScriptValue(const String& wireData) |
| 2427 : m_externallyAllocatedMemory(0) | 2443 : m_externallyAllocatedMemory(0) |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2466 // If the allocated memory was not registered before, then this class is lik
ely | 2482 // If the allocated memory was not registered before, then this class is lik
ely |
| 2467 // used in a context other then Worker's onmessage environment and the prese
nce of | 2483 // used in a context other then Worker's onmessage environment and the prese
nce of |
| 2468 // current v8 context is not guaranteed. Avoid calling v8 then. | 2484 // current v8 context is not guaranteed. Avoid calling v8 then. |
| 2469 if (m_externallyAllocatedMemory) { | 2485 if (m_externallyAllocatedMemory) { |
| 2470 ASSERT(v8::Isolate::GetCurrent()); | 2486 ASSERT(v8::Isolate::GetCurrent()); |
| 2471 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_exte
rnallyAllocatedMemory); | 2487 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_exte
rnallyAllocatedMemory); |
| 2472 } | 2488 } |
| 2473 } | 2489 } |
| 2474 | 2490 |
| 2475 } // namespace WebCore | 2491 } // namespace WebCore |
| OLD | NEW |