Changeset 57133 in webkit
- Timestamp:
- Apr 6, 2010 1:12:48 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r57130 r57133 1 2010-04-06 Pavel Feldman <pfeldman@chromium.org> 2 3 Not reviewed: reverting v8 change at r57079 for crashing Chromium layout tests. 4 1 5 2010-04-05 MORITA Hajime <morrita@google.com> 2 6 -
trunk/WebCore/bindings/v8/SerializedScriptValue.cpp
r57079 r57133 32 32 #include "SerializedScriptValue.h" 33 33 34 #include "ByteArray.h"35 #include "CanvasPixelArray.h"36 #include "ImageData.h"37 34 #include "SharedBuffer.h" 38 #include "V8ImageData.h"39 35 40 36 #include <v8.h> … … 45 41 // FIXME: 46 42 // - catch V8 exceptions 43 // - be ready to get empty handles 47 44 // - consider crashing in debug mode on deserialization errors 48 45 … … 64 61 StringTag = 'S', 65 62 Int32Tag = 'I', 66 Uint32Tag = 'U',67 DateTag = 'D',68 63 NumberTag = 'N', 69 ImageDataTag = '#',64 ObjectTag = '{', 70 65 ArrayTag = '[', 71 ObjectTag = '{',72 SparseArrayTag = '@',73 66 }; 67 68 // Helpers to do verbose handle casts. 69 70 template <typename T, typename U> 71 static v8::Handle<T> handleCast(v8::Handle<U> handle) { return v8::Handle<T>::Cast(handle); } 72 73 template <typename T, typename U> 74 static v8::Local<T> handleCast(v8::Local<U> handle) { return v8::Local<T>::Cast(handle); } 74 75 75 76 static bool shouldCheckForCycles(int depth) … … 118 119 class Writer : Noncopyable { 119 120 public: 120 Writer() 121 : m_position(0) 121 Writer() : m_position(0) 122 122 { 123 123 } … … 135 135 void writeString(const char* data, int length) 136 136 { 137 ASSERT(length >= 0);138 137 append(StringTag); 139 138 doWriteUint32(static_cast<uint32_t>(length)); 140 append( reinterpret_cast<const uint8_t*>(data), length);139 append(data, length); 141 140 } 142 141 … … 147 146 } 148 147 149 void writeUint32(uint32_t value)150 {151 append(Uint32Tag);152 doWriteUint32(value);153 }154 155 void writeDate(double numberValue)156 {157 append(DateTag);158 doWriteNumber(numberValue);159 }160 161 148 void writeNumber(double number) 162 149 { 163 150 append(NumberTag); 164 doWriteNumber(number); 165 } 166 167 void writeImageData(uint32_t width, uint32_t height, const uint8_t* pixelData, uint32_t pixelDataLength) 168 { 169 append(ImageDataTag); 170 doWriteUint32(width); 171 doWriteUint32(height); 172 doWriteUint32(pixelDataLength); 173 append(pixelData, pixelDataLength); 174 } 175 176 void writeArray(uint32_t length) 177 { 178 append(ArrayTag); 179 doWriteUint32(length); 180 } 181 182 void writeObject(uint32_t numProperties) 183 { 184 append(ObjectTag); 185 doWriteUint32(numProperties); 186 } 187 188 void writeSparseArray(uint32_t numProperties, uint32_t length) 189 { 190 append(SparseArrayTag); 191 doWriteUint32(numProperties); 192 doWriteUint32(length); 151 append(reinterpret_cast<char*>(&number), sizeof(number)); 152 } 153 154 // Records that a composite object can be constructed by using 155 // |length| previously stored values. 156 void endComposite(SerializationTag tag, int32_t length) 157 { 158 ASSERT(tag == ObjectTag || tag == ArrayTag); 159 append(tag); 160 doWriteUint32(static_cast<uint32_t>(length)); 193 161 } 194 162 … … 203 171 { 204 172 while (true) { 205 uint8_tb = (value & varIntMask);173 char b = (value & varIntMask); 206 174 value >>= varIntShift; 207 175 if (!value) { … … 213 181 } 214 182 215 void doWriteNumber(double number)216 {217 append(reinterpret_cast<uint8_t*>(&number), sizeof(number));218 }219 220 183 void append(SerializationTag tag) 221 184 { 222 append(static_cast< uint8_t>(tag));223 } 224 225 void append( uint8_tb)185 append(static_cast<char>(tag)); 186 } 187 188 void append(char b) 226 189 { 227 190 ensureSpace(1); 228 * byteAt(m_position++) = b;229 } 230 231 void append(const uint8_t* data, int length)191 *charAt(m_position++) = b; 192 } 193 194 void append(const char* data, int length) 232 195 { 233 196 ensureSpace(length); 234 memcpy( byteAt(m_position), data, length);197 memcpy(charAt(m_position), data, length); 235 198 m_position += length; 236 199 } … … 248 211 // the bytes in the last UChar is not initialized. 249 212 if (m_position % 2) 250 * byteAt(m_position) = static_cast<uint8_t>(PaddingTag);251 } 252 253 uint8_t* byteAt(int position) { return reinterpret_cast<uint8_t*>(m_buffer.data()) + position; }213 *charAt(m_position) = static_cast<char>(PaddingTag); 214 } 215 216 char* charAt(int position) { return reinterpret_cast<char*>(m_buffer.data()) + position; } 254 217 255 218 Vector<BufferValueType> m_buffer; … … 258 221 259 222 class Serializer { 260 class StateBase;261 223 public: 262 224 explicit Serializer(Writer& writer) 263 225 : m_writer(writer) 226 , m_state(0) 264 227 , m_depth(0) 265 , m_hasError(false)266 228 { 267 229 } … … 270 232 { 271 233 v8::HandleScope scope; 272 StateBase* state = doSerialize(value, 0); 273 while (state) 274 state = state->advance(*this); 275 return !m_hasError; 276 } 277 278 // Functions used by serialization states. 279 280 StateBase* doSerialize(v8::Handle<v8::Value> value, StateBase* next); 281 282 StateBase* writeArray(uint32_t length, StateBase* state) 283 { 284 m_writer.writeArray(length); 285 return pop(state); 286 } 287 288 StateBase* writeObject(uint32_t numProperties, StateBase* state) 289 { 290 m_writer.writeObject(numProperties); 291 return pop(state); 292 } 293 294 StateBase* writeSparseArray(uint32_t numProperties, uint32_t length, StateBase* state) 295 { 296 m_writer.writeSparseArray(numProperties, length); 297 return pop(state); 234 StackCleaner cleaner(&m_state); 235 if (!doSerialize(value)) 236 return false; 237 while (top()) { 238 int length; 239 while (!top()->isDone(&length)) { 240 // Note that doSerialize() can change current top(). 241 if (!doSerialize(top()->advance())) 242 return false; 243 } 244 m_writer.endComposite(top()->tag(), length); 245 pop(); 246 } 247 return true; 298 248 } 299 249 … … 305 255 // Link to the next state to form a stack. 306 256 StateBase* nextState() { return m_next; } 257 void setNextState(StateBase* next) { m_next = next; } 307 258 308 259 // Composite object we're processing in this state. 309 260 v8::Handle<v8::Value> composite() { return m_composite; } 310 261 311 // Serializes (a part of) the current composite and returns 312 // the next state to process or null when this is the final 313 // state. 314 virtual StateBase* advance(Serializer&) = 0; 262 // Serialization tag for the current composite. 263 virtual SerializationTag tag() const = 0; 264 265 // Returns whether iteration over subobjects of the current 266 // composite object is done. If yes, |*length| is set to the 267 // number of subobjects. 268 virtual bool isDone(int* length) = 0; 269 270 // Advances to the next subobject. 271 // Requires: !this->isDone(). 272 virtual v8::Local<v8::Value> advance() = 0; 315 273 316 274 protected: 317 StateBase(v8::Handle<v8::Value> composite , StateBase* next)318 : m_ composite(composite)319 , m_ next(next)275 StateBase(v8::Handle<v8::Value> composite) 276 : m_next(0) 277 , m_composite(composite) 320 278 { 321 279 } 322 280 323 281 private: 282 StateBase* m_next; 324 283 v8::Handle<v8::Value> m_composite; 325 StateBase* m_next;326 284 }; 327 285 328 // Dummy state that is used to signal serialization errors. 329 class ErrorState : public StateBase { 330 public: 331 ErrorState() 332 : StateBase(v8::Handle<v8::Value>(), 0) 333 { 334 } 335 336 virtual StateBase* advance(Serializer&) 337 { 338 delete this; 339 return 0; 340 } 341 }; 342 343 template <typename T> 286 template <typename T, SerializationTag compositeTag> 344 287 class State : public StateBase { 345 288 public: 346 v8::Handle<T> composite() { return v8::Handle<T>::Cast(StateBase::composite()); } 289 v8::Handle<T> composite() { return handleCast<T>(StateBase::composite()); } 290 291 virtual SerializationTag tag() const { return compositeTag; } 347 292 348 293 protected: 349 State(v8::Handle<T> composite, StateBase* next) 350 : StateBase(composite, next) 294 explicit State(v8::Handle<T> composite) : StateBase(composite) 351 295 { 352 296 } 353 297 }; 354 298 355 #if 0 356 // Currently unused, see comment in newArrayState. 357 class ArrayState : public State<v8::Array> { 299 // Helper to clean up the state stack in case of errors. 300 class StackCleaner : Noncopyable { 358 301 public: 359 ArrayState(v8::Handle<v8::Array> array, StateBase* next) 360 : State<v8::Array>(array, next) 361 , m_index(-1) 362 { 363 } 364 365 virtual StateBase* advance(Serializer& serializer) 366 { 367 ++m_index; 368 for (; m_index < composite()->Length(); ++m_index) { 369 if (StateBase* newState = serializer.doSerialize(composite()->Get(m_index), this)) 370 return newState; 302 explicit StackCleaner(StateBase** stack) : m_stack(stack) 303 { 304 } 305 306 ~StackCleaner() 307 { 308 StateBase* state = *m_stack; 309 while (state) { 310 StateBase* tmp = state->nextState(); 311 delete state; 312 state = tmp; 371 313 } 372 return serializer.writeArray(composite()->Length(), this); 314 *m_stack = 0; 315 } 316 317 private: 318 StateBase** m_stack; 319 }; 320 321 class ArrayState : public State<v8::Array, ArrayTag> { 322 public: 323 ArrayState(v8::Handle<v8::Array> array) 324 : State<v8::Array, ArrayTag>(array) 325 , m_index(0) 326 { 327 } 328 329 virtual bool isDone(int* length) 330 { 331 *length = composite()->Length(); 332 return static_cast<int>(m_index) >= *length; 333 } 334 335 virtual v8::Local<v8::Value> advance() 336 { 337 ASSERT(m_index < composite()->Length()); 338 v8::HandleScope scope; 339 return scope.Close(composite()->Get(v8::Integer::New(m_index++))); 373 340 } 374 341 … … 376 343 unsigned m_index; 377 344 }; 378 #endif 379 380 class AbstractObjectState : public State<v8::Object> { 345 346 class ObjectState : public State<v8::Object, ObjectTag> { 381 347 public: 382 AbstractObjectState(v8::Handle<v8::Object> object, StateBase* next)383 : State<v8::Object >(object, next)348 ObjectState(v8::Handle<v8::Object> object) 349 : State<v8::Object, ObjectTag>(object) 384 350 , m_propertyNames(object->GetPropertyNames()) 385 351 , m_index(-1) 386 , m_nameDone(false) 387 { 388 } 389 390 virtual StateBase* advance(Serializer& serializer) 391 { 352 , m_length(0) 353 { 354 nextProperty(); 355 } 356 357 virtual bool isDone(int* length) 358 { 359 *length = m_length; 360 return m_index >= 2 * m_propertyNames->Length(); 361 } 362 363 virtual v8::Local<v8::Value> advance() 364 { 365 ASSERT(m_index < 2 * m_propertyNames->Length()); 366 if (!(m_index % 2)) { 367 ++m_index; 368 return m_propertyName; 369 } 370 v8::Local<v8::Value> result = composite()->Get(m_propertyName); 371 nextProperty(); 372 return result; 373 } 374 375 private: 376 void nextProperty() 377 { 378 v8::HandleScope scope; 392 379 ++m_index; 393 for (; m_index < m_propertyNames->Length(); ++m_index) {394 if (m_propertyName.IsEmpty()) {395 v8::Local<v8::Value> propertyName = m_propertyNames->Get(m_index);396 if ((propertyName->IsString() && composite()->HasRealNamedProperty(propertyName.As<v8::String>()))397 || (propertyName->IsUint32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value()))) {398 m_propertyName = propertyName;399 } else400 continue;380 ASSERT(!(m_index % 2)); 381 for (; m_index < 2 * m_propertyNames->Length(); m_index += 2) { 382 v8::Local<v8::Value> propertyName = m_propertyNames->Get(v8::Integer::New(m_index / 2)); 383 if ((propertyName->IsString() && composite()->HasRealNamedProperty(handleCast<v8::String>(propertyName))) 384 || (propertyName->IsInt32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value()))) { 385 m_propertyName = scope.Close(propertyName); 386 m_length += 2; 387 return; 401 388 } 402 ASSERT(!m_propertyName.IsEmpty());403 if (!m_nameDone) {404 m_nameDone = true;405 if (StateBase* newState = serializer.doSerialize(m_propertyName, this))406 return newState;407 }408 v8::Local<v8::Value> value = composite()->Get(m_propertyName);409 m_nameDone = false;410 m_propertyName.Clear();411 if (StateBase* newState = serializer.doSerialize(value, this))412 return newState;413 389 } 414 return objectDone(m_index, serializer); 415 } 416 417 protected: 418 virtual StateBase* objectDone(unsigned numProperties, Serializer&) = 0; 419 420 private: 390 } 391 421 392 v8::Local<v8::Array> m_propertyNames; 422 393 v8::Local<v8::Value> m_propertyName; 423 394 unsigned m_index; 424 bool m_nameDone;395 unsigned m_length; 425 396 }; 426 397 427 class ObjectState : public AbstractObjectState { 428 public: 429 ObjectState(v8::Handle<v8::Object> object, StateBase* next) 430 : AbstractObjectState(object, next) 431 { 432 } 433 434 protected: 435 virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) 436 { 437 return serializer.writeObject(numProperties, this); 438 } 439 }; 440 441 class SparseArrayState : public AbstractObjectState { 442 public: 443 SparseArrayState(v8::Handle<v8::Array> array, StateBase* next) 444 : AbstractObjectState(array, next) 445 { 446 } 447 448 protected: 449 virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) 450 { 451 return serializer.writeSparseArray(numProperties, composite().As<v8::Array>()->Length(), this); 452 } 453 }; 454 455 StateBase* push(StateBase* state) 456 { 457 ASSERT(state); 398 bool doSerialize(v8::Handle<v8::Value> value) 399 { 400 if (value->IsUndefined()) 401 m_writer.writeUndefined(); 402 else if (value->IsNull()) 403 m_writer.writeNull(); 404 else if (value->IsTrue()) 405 m_writer.writeTrue(); 406 else if (value->IsFalse()) 407 m_writer.writeFalse(); 408 else if (value->IsInt32()) 409 m_writer.writeInt32(value->Int32Value()); 410 else if (value->IsNumber()) 411 m_writer.writeNumber(handleCast<v8::Number>(value)->Value()); 412 else if (value->IsString()) { 413 v8::String::Utf8Value stringValue(value); 414 m_writer.writeString(*stringValue, stringValue.length()); 415 } else if (value->IsArray()) { 416 if (!checkComposite(value)) 417 return false; 418 push(new ArrayState(handleCast<v8::Array>(value))); 419 } else if (value->IsObject()) { 420 if (!checkComposite(value)) 421 return false; 422 push(new ObjectState(handleCast<v8::Object>(value))); 423 // FIXME: 424 // - check not a wrapper 425 // - support File, ImageData, etc. 426 } 427 return true; 428 } 429 430 void push(StateBase* state) 431 { 432 state->setNextState(m_state); 433 m_state = state; 458 434 ++m_depth; 459 return checkComposite(state) ? state : handleError(state); 460 } 461 462 StateBase* pop(StateBase* state) 463 { 464 ASSERT(state); 435 } 436 437 StateBase* top() { return m_state; } 438 439 void pop() 440 { 441 if (!m_state) 442 return; 443 StateBase* top = m_state; 444 m_state = top->nextState(); 445 delete top; 465 446 --m_depth; 466 StateBase* next = state->nextState(); 467 delete state; 468 return next; 469 } 470 471 StateBase* handleError(StateBase* state) 472 { 473 m_hasError = true; 474 while (state) { 475 StateBase* tmp = state->nextState(); 476 delete tmp; 477 state = tmp; 478 } 479 return new ErrorState; 480 } 481 482 bool checkComposite(StateBase* top) 483 { 484 ASSERT(top); 447 } 448 449 bool checkComposite(v8::Handle<v8::Value> composite) 450 { 485 451 if (m_depth > maxDepth) 486 452 return false; 487 453 if (!shouldCheckForCycles(m_depth)) 488 454 return true; 489 v8::Handle<v8::Value> composite = top->composite(); 490 for (StateBase* state = top->nextState(); state; state = state->nextState()) { 455 for (StateBase* state = top(); state; state = state->nextState()) { 491 456 if (state->composite() == composite) 492 457 return false; … … 495 460 } 496 461 497 void writeString(v8::Handle<v8::Value> value)498 {499 v8::String::Utf8Value stringValue(value);500 m_writer.writeString(*stringValue, stringValue.length());501 }502 503 void writeImageData(v8::Handle<v8::Value> value)504 {505 ImageData* imageData = V8ImageData::toNative(value.As<v8::Object>());506 if (!imageData)507 return;508 WTF::ByteArray* pixelArray = imageData->data()->data();509 m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray->data(), pixelArray->length());510 }511 512 static StateBase* newArrayState(v8::Handle<v8::Array> array, StateBase* next)513 {514 // FIXME: use plain Array state when we can quickly check that515 // an array is not sparse and has only indexed properties.516 return new SparseArrayState(array, next);517 }518 519 static StateBase* newObjectState(v8::Handle<v8::Object> object, StateBase* next)520 {521 // FIXME:522 // - check not a wrapper523 // - support File, etc.524 return new ObjectState(object, next);525 }526 527 462 Writer& m_writer; 463 StateBase* m_state; 528 464 int m_depth; 529 bool m_hasError;530 };531 532 Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, StateBase* next)533 {534 if (value->IsUndefined())535 m_writer.writeUndefined();536 else if (value->IsNull())537 m_writer.writeNull();538 else if (value->IsTrue())539 m_writer.writeTrue();540 else if (value->IsFalse())541 m_writer.writeFalse();542 else if (value->IsInt32())543 m_writer.writeInt32(value->Int32Value());544 else if (value->IsUint32())545 m_writer.writeUint32(value->Uint32Value());546 else if (value->IsDate())547 m_writer.writeDate(value->NumberValue());548 else if (value->IsNumber())549 m_writer.writeNumber(value.As<v8::Number>()->Value());550 else if (value->IsString())551 writeString(value);552 else if (value->IsArray())553 return push(newArrayState(value.As<v8::Array>(), next));554 else if (V8ImageData::HasInstance(value))555 writeImageData(value);556 else if (value->IsObject())557 return push(newObjectState(value.As<v8::Object>(), next));558 return 0;559 }560 561 // Interface used by Reader to create objects of composite types.562 class CompositeCreator {563 public:564 virtual ~CompositeCreator() { }565 566 virtual bool createArray(uint32_t length, v8::Handle<v8::Value>* value) = 0;567 virtual bool createObject(uint32_t numProperties, v8::Handle<v8::Value>* value) = 0;568 virtual bool createSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) = 0;569 465 }; 570 466 … … 573 469 class Reader { 574 470 public: 575 Reader(const uint8_t* buffer, int length)471 Reader(const char* buffer, int length) 576 472 : m_buffer(buffer) 577 473 , m_length(length) … … 583 479 bool isEof() const { return m_position >= m_length; } 584 480 585 bool read( v8::Handle<v8::Value>* value, CompositeCreator& creator)586 { 587 SerializationTag tag;588 if (!readTag( &tag))589 return false; 590 switch ( tag) {481 bool read(SerializationTag* tag, v8::Handle<v8::Value>* value, int* length) 482 { 483 uint32_t rawLength; 484 if (!readTag(tag)) 485 return false; 486 switch (*tag) { 591 487 case InvalidTag: 592 488 return false; 593 489 case PaddingTag: 594 return true;490 break; 595 491 case UndefinedTag: 596 492 *value = v8::Undefined(); … … 613 509 return false; 614 510 break; 615 case Uint32Tag:616 if (!readUint32(value))617 return false;618 break;619 case DateTag:620 if (!readDate(value))621 return false;622 break;623 511 case NumberTag: 624 512 if (!readNumber(value)) 625 513 return false; 626 514 break; 627 case ImageDataTag: 628 if (!readImageData(value)) 629 return false; 630 break; 631 case ArrayTag: { 632 uint32_t length; 633 if (!doReadUint32(&length)) 634 return false; 635 if (!creator.createArray(length, value)) 636 return false; 637 break; 638 } 639 case ObjectTag: { 640 uint32_t numProperties; 641 if (!doReadUint32(&numProperties)) 642 return false; 643 if (!creator.createObject(numProperties, value)) 644 return false; 645 break; 646 } 647 case SparseArrayTag: { 648 uint32_t numProperties; 649 uint32_t length; 650 if (!doReadUint32(&numProperties)) 651 return false; 652 if (!doReadUint32(&length)) 653 return false; 654 if (!creator.createSparseArray(numProperties, length, value)) 655 return false; 656 break; 657 } 658 default: 659 return false; 660 } 661 return !value->IsEmpty(); 515 case ObjectTag: 516 case ArrayTag: 517 if (!doReadUint32(&rawLength)) 518 return false; 519 *length = rawLength; 520 break; 521 } 522 return true; 662 523 } 663 524 … … 678 539 if (m_position + length > m_length) 679 540 return false; 680 *value = v8::String::New( reinterpret_cast<const char*>(m_buffer + m_position), length);541 *value = v8::String::New(m_buffer + m_position, length); 681 542 m_position += length; 682 543 return true; … … 692 553 } 693 554 694 bool readUint32(v8::Handle<v8::Value>* value)695 {696 uint32_t rawValue;697 if (!doReadUint32(&rawValue))698 return false;699 *value = v8::Integer::New(rawValue);700 return true;701 }702 703 bool readDate(v8::Handle<v8::Value>* value)704 {705 double numberValue;706 if (!doReadNumber(&numberValue))707 return false;708 *value = v8::Date::New(numberValue);709 return true;710 }711 712 555 bool readNumber(v8::Handle<v8::Value>* value) 713 556 { 557 if (m_position + sizeof(double) > m_length) 558 return false; 714 559 double number; 715 if (!doReadNumber(&number)) 716 return false; 560 char* numberAsByteArray = reinterpret_cast<char*>(&number); 561 for (unsigned i = 0; i < sizeof(double); ++i) 562 numberAsByteArray[i] = m_buffer[m_position++]; 717 563 *value = v8::Number::New(number); 718 564 return true; 719 565 } 720 566 721 bool readImageData(v8::Handle<v8::Value>* value)722 {723 uint32_t width;724 uint32_t height;725 uint32_t pixelDataLength;726 if (!doReadUint32(&width))727 return false;728 if (!doReadUint32(&height))729 return false;730 if (!doReadUint32(&pixelDataLength))731 return false;732 if (m_position + pixelDataLength > m_length)733 return false;734 PassRefPtr<ImageData> imageData = ImageData::create(width, height);735 WTF::ByteArray* pixelArray = imageData->data()->data();736 ASSERT(pixelArray);737 ASSERT(pixelArray->length() >= pixelDataLength);738 memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength);739 m_position += pixelDataLength;740 *value = toV8(imageData);741 return true;742 }743 744 567 bool doReadUint32(uint32_t* value) 745 568 { 746 569 *value = 0; 747 uint8_tcurrentByte;570 char currentByte; 748 571 int shift = 0; 749 572 do { … … 757 580 } 758 581 759 bool doReadNumber(double* number) 760 { 761 if (m_position + sizeof(double) > m_length) 762 return false; 763 uint8_t* numberAsByteArray = reinterpret_cast<uint8_t*>(number); 764 for (unsigned i = 0; i < sizeof(double); ++i) 765 numberAsByteArray[i] = m_buffer[m_position++]; 766 return true; 767 } 768 769 const uint8_t* m_buffer; 582 const char* m_buffer; 770 583 const unsigned m_length; 771 584 unsigned m_position; 772 585 }; 773 586 774 class Deserializer : public CompositeCreator{587 class Deserializer { 775 588 public: 776 explicit Deserializer(Reader& reader) 777 : m_reader(reader) 589 explicit Deserializer(Reader& reader) : m_reader(reader) 778 590 { 779 591 } … … 791 603 } 792 604 793 virtual bool createArray(uint32_t length, v8::Handle<v8::Value>* value)794 {795 if (length > stackDepth())796 return false;797 v8::Local<v8::Array> array = v8::Array::New(length);798 if (array.IsEmpty())799 return false;800 const int depth = stackDepth() - length;801 for (unsigned i = 0; i < length; ++i)802 array->Set(i, element(depth + i));803 pop(length);804 *value = array;805 return true;806 }807 808 virtual bool createObject(uint32_t numProperties, v8::Handle<v8::Value>* value)809 {810 v8::Local<v8::Object> object = v8::Object::New();811 if (object.IsEmpty())812 return false;813 return initializeObject(object, numProperties, value);814 }815 816 virtual bool createSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value)817 {818 v8::Local<v8::Array> array = v8::Array::New(length);819 if (array.IsEmpty())820 return false;821 return initializeObject(array, numProperties, value);822 }823 824 605 private: 825 bool initializeObject(v8::Handle<v8::Object> object, uint32_t numProperties, v8::Handle<v8::Value>* value)826 {827 unsigned length = 2 * numProperties;828 if (length > stackDepth())829 return false;830 for (unsigned i = stackDepth() - length; i < stackDepth(); i += 2) {831 v8::Local<v8::Value> propertyName = element(i);832 v8::Local<v8::Value> propertyValue = element(i + 1);833 object->Set(propertyName, propertyValue);834 }835 pop(length);836 *value = object;837 return true;838 }839 840 606 bool doDeserialize() 841 607 { 608 SerializationTag tag; 842 609 v8::Local<v8::Value> value; 843 if (!m_reader.read(&value, *this)) 844 return false; 845 if (!value.IsEmpty()) 610 int length = 0; 611 if (!m_reader.read(&tag, &value, &length)) 612 return false; 613 if (!value.IsEmpty()) { 846 614 push(value); 615 } else if (tag == ObjectTag) { 616 if (length > stackDepth()) 617 return false; 618 v8::Local<v8::Object> object = v8::Object::New(); 619 for (int i = stackDepth() - length; i < stackDepth(); i += 2) { 620 v8::Local<v8::Value> propertyName = element(i); 621 v8::Local<v8::Value> propertyValue = element(i + 1); 622 object->Set(propertyName, propertyValue); 623 } 624 pop(length); 625 push(object); 626 } else if (tag == ArrayTag) { 627 if (length > stackDepth()) 628 return false; 629 v8::Local<v8::Array> array = v8::Array::New(length); 630 const int depth = stackDepth() - length; 631 { 632 v8::HandleScope scope; 633 for (int i = 0; i < length; ++i) 634 array->Set(v8::Integer::New(i), element(depth + i)); 635 } 636 pop(length); 637 push(array); 638 } else if (tag != PaddingTag) 639 return false; 847 640 return true; 848 641 } … … 856 649 } 857 650 858 unsignedstackDepth() const { return m_stack.size(); }651 int stackDepth() const { return m_stack.size(); } 859 652 860 653 v8::Local<v8::Value> element(unsigned index) … … 899 692 return v8::Null(); 900 693 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); 901 Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters()), 2 * m_data.length());694 Reader reader(reinterpret_cast<const char*>(m_data.impl()->characters()), 2 * m_data.length()); 902 695 Deserializer deserializer(reader); 903 696 return deserializer.deserialize();
Note: See TracChangeset
for help on using the changeset viewer.