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 |