SerializedScriptValue.cpp 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995
  1. /*
  2. * Copyright (C) 2009, 2013 Apple Inc. 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
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
  17. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  18. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  20. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  21. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. *
  25. */
  26. #include "config.h"
  27. #include "SerializedScriptValue.h"
  28. #include "Blob.h"
  29. #include "ExceptionCode.h"
  30. #include "File.h"
  31. #include "FileList.h"
  32. #include "ImageData.h"
  33. #include "JSArrayBuffer.h"
  34. #include "JSArrayBufferView.h"
  35. #include "JSBlob.h"
  36. #include "JSDataView.h"
  37. #include "JSDOMGlobalObject.h"
  38. #include "JSFile.h"
  39. #include "JSFileList.h"
  40. #include "JSFloat32Array.h"
  41. #include "JSFloat64Array.h"
  42. #include "JSImageData.h"
  43. #include "JSInt16Array.h"
  44. #include "JSInt32Array.h"
  45. #include "JSInt8Array.h"
  46. #include "JSMessagePort.h"
  47. #include "JSNavigator.h"
  48. #include "JSUint16Array.h"
  49. #include "JSUint32Array.h"
  50. #include "JSUint8Array.h"
  51. #include "JSUint8ClampedArray.h"
  52. #include "NotImplemented.h"
  53. #include "ScriptValue.h"
  54. #include "SharedBuffer.h"
  55. #include "WebCoreJSClientData.h"
  56. #include <limits>
  57. #include <JavaScriptCore/APICast.h>
  58. #include <JavaScriptCore/APIShims.h>
  59. #include <runtime/BooleanObject.h>
  60. #include <runtime/DateInstance.h>
  61. #include <runtime/Error.h>
  62. #include <runtime/ExceptionHelpers.h>
  63. #include <runtime/ObjectConstructor.h>
  64. #include <runtime/Operations.h>
  65. #include <runtime/PropertyNameArray.h>
  66. #include <runtime/RegExp.h>
  67. #include <runtime/RegExpObject.h>
  68. #include <wtf/ArrayBuffer.h>
  69. #include <wtf/HashTraits.h>
  70. #include <wtf/Uint8ClampedArray.h>
  71. #include <wtf/Vector.h>
  72. using namespace JSC;
  73. using namespace std;
  74. #if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN) || CPU(NEEDS_ALIGNED_ACCESS)
  75. #define ASSUME_LITTLE_ENDIAN 0
  76. #else
  77. #define ASSUME_LITTLE_ENDIAN 1
  78. #endif
  79. namespace WebCore {
  80. static const unsigned maximumFilterRecursion = 40000;
  81. enum WalkerState { StateUnknown, ArrayStartState, ArrayStartVisitMember, ArrayEndVisitMember,
  82. ObjectStartState, ObjectStartVisitMember, ObjectEndVisitMember };
  83. // These can't be reordered, and any new types must be added to the end of the list
  84. enum SerializationTag {
  85. ArrayTag = 1,
  86. ObjectTag = 2,
  87. UndefinedTag = 3,
  88. NullTag = 4,
  89. IntTag = 5,
  90. ZeroTag = 6,
  91. OneTag = 7,
  92. FalseTag = 8,
  93. TrueTag = 9,
  94. DoubleTag = 10,
  95. DateTag = 11,
  96. FileTag = 12,
  97. FileListTag = 13,
  98. ImageDataTag = 14,
  99. BlobTag = 15,
  100. StringTag = 16,
  101. EmptyStringTag = 17,
  102. RegExpTag = 18,
  103. ObjectReferenceTag = 19,
  104. MessagePortReferenceTag = 20,
  105. ArrayBufferTag = 21,
  106. ArrayBufferViewTag = 22,
  107. ArrayBufferTransferTag = 23,
  108. TrueObjectTag = 24,
  109. FalseObjectTag = 25,
  110. StringObjectTag = 26,
  111. EmptyStringObjectTag = 27,
  112. NumberObjectTag = 28,
  113. ErrorTag = 255
  114. };
  115. enum ArrayBufferViewSubtag {
  116. DataViewTag = 0,
  117. Int8ArrayTag = 1,
  118. Uint8ArrayTag = 2,
  119. Uint8ClampedArrayTag = 3,
  120. Int16ArrayTag = 4,
  121. Uint16ArrayTag = 5,
  122. Int32ArrayTag = 6,
  123. Uint32ArrayTag = 7,
  124. Float32ArrayTag = 8,
  125. Float64ArrayTag = 9
  126. };
  127. static unsigned typedArrayElementSize(ArrayBufferViewSubtag tag)
  128. {
  129. switch (tag) {
  130. case DataViewTag:
  131. case Int8ArrayTag:
  132. case Uint8ArrayTag:
  133. case Uint8ClampedArrayTag:
  134. return 1;
  135. case Int16ArrayTag:
  136. case Uint16ArrayTag:
  137. return 2;
  138. case Int32ArrayTag:
  139. case Uint32ArrayTag:
  140. case Float32ArrayTag:
  141. return 4;
  142. case Float64ArrayTag:
  143. return 8;
  144. default:
  145. return 0;
  146. }
  147. }
  148. /* CurrentVersion tracks the serialization version so that persistant stores
  149. * are able to correctly bail out in the case of encountering newer formats.
  150. *
  151. * Initial version was 1.
  152. * Version 2. added the ObjectReferenceTag and support for serialization of cyclic graphs.
  153. * Version 3. added the FalseObjectTag, TrueObjectTag, NumberObjectTag, StringObjectTag
  154. * and EmptyStringObjectTag for serialization of Boolean, Number and String objects.
  155. * Version 4. added support for serializing non-index properties of arrays.
  156. */
  157. static const unsigned CurrentVersion = 4;
  158. static const unsigned TerminatorTag = 0xFFFFFFFF;
  159. static const unsigned StringPoolTag = 0xFFFFFFFE;
  160. static const unsigned NonIndexPropertiesTag = 0xFFFFFFFD;
  161. /*
  162. * Object serialization is performed according to the following grammar, all tags
  163. * are recorded as a single uint8_t.
  164. *
  165. * IndexType (used for the object pool and StringData's constant pool) is the
  166. * minimum sized unsigned integer type required to represent the maximum index
  167. * in the constant pool.
  168. *
  169. * SerializedValue :- <CurrentVersion:uint32_t> Value
  170. * Value :- Array | Object | Terminal
  171. *
  172. * Array :-
  173. * ArrayTag <length:uint32_t>(<index:uint32_t><value:Value>)* TerminatorTag
  174. *
  175. * Object :-
  176. * ObjectTag (<name:StringData><value:Value>)* TerminatorTag
  177. *
  178. * Terminal :-
  179. * UndefinedTag
  180. * | NullTag
  181. * | IntTag <value:int32_t>
  182. * | ZeroTag
  183. * | OneTag
  184. * | FalseTag
  185. * | TrueTag
  186. * | FalseObjectTag
  187. * | TrueObjectTag
  188. * | DoubleTag <value:double>
  189. * | NumberObjectTag <value:double>
  190. * | DateTag <value:double>
  191. * | String
  192. * | EmptyStringTag
  193. * | EmptyStringObjectTag
  194. * | File
  195. * | FileList
  196. * | ImageData
  197. * | Blob
  198. * | ObjectReference
  199. * | MessagePortReferenceTag <value:uint32_t>
  200. * | ArrayBuffer
  201. * | ArrayBufferViewTag ArrayBufferViewSubtag <byteOffset:uint32_t> <byteLenght:uint32_t> (ArrayBuffer | ObjectReference)
  202. * | ArrayBufferTransferTag <value:uint32_t>
  203. *
  204. * String :-
  205. * EmptyStringTag
  206. * StringTag StringData
  207. *
  208. * StringObject:
  209. * EmptyStringObjectTag
  210. * StringObjectTag StringData
  211. *
  212. * StringData :-
  213. * StringPoolTag <cpIndex:IndexType>
  214. * (not (TerminatorTag | StringPoolTag))<length:uint32_t><characters:UChar{length}> // Added to constant pool when seen, string length 0xFFFFFFFF is disallowed
  215. *
  216. * File :-
  217. * FileTag FileData
  218. *
  219. * FileData :-
  220. * <path:StringData> <url:StringData> <type:StringData>
  221. *
  222. * FileList :-
  223. * FileListTag <length:uint32_t>(<file:FileData>){length}
  224. *
  225. * ImageData :-
  226. * ImageDataTag <width:int32_t><height:int32_t><length:uint32_t><data:uint8_t{length}>
  227. *
  228. * Blob :-
  229. * BlobTag <url:StringData><type:StringData><size:long long>
  230. *
  231. * RegExp :-
  232. * RegExpTag <pattern:StringData><flags:StringData>
  233. *
  234. * ObjectReference :-
  235. * ObjectReferenceTag <opIndex:IndexType>
  236. *
  237. * ArrayBuffer :-
  238. * ArrayBufferTag <length:uint32_t> <contents:byte{length}>
  239. */
  240. typedef pair<JSC::JSValue, SerializationReturnCode> DeserializationResult;
  241. class CloneBase {
  242. protected:
  243. CloneBase(ExecState* exec)
  244. : m_exec(exec)
  245. , m_failed(false)
  246. {
  247. }
  248. bool shouldTerminate()
  249. {
  250. return m_exec->hadException();
  251. }
  252. void throwStackOverflow()
  253. {
  254. throwError(m_exec, createStackOverflowError(m_exec));
  255. }
  256. NO_RETURN_DUE_TO_ASSERT
  257. void fail()
  258. {
  259. ASSERT_NOT_REACHED();
  260. m_failed = true;
  261. }
  262. ExecState* m_exec;
  263. bool m_failed;
  264. MarkedArgumentBuffer m_gcBuffer;
  265. };
  266. #if ASSUME_LITTLE_ENDIAN
  267. template <typename T> static void writeLittleEndian(Vector<uint8_t>& buffer, T value)
  268. {
  269. buffer.append(reinterpret_cast<uint8_t*>(&value), sizeof(value));
  270. }
  271. #else
  272. template <typename T> static void writeLittleEndian(Vector<uint8_t>& buffer, T value)
  273. {
  274. for (unsigned i = 0; i < sizeof(T); i++) {
  275. buffer.append(value & 0xFF);
  276. value >>= 8;
  277. }
  278. }
  279. #endif
  280. template <> void writeLittleEndian<uint8_t>(Vector<uint8_t>& buffer, uint8_t value)
  281. {
  282. buffer.append(value);
  283. }
  284. template <typename T> static bool writeLittleEndian(Vector<uint8_t>& buffer, const T* values, uint32_t length)
  285. {
  286. if (length > numeric_limits<uint32_t>::max() / sizeof(T))
  287. return false;
  288. #if ASSUME_LITTLE_ENDIAN
  289. buffer.append(reinterpret_cast<const uint8_t*>(values), length * sizeof(T));
  290. #else
  291. for (unsigned i = 0; i < length; i++) {
  292. T value = values[i];
  293. for (unsigned j = 0; j < sizeof(T); j++) {
  294. buffer.append(static_cast<uint8_t>(value & 0xFF));
  295. value >>= 8;
  296. }
  297. }
  298. #endif
  299. return true;
  300. }
  301. class CloneSerializer : CloneBase {
  302. public:
  303. static SerializationReturnCode serialize(ExecState* exec, JSValue value,
  304. MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers,
  305. Vector<String>& blobURLs, Vector<uint8_t>& out)
  306. {
  307. CloneSerializer serializer(exec, messagePorts, arrayBuffers, blobURLs, out);
  308. return serializer.serialize(value);
  309. }
  310. static bool serialize(const String& s, Vector<uint8_t>& out)
  311. {
  312. writeLittleEndian(out, CurrentVersion);
  313. if (s.isEmpty()) {
  314. writeLittleEndian<uint8_t>(out, EmptyStringTag);
  315. return true;
  316. }
  317. writeLittleEndian<uint8_t>(out, StringTag);
  318. writeLittleEndian(out, s.length());
  319. return writeLittleEndian(out, s.impl()->characters(), s.length());
  320. }
  321. static void serializeUndefined(Vector<uint8_t>& out)
  322. {
  323. writeLittleEndian(out, CurrentVersion);
  324. writeLittleEndian<uint8_t>(out, UndefinedTag);
  325. }
  326. static void serializeBoolean(bool value, Vector<uint8_t>& out)
  327. {
  328. writeLittleEndian(out, CurrentVersion);
  329. writeLittleEndian<uint8_t>(out, value ? TrueTag : FalseTag);
  330. }
  331. static void serializeNumber(double value, Vector<uint8_t>& out)
  332. {
  333. writeLittleEndian(out, CurrentVersion);
  334. writeLittleEndian<uint8_t>(out, DoubleTag);
  335. union {
  336. double d;
  337. int64_t i;
  338. } u;
  339. u.d = value;
  340. writeLittleEndian(out, u.i);
  341. }
  342. private:
  343. typedef HashMap<JSObject*, uint32_t> ObjectPool;
  344. CloneSerializer(ExecState* exec, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, Vector<String>& blobURLs, Vector<uint8_t>& out)
  345. : CloneBase(exec)
  346. , m_buffer(out)
  347. , m_blobURLs(blobURLs)
  348. , m_emptyIdentifier(exec, emptyString())
  349. {
  350. write(CurrentVersion);
  351. fillTransferMap(messagePorts, m_transferredMessagePorts);
  352. fillTransferMap(arrayBuffers, m_transferredArrayBuffers);
  353. }
  354. template <class T>
  355. void fillTransferMap(Vector<RefPtr<T>, 1>* input, ObjectPool& result)
  356. {
  357. if (!input)
  358. return;
  359. JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(m_exec->lexicalGlobalObject());
  360. for (size_t i = 0; i < input->size(); i++) {
  361. JSC::JSValue value = toJS(m_exec, globalObject, input->at(i).get());
  362. JSC::JSObject* obj = value.getObject();
  363. if (obj && !result.contains(obj))
  364. result.add(obj, i);
  365. }
  366. }
  367. SerializationReturnCode serialize(JSValue in);
  368. bool isArray(JSValue value)
  369. {
  370. if (!value.isObject())
  371. return false;
  372. JSObject* object = asObject(value);
  373. return isJSArray(object) || object->inherits(&JSArray::s_info);
  374. }
  375. bool checkForDuplicate(JSObject* object)
  376. {
  377. // Record object for graph reconstruction
  378. ObjectPool::const_iterator found = m_objectPool.find(object);
  379. // Handle duplicate references
  380. if (found != m_objectPool.end()) {
  381. write(ObjectReferenceTag);
  382. ASSERT(static_cast<int32_t>(found->value) < m_objectPool.size());
  383. writeObjectIndex(found->value);
  384. return true;
  385. }
  386. return false;
  387. }
  388. void recordObject(JSObject* object)
  389. {
  390. m_objectPool.add(object, m_objectPool.size());
  391. m_gcBuffer.append(object);
  392. }
  393. bool startObjectInternal(JSObject* object)
  394. {
  395. if (checkForDuplicate(object))
  396. return false;
  397. recordObject(object);
  398. return true;
  399. }
  400. bool startObject(JSObject* object)
  401. {
  402. if (!startObjectInternal(object))
  403. return false;
  404. write(ObjectTag);
  405. return true;
  406. }
  407. bool startArray(JSArray* array)
  408. {
  409. if (!startObjectInternal(array))
  410. return false;
  411. unsigned length = array->length();
  412. write(ArrayTag);
  413. write(length);
  414. return true;
  415. }
  416. void endObject()
  417. {
  418. write(TerminatorTag);
  419. }
  420. JSValue getProperty(JSObject* object, const Identifier& propertyName)
  421. {
  422. PropertySlot slot(object);
  423. if (object->methodTable()->getOwnPropertySlot(object, m_exec, propertyName, slot))
  424. return slot.getValue(m_exec, propertyName);
  425. return JSValue();
  426. }
  427. void dumpImmediate(JSValue value)
  428. {
  429. if (value.isNull())
  430. write(NullTag);
  431. else if (value.isUndefined())
  432. write(UndefinedTag);
  433. else if (value.isNumber()) {
  434. if (value.isInt32()) {
  435. if (!value.asInt32())
  436. write(ZeroTag);
  437. else if (value.asInt32() == 1)
  438. write(OneTag);
  439. else {
  440. write(IntTag);
  441. write(static_cast<uint32_t>(value.asInt32()));
  442. }
  443. } else {
  444. write(DoubleTag);
  445. write(value.asDouble());
  446. }
  447. } else if (value.isBoolean()) {
  448. if (value.isTrue())
  449. write(TrueTag);
  450. else
  451. write(FalseTag);
  452. }
  453. }
  454. void dumpString(String str)
  455. {
  456. if (str.isEmpty())
  457. write(EmptyStringTag);
  458. else {
  459. write(StringTag);
  460. write(str);
  461. }
  462. }
  463. void dumpStringObject(String str)
  464. {
  465. if (str.isEmpty())
  466. write(EmptyStringObjectTag);
  467. else {
  468. write(StringObjectTag);
  469. write(str);
  470. }
  471. }
  472. bool dumpArrayBufferView(JSObject* obj, SerializationReturnCode& code)
  473. {
  474. write(ArrayBufferViewTag);
  475. if (obj->inherits(&JSDataView::s_info))
  476. write(DataViewTag);
  477. else if (obj->inherits(&JSUint8ClampedArray::s_info))
  478. write(Uint8ClampedArrayTag);
  479. else if (obj->inherits(&JSInt8Array::s_info))
  480. write(Int8ArrayTag);
  481. else if (obj->inherits(&JSUint8Array::s_info))
  482. write(Uint8ArrayTag);
  483. else if (obj->inherits(&JSInt16Array::s_info))
  484. write(Int16ArrayTag);
  485. else if (obj->inherits(&JSUint16Array::s_info))
  486. write(Uint16ArrayTag);
  487. else if (obj->inherits(&JSInt32Array::s_info))
  488. write(Int32ArrayTag);
  489. else if (obj->inherits(&JSUint32Array::s_info))
  490. write(Uint32ArrayTag);
  491. else if (obj->inherits(&JSFloat32Array::s_info))
  492. write(Float32ArrayTag);
  493. else if (obj->inherits(&JSFloat64Array::s_info))
  494. write(Float64ArrayTag);
  495. else
  496. return false;
  497. RefPtr<ArrayBufferView> arrayBufferView = toArrayBufferView(obj);
  498. write(static_cast<uint32_t>(arrayBufferView->byteOffset()));
  499. write(static_cast<uint32_t>(arrayBufferView->byteLength()));
  500. RefPtr<ArrayBuffer> arrayBuffer = arrayBufferView->buffer();
  501. if (!arrayBuffer) {
  502. code = ValidationError;
  503. return true;
  504. }
  505. JSValue bufferObj = toJS(m_exec, jsCast<JSDOMGlobalObject*>(m_exec->lexicalGlobalObject()), arrayBuffer.get());
  506. return dumpIfTerminal(bufferObj, code);
  507. }
  508. bool dumpIfTerminal(JSValue value, SerializationReturnCode& code)
  509. {
  510. if (!value.isCell()) {
  511. dumpImmediate(value);
  512. return true;
  513. }
  514. if (value.isString()) {
  515. String str = asString(value)->value(m_exec);
  516. dumpString(str);
  517. return true;
  518. }
  519. if (value.isNumber()) {
  520. write(DoubleTag);
  521. write(value.asNumber());
  522. return true;
  523. }
  524. if (value.isObject() && asObject(value)->inherits(&DateInstance::s_info)) {
  525. write(DateTag);
  526. write(asDateInstance(value)->internalNumber());
  527. return true;
  528. }
  529. if (isArray(value))
  530. return false;
  531. if (value.isObject()) {
  532. JSObject* obj = asObject(value);
  533. if (obj->inherits(&BooleanObject::s_info)) {
  534. if (!startObjectInternal(obj)) // handle duplicates
  535. return true;
  536. write(asBooleanObject(value)->internalValue().toBoolean(m_exec) ? TrueObjectTag : FalseObjectTag);
  537. return true;
  538. }
  539. if (obj->inherits(&StringObject::s_info)) {
  540. if (!startObjectInternal(obj)) // handle duplicates
  541. return true;
  542. String str = asString(asStringObject(value)->internalValue())->value(m_exec);
  543. dumpStringObject(str);
  544. return true;
  545. }
  546. if (obj->inherits(&NumberObject::s_info)) {
  547. if (!startObjectInternal(obj)) // handle duplicates
  548. return true;
  549. write(NumberObjectTag);
  550. NumberObject* obj = static_cast<NumberObject*>(asObject(value));
  551. write(obj->internalValue().asNumber());
  552. return true;
  553. }
  554. if (obj->inherits(&JSFile::s_info)) {
  555. write(FileTag);
  556. write(toFile(obj));
  557. return true;
  558. }
  559. if (obj->inherits(&JSFileList::s_info)) {
  560. FileList* list = toFileList(obj);
  561. write(FileListTag);
  562. unsigned length = list->length();
  563. write(length);
  564. for (unsigned i = 0; i < length; i++)
  565. write(list->item(i));
  566. return true;
  567. }
  568. if (obj->inherits(&JSBlob::s_info)) {
  569. write(BlobTag);
  570. Blob* blob = toBlob(obj);
  571. m_blobURLs.append(blob->url());
  572. write(blob->url());
  573. write(blob->type());
  574. write(blob->size());
  575. return true;
  576. }
  577. if (obj->inherits(&JSImageData::s_info)) {
  578. ImageData* data = toImageData(obj);
  579. write(ImageDataTag);
  580. write(data->width());
  581. write(data->height());
  582. write(data->data()->length());
  583. write(data->data()->data(), data->data()->length());
  584. return true;
  585. }
  586. if (obj->inherits(&RegExpObject::s_info)) {
  587. RegExpObject* regExp = asRegExpObject(obj);
  588. char flags[3];
  589. int flagCount = 0;
  590. if (regExp->regExp()->global())
  591. flags[flagCount++] = 'g';
  592. if (regExp->regExp()->ignoreCase())
  593. flags[flagCount++] = 'i';
  594. if (regExp->regExp()->multiline())
  595. flags[flagCount++] = 'm';
  596. write(RegExpTag);
  597. write(regExp->regExp()->pattern());
  598. write(String(flags, flagCount));
  599. return true;
  600. }
  601. if (obj->inherits(&JSMessagePort::s_info)) {
  602. ObjectPool::iterator index = m_transferredMessagePorts.find(obj);
  603. if (index != m_transferredMessagePorts.end()) {
  604. write(MessagePortReferenceTag);
  605. write(index->value);
  606. return true;
  607. }
  608. // MessagePort object could not be found in transferred message ports
  609. code = ValidationError;
  610. return true;
  611. }
  612. if (obj->inherits(&JSArrayBuffer::s_info)) {
  613. RefPtr<ArrayBuffer> arrayBuffer = toArrayBuffer(obj);
  614. if (arrayBuffer->isNeutered()) {
  615. code = ValidationError;
  616. return true;
  617. }
  618. ObjectPool::iterator index = m_transferredArrayBuffers.find(obj);
  619. if (index != m_transferredArrayBuffers.end()) {
  620. write(ArrayBufferTransferTag);
  621. write(index->value);
  622. return true;
  623. }
  624. if (!startObjectInternal(obj)) // handle duplicates
  625. return true;
  626. write(ArrayBufferTag);
  627. write(arrayBuffer->byteLength());
  628. write(static_cast<const uint8_t *>(arrayBuffer->data()), arrayBuffer->byteLength());
  629. return true;
  630. }
  631. if (obj->inherits(&JSArrayBufferView::s_info)) {
  632. if (checkForDuplicate(obj))
  633. return true;
  634. bool success = dumpArrayBufferView(obj, code);
  635. recordObject(obj);
  636. return success;
  637. }
  638. return false;
  639. }
  640. // Any other types are expected to serialize as null.
  641. write(NullTag);
  642. return true;
  643. }
  644. void write(SerializationTag tag)
  645. {
  646. writeLittleEndian<uint8_t>(m_buffer, static_cast<uint8_t>(tag));
  647. }
  648. void write(ArrayBufferViewSubtag tag)
  649. {
  650. writeLittleEndian<uint8_t>(m_buffer, static_cast<uint8_t>(tag));
  651. }
  652. void write(uint8_t c)
  653. {
  654. writeLittleEndian(m_buffer, c);
  655. }
  656. void write(uint32_t i)
  657. {
  658. writeLittleEndian(m_buffer, i);
  659. }
  660. void write(double d)
  661. {
  662. union {
  663. double d;
  664. int64_t i;
  665. } u;
  666. u.d = d;
  667. writeLittleEndian(m_buffer, u.i);
  668. }
  669. void write(int32_t i)
  670. {
  671. writeLittleEndian(m_buffer, i);
  672. }
  673. void write(unsigned long long i)
  674. {
  675. writeLittleEndian(m_buffer, i);
  676. }
  677. void write(uint16_t ch)
  678. {
  679. writeLittleEndian(m_buffer, ch);
  680. }
  681. void writeStringIndex(unsigned i)
  682. {
  683. writeConstantPoolIndex(m_constantPool, i);
  684. }
  685. void writeObjectIndex(unsigned i)
  686. {
  687. writeConstantPoolIndex(m_objectPool, i);
  688. }
  689. template <class T> void writeConstantPoolIndex(const T& constantPool, unsigned i)
  690. {
  691. ASSERT(static_cast<int32_t>(i) < constantPool.size());
  692. if (constantPool.size() <= 0xFF)
  693. write(static_cast<uint8_t>(i));
  694. else if (constantPool.size() <= 0xFFFF)
  695. write(static_cast<uint16_t>(i));
  696. else
  697. write(static_cast<uint32_t>(i));
  698. }
  699. void write(const Identifier& ident)
  700. {
  701. const String& str = ident.string();
  702. StringConstantPool::AddResult addResult = m_constantPool.add(str.impl(), m_constantPool.size());
  703. if (!addResult.isNewEntry) {
  704. write(StringPoolTag);
  705. writeStringIndex(addResult.iterator->value);
  706. return;
  707. }
  708. // This condition is unlikely to happen as they would imply an ~8gb
  709. // string but we should guard against it anyway
  710. if (str.length() >= StringPoolTag) {
  711. fail();
  712. return;
  713. }
  714. // Guard against overflow
  715. if (str.length() > (numeric_limits<uint32_t>::max() - sizeof(uint32_t)) / sizeof(UChar)) {
  716. fail();
  717. return;
  718. }
  719. writeLittleEndian<uint32_t>(m_buffer, str.length());
  720. if (!writeLittleEndian<uint16_t>(m_buffer, reinterpret_cast<const uint16_t*>(str.characters()), str.length()))
  721. fail();
  722. }
  723. void write(const String& str)
  724. {
  725. if (str.isNull())
  726. write(m_emptyIdentifier);
  727. else
  728. write(Identifier(m_exec, str));
  729. }
  730. void write(const File* file)
  731. {
  732. m_blobURLs.append(file->url());
  733. write(file->path());
  734. write(file->url());
  735. write(file->type());
  736. }
  737. void write(const uint8_t* data, unsigned length)
  738. {
  739. m_buffer.append(data, length);
  740. }
  741. Vector<uint8_t>& m_buffer;
  742. Vector<String>& m_blobURLs;
  743. ObjectPool m_objectPool;
  744. ObjectPool m_transferredMessagePorts;
  745. ObjectPool m_transferredArrayBuffers;
  746. typedef HashMap<RefPtr<StringImpl>, uint32_t, IdentifierRepHash> StringConstantPool;
  747. StringConstantPool m_constantPool;
  748. Identifier m_emptyIdentifier;
  749. };
  750. SerializationReturnCode CloneSerializer::serialize(JSValue in)
  751. {
  752. Vector<uint32_t, 16> indexStack;
  753. Vector<uint32_t, 16> lengthStack;
  754. Vector<PropertyNameArray, 16> propertyStack;
  755. Vector<JSObject*, 32> inputObjectStack;
  756. Vector<WalkerState, 16> stateStack;
  757. WalkerState state = StateUnknown;
  758. JSValue inValue = in;
  759. while (1) {
  760. switch (state) {
  761. arrayStartState:
  762. case ArrayStartState: {
  763. ASSERT(isArray(inValue));
  764. if (inputObjectStack.size() > maximumFilterRecursion)
  765. return StackOverflowError;
  766. JSArray* inArray = asArray(inValue);
  767. unsigned length = inArray->length();
  768. if (!startArray(inArray))
  769. break;
  770. inputObjectStack.append(inArray);
  771. indexStack.append(0);
  772. lengthStack.append(length);
  773. // fallthrough
  774. }
  775. arrayStartVisitMember:
  776. case ArrayStartVisitMember: {
  777. JSObject* array = inputObjectStack.last();
  778. uint32_t index = indexStack.last();
  779. if (index == lengthStack.last()) {
  780. indexStack.removeLast();
  781. lengthStack.removeLast();
  782. propertyStack.append(PropertyNameArray(m_exec));
  783. array->methodTable()->getOwnNonIndexPropertyNames(array, m_exec, propertyStack.last(), ExcludeDontEnumProperties);
  784. if (propertyStack.last().size()) {
  785. write(NonIndexPropertiesTag);
  786. indexStack.append(0);
  787. goto objectStartVisitMember;
  788. }
  789. propertyStack.removeLast();
  790. endObject();
  791. inputObjectStack.removeLast();
  792. break;
  793. }
  794. inValue = array->getDirectIndex(m_exec, index);
  795. if (!inValue) {
  796. indexStack.last()++;
  797. goto arrayStartVisitMember;
  798. }
  799. write(index);
  800. SerializationReturnCode terminalCode = SuccessfullyCompleted;
  801. if (dumpIfTerminal(inValue, terminalCode)) {
  802. if (terminalCode != SuccessfullyCompleted)
  803. return terminalCode;
  804. indexStack.last()++;
  805. goto arrayStartVisitMember;
  806. }
  807. stateStack.append(ArrayEndVisitMember);
  808. goto stateUnknown;
  809. }
  810. case ArrayEndVisitMember: {
  811. indexStack.last()++;
  812. goto arrayStartVisitMember;
  813. }
  814. objectStartState:
  815. case ObjectStartState: {
  816. ASSERT(inValue.isObject());
  817. if (inputObjectStack.size() > maximumFilterRecursion)
  818. return StackOverflowError;
  819. JSObject* inObject = asObject(inValue);
  820. if (!startObject(inObject))
  821. break;
  822. // At this point, all supported objects other than Object
  823. // objects have been handled. If we reach this point and
  824. // the input is not an Object object then we should throw
  825. // a DataCloneError.
  826. if (inObject->classInfo() != &JSFinalObject::s_info)
  827. return DataCloneError;
  828. inputObjectStack.append(inObject);
  829. indexStack.append(0);
  830. propertyStack.append(PropertyNameArray(m_exec));
  831. inObject->methodTable()->getOwnPropertyNames(inObject, m_exec, propertyStack.last(), ExcludeDontEnumProperties);
  832. // fallthrough
  833. }
  834. objectStartVisitMember:
  835. case ObjectStartVisitMember: {
  836. JSObject* object = inputObjectStack.last();
  837. uint32_t index = indexStack.last();
  838. PropertyNameArray& properties = propertyStack.last();
  839. if (index == properties.size()) {
  840. endObject();
  841. inputObjectStack.removeLast();
  842. indexStack.removeLast();
  843. propertyStack.removeLast();
  844. break;
  845. }
  846. inValue = getProperty(object, properties[index]);
  847. if (shouldTerminate())
  848. return ExistingExceptionError;
  849. if (!inValue) {
  850. // Property was removed during serialisation
  851. indexStack.last()++;
  852. goto objectStartVisitMember;
  853. }
  854. write(properties[index]);
  855. if (shouldTerminate())
  856. return ExistingExceptionError;
  857. SerializationReturnCode terminalCode = SuccessfullyCompleted;
  858. if (!dumpIfTerminal(inValue, terminalCode)) {
  859. stateStack.append(ObjectEndVisitMember);
  860. goto stateUnknown;
  861. }
  862. if (terminalCode != SuccessfullyCompleted)
  863. return terminalCode;
  864. // fallthrough
  865. }
  866. case ObjectEndVisitMember: {
  867. if (shouldTerminate())
  868. return ExistingExceptionError;
  869. indexStack.last()++;
  870. goto objectStartVisitMember;
  871. }
  872. stateUnknown:
  873. case StateUnknown: {
  874. SerializationReturnCode terminalCode = SuccessfullyCompleted;
  875. if (dumpIfTerminal(inValue, terminalCode)) {
  876. if (terminalCode != SuccessfullyCompleted)
  877. return terminalCode;
  878. break;
  879. }
  880. if (isArray(inValue))
  881. goto arrayStartState;
  882. goto objectStartState;
  883. }
  884. }
  885. if (stateStack.isEmpty())
  886. break;
  887. state = stateStack.last();
  888. stateStack.removeLast();
  889. }
  890. if (m_failed)
  891. return UnspecifiedError;
  892. return SuccessfullyCompleted;
  893. }
  894. typedef Vector<WTF::ArrayBufferContents> ArrayBufferContentsArray;
  895. class CloneDeserializer : CloneBase {
  896. public:
  897. static String deserializeString(const Vector<uint8_t>& buffer)
  898. {
  899. if (buffer.isEmpty())
  900. return String();
  901. const uint8_t* ptr = buffer.begin();
  902. const uint8_t* end = buffer.end();
  903. uint32_t version;
  904. if (!readLittleEndian(ptr, end, version) || version > CurrentVersion)
  905. return String();
  906. uint8_t tag;
  907. if (!readLittleEndian(ptr, end, tag) || tag != StringTag)
  908. return String();
  909. uint32_t length;
  910. if (!readLittleEndian(ptr, end, length) || length >= StringPoolTag)
  911. return String();
  912. String str;
  913. if (!readString(ptr, end, str, length))
  914. return String();
  915. return String(str.impl());
  916. }
  917. static DeserializationResult deserialize(ExecState* exec, JSGlobalObject* globalObject,
  918. MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContentsArray,
  919. const Vector<uint8_t>& buffer)
  920. {
  921. if (!buffer.size())
  922. return make_pair(jsNull(), UnspecifiedError);
  923. CloneDeserializer deserializer(exec, globalObject, messagePorts, arrayBufferContentsArray, buffer);
  924. if (!deserializer.isValid())
  925. return make_pair(JSValue(), ValidationError);
  926. return deserializer.deserialize();
  927. }
  928. private:
  929. struct CachedString {
  930. CachedString(const String& string)
  931. : m_string(string)
  932. {
  933. }
  934. JSValue jsString(ExecState* exec)
  935. {
  936. if (!m_jsString)
  937. m_jsString = JSC::jsString(exec, m_string);
  938. return m_jsString;
  939. }
  940. const String& string() { return m_string; }
  941. private:
  942. String m_string;
  943. JSValue m_jsString;
  944. };
  945. struct CachedStringRef {
  946. CachedStringRef()
  947. : m_base(0)
  948. , m_index(0)
  949. {
  950. }
  951. CachedStringRef(Vector<CachedString>* base, size_t index)
  952. : m_base(base)
  953. , m_index(index)
  954. {
  955. }
  956. CachedString* operator->() { ASSERT(m_base); return &m_base->at(m_index); }
  957. private:
  958. Vector<CachedString>* m_base;
  959. size_t m_index;
  960. };
  961. CloneDeserializer(ExecState* exec, JSGlobalObject* globalObject,
  962. MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContents,
  963. const Vector<uint8_t>& buffer)
  964. : CloneBase(exec)
  965. , m_globalObject(globalObject)
  966. , m_isDOMGlobalObject(globalObject->inherits(&JSDOMGlobalObject::s_info))
  967. , m_ptr(buffer.data())
  968. , m_end(buffer.data() + buffer.size())
  969. , m_version(0xFFFFFFFF)
  970. , m_messagePorts(messagePorts)
  971. , m_arrayBufferContents(arrayBufferContents)
  972. , m_arrayBuffers(arrayBufferContents ? arrayBufferContents->size() : 0)
  973. {
  974. if (!read(m_version))
  975. m_version = 0xFFFFFFFF;
  976. }
  977. DeserializationResult deserialize();
  978. void throwValidationError()
  979. {
  980. throwError(m_exec, createTypeError(m_exec, "Unable to deserialize data."));
  981. }
  982. bool isValid() const { return m_version <= CurrentVersion; }
  983. template <typename T> bool readLittleEndian(T& value)
  984. {
  985. if (m_failed || !readLittleEndian(m_ptr, m_end, value)) {
  986. fail();
  987. return false;
  988. }
  989. return true;
  990. }
  991. #if ASSUME_LITTLE_ENDIAN
  992. template <typename T> static bool readLittleEndian(const uint8_t*& ptr, const uint8_t* end, T& value)
  993. {
  994. if (ptr > end - sizeof(value))
  995. return false;
  996. if (sizeof(T) == 1)
  997. value = *ptr++;
  998. else {
  999. value = *reinterpret_cast<const T*>(ptr);
  1000. ptr += sizeof(T);
  1001. }
  1002. return true;
  1003. }
  1004. #else
  1005. template <typename T> static bool readLittleEndian(const uint8_t*& ptr, const uint8_t* end, T& value)
  1006. {
  1007. if (ptr > end - sizeof(value))
  1008. return false;
  1009. if (sizeof(T) == 1)
  1010. value = *ptr++;
  1011. else {
  1012. value = 0;
  1013. for (unsigned i = 0; i < sizeof(T); i++)
  1014. value += ((T)*ptr++) << (i * 8);
  1015. }
  1016. return true;
  1017. }
  1018. #endif
  1019. bool read(uint32_t& i)
  1020. {
  1021. return readLittleEndian(i);
  1022. }
  1023. bool read(int32_t& i)
  1024. {
  1025. return readLittleEndian(*reinterpret_cast<uint32_t*>(&i));
  1026. }
  1027. bool read(uint16_t& i)
  1028. {
  1029. return readLittleEndian(i);
  1030. }
  1031. bool read(uint8_t& i)
  1032. {
  1033. return readLittleEndian(i);
  1034. }
  1035. bool read(double& d)
  1036. {
  1037. union {
  1038. double d;
  1039. uint64_t i64;
  1040. } u;
  1041. if (!readLittleEndian(u.i64))
  1042. return false;
  1043. d = u.d;
  1044. return true;
  1045. }
  1046. bool read(unsigned long long& i)
  1047. {
  1048. return readLittleEndian(i);
  1049. }
  1050. bool readStringIndex(uint32_t& i)
  1051. {
  1052. return readConstantPoolIndex(m_constantPool, i);
  1053. }
  1054. template <class T> bool readConstantPoolIndex(const T& constantPool, uint32_t& i)
  1055. {
  1056. if (constantPool.size() <= 0xFF) {
  1057. uint8_t i8;
  1058. if (!read(i8))
  1059. return false;
  1060. i = i8;
  1061. return true;
  1062. }
  1063. if (constantPool.size() <= 0xFFFF) {
  1064. uint16_t i16;
  1065. if (!read(i16))
  1066. return false;
  1067. i = i16;
  1068. return true;
  1069. }
  1070. return read(i);
  1071. }
  1072. static bool readString(const uint8_t*& ptr, const uint8_t* end, String& str, unsigned length)
  1073. {
  1074. if (length >= numeric_limits<int32_t>::max() / sizeof(UChar))
  1075. return false;
  1076. unsigned size = length * sizeof(UChar);
  1077. if ((end - ptr) < static_cast<int>(size))
  1078. return false;
  1079. #if ASSUME_LITTLE_ENDIAN
  1080. str = String(reinterpret_cast<const UChar*>(ptr), length);
  1081. ptr += length * sizeof(UChar);
  1082. #else
  1083. Vector<UChar> buffer;
  1084. buffer.reserveCapacity(length);
  1085. for (unsigned i = 0; i < length; i++) {
  1086. uint16_t ch;
  1087. readLittleEndian(ptr, end, ch);
  1088. buffer.append(ch);
  1089. }
  1090. str = String::adopt(buffer);
  1091. #endif
  1092. return true;
  1093. }
  1094. bool readStringData(CachedStringRef& cachedString)
  1095. {
  1096. bool scratch;
  1097. return readStringData(cachedString, scratch);
  1098. }
  1099. bool readStringData(CachedStringRef& cachedString, bool& wasTerminator)
  1100. {
  1101. if (m_failed)
  1102. return false;
  1103. uint32_t length = 0;
  1104. if (!read(length))
  1105. return false;
  1106. if (length == TerminatorTag) {
  1107. wasTerminator = true;
  1108. return false;
  1109. }
  1110. if (length == StringPoolTag) {
  1111. unsigned index = 0;
  1112. if (!readStringIndex(index)) {
  1113. fail();
  1114. return false;
  1115. }
  1116. if (index >= m_constantPool.size()) {
  1117. fail();
  1118. return false;
  1119. }
  1120. cachedString = CachedStringRef(&m_constantPool, index);
  1121. return true;
  1122. }
  1123. String str;
  1124. if (!readString(m_ptr, m_end, str, length)) {
  1125. fail();
  1126. return false;
  1127. }
  1128. m_constantPool.append(str);
  1129. cachedString = CachedStringRef(&m_constantPool, m_constantPool.size() - 1);
  1130. return true;
  1131. }
  1132. SerializationTag readTag()
  1133. {
  1134. if (m_ptr >= m_end)
  1135. return ErrorTag;
  1136. return static_cast<SerializationTag>(*m_ptr++);
  1137. }
  1138. bool readArrayBufferViewSubtag(ArrayBufferViewSubtag& tag)
  1139. {
  1140. if (m_ptr >= m_end)
  1141. return false;
  1142. tag = static_cast<ArrayBufferViewSubtag>(*m_ptr++);
  1143. return true;
  1144. }
  1145. void putProperty(JSObject* object, unsigned index, JSValue value)
  1146. {
  1147. object->putDirectIndex(m_exec, index, value);
  1148. }
  1149. void putProperty(JSObject* object, const Identifier& property, JSValue value)
  1150. {
  1151. object->putDirectMayBeIndex(m_exec, property, value);
  1152. }
  1153. bool readFile(RefPtr<File>& file)
  1154. {
  1155. CachedStringRef path;
  1156. if (!readStringData(path))
  1157. return 0;
  1158. CachedStringRef url;
  1159. if (!readStringData(url))
  1160. return 0;
  1161. CachedStringRef type;
  1162. if (!readStringData(type))
  1163. return 0;
  1164. if (m_isDOMGlobalObject)
  1165. file = File::create(path->string(), KURL(KURL(), url->string()), type->string());
  1166. return true;
  1167. }
  1168. bool readArrayBuffer(RefPtr<ArrayBuffer>& arrayBuffer)
  1169. {
  1170. uint32_t length;
  1171. if (!read(length))
  1172. return false;
  1173. if (m_ptr + length > m_end)
  1174. return false;
  1175. arrayBuffer = ArrayBuffer::create(m_ptr, length);
  1176. m_ptr += length;
  1177. return true;
  1178. }
  1179. bool readArrayBufferView(JSValue& arrayBufferView)
  1180. {
  1181. ArrayBufferViewSubtag arrayBufferViewSubtag;
  1182. if (!readArrayBufferViewSubtag(arrayBufferViewSubtag))
  1183. return false;
  1184. uint32_t byteOffset;
  1185. if (!read(byteOffset))
  1186. return false;
  1187. uint32_t byteLength;
  1188. if (!read(byteLength))
  1189. return false;
  1190. JSObject* arrayBufferObj = asObject(readTerminal());
  1191. if (!arrayBufferObj || !arrayBufferObj->inherits(&JSArrayBuffer::s_info))
  1192. return false;
  1193. unsigned elementSize = typedArrayElementSize(arrayBufferViewSubtag);
  1194. if (!elementSize)
  1195. return false;
  1196. unsigned length = byteLength / elementSize;
  1197. if (length * elementSize != byteLength)
  1198. return false;
  1199. RefPtr<ArrayBuffer> arrayBuffer = toArrayBuffer(arrayBufferObj);
  1200. switch (arrayBufferViewSubtag) {
  1201. case DataViewTag:
  1202. arrayBufferView = getJSValue(DataView::create(arrayBuffer, byteOffset, length).get());
  1203. return true;
  1204. case Int8ArrayTag:
  1205. arrayBufferView = getJSValue(Int8Array::create(arrayBuffer, byteOffset, length).get());
  1206. return true;
  1207. case Uint8ArrayTag:
  1208. arrayBufferView = getJSValue(Uint8Array::create(arrayBuffer, byteOffset, length).get());
  1209. return true;
  1210. case Uint8ClampedArrayTag:
  1211. arrayBufferView = getJSValue(Uint8ClampedArray::create(arrayBuffer, byteOffset, length).get());
  1212. return true;
  1213. case Int16ArrayTag:
  1214. arrayBufferView = getJSValue(Int16Array::create(arrayBuffer, byteOffset, length).get());
  1215. return true;
  1216. case Uint16ArrayTag:
  1217. arrayBufferView = getJSValue(Uint16Array::create(arrayBuffer, byteOffset, length).get());
  1218. return true;
  1219. case Int32ArrayTag:
  1220. arrayBufferView = getJSValue(Int32Array::create(arrayBuffer, byteOffset, length).get());
  1221. return true;
  1222. case Uint32ArrayTag:
  1223. arrayBufferView = getJSValue(Uint32Array::create(arrayBuffer, byteOffset, length).get());
  1224. return true;
  1225. case Float32ArrayTag:
  1226. arrayBufferView = getJSValue(Float32Array::create(arrayBuffer, byteOffset, length).get());
  1227. return true;
  1228. case Float64ArrayTag:
  1229. arrayBufferView = getJSValue(Float64Array::create(arrayBuffer, byteOffset, length).get());
  1230. return true;
  1231. default:
  1232. return false;
  1233. }
  1234. }
  1235. template<class T>
  1236. JSValue getJSValue(T* nativeObj)
  1237. {
  1238. return toJS(m_exec, jsCast<JSDOMGlobalObject*>(m_globalObject), nativeObj);
  1239. }
  1240. JSValue readTerminal()
  1241. {
  1242. SerializationTag tag = readTag();
  1243. switch (tag) {
  1244. case UndefinedTag:
  1245. return jsUndefined();
  1246. case NullTag:
  1247. return jsNull();
  1248. case IntTag: {
  1249. int32_t i;
  1250. if (!read(i))
  1251. return JSValue();
  1252. return jsNumber(i);
  1253. }
  1254. case ZeroTag:
  1255. return jsNumber(0);
  1256. case OneTag:
  1257. return jsNumber(1);
  1258. case FalseTag:
  1259. return jsBoolean(false);
  1260. case TrueTag:
  1261. return jsBoolean(true);
  1262. case FalseObjectTag: {
  1263. BooleanObject* obj = BooleanObject::create(m_exec->vm(), m_globalObject->booleanObjectStructure());
  1264. obj->setInternalValue(m_exec->vm(), jsBoolean(false));
  1265. m_gcBuffer.append(obj);
  1266. return obj;
  1267. }
  1268. case TrueObjectTag: {
  1269. BooleanObject* obj = BooleanObject::create(m_exec->vm(), m_globalObject->booleanObjectStructure());
  1270. obj->setInternalValue(m_exec->vm(), jsBoolean(true));
  1271. m_gcBuffer.append(obj);
  1272. return obj;
  1273. }
  1274. case DoubleTag: {
  1275. double d;
  1276. if (!read(d))
  1277. return JSValue();
  1278. return jsNumber(d);
  1279. }
  1280. case NumberObjectTag: {
  1281. double d;
  1282. if (!read(d))
  1283. return JSValue();
  1284. NumberObject* obj = constructNumber(m_exec, m_globalObject, jsNumber(d));
  1285. m_gcBuffer.append(obj);
  1286. return obj;
  1287. }
  1288. case DateTag: {
  1289. double d;
  1290. if (!read(d))
  1291. return JSValue();
  1292. return DateInstance::create(m_exec, m_globalObject->dateStructure(), d);
  1293. }
  1294. case FileTag: {
  1295. RefPtr<File> file;
  1296. if (!readFile(file))
  1297. return JSValue();
  1298. if (!m_isDOMGlobalObject)
  1299. return jsNull();
  1300. return toJS(m_exec, jsCast<JSDOMGlobalObject*>(m_globalObject), file.get());
  1301. }
  1302. case FileListTag: {
  1303. unsigned length = 0;
  1304. if (!read(length))
  1305. return JSValue();
  1306. RefPtr<FileList> result = FileList::create();
  1307. for (unsigned i = 0; i < length; i++) {
  1308. RefPtr<File> file;
  1309. if (!readFile(file))
  1310. return JSValue();
  1311. if (m_isDOMGlobalObject)
  1312. result->append(file.get());
  1313. }
  1314. if (!m_isDOMGlobalObject)
  1315. return jsNull();
  1316. return getJSValue(result.get());
  1317. }
  1318. case ImageDataTag: {
  1319. int32_t width;
  1320. if (!read(width))
  1321. return JSValue();
  1322. int32_t height;
  1323. if (!read(height))
  1324. return JSValue();
  1325. uint32_t length;
  1326. if (!read(length))
  1327. return JSValue();
  1328. if (m_end < ((uint8_t*)0) + length || m_ptr > m_end - length) {
  1329. fail();
  1330. return JSValue();
  1331. }
  1332. if (!m_isDOMGlobalObject) {
  1333. m_ptr += length;
  1334. return jsNull();
  1335. }
  1336. RefPtr<ImageData> result = ImageData::create(IntSize(width, height));
  1337. memcpy(result->data()->data(), m_ptr, length);
  1338. m_ptr += length;
  1339. return getJSValue(result.get());
  1340. }
  1341. case BlobTag: {
  1342. CachedStringRef url;
  1343. if (!readStringData(url))
  1344. return JSValue();
  1345. CachedStringRef type;
  1346. if (!readStringData(type))
  1347. return JSValue();
  1348. unsigned long long size = 0;
  1349. if (!read(size))
  1350. return JSValue();
  1351. if (!m_isDOMGlobalObject)
  1352. return jsNull();
  1353. return getJSValue(Blob::create(KURL(KURL(), url->string()), type->string(), size).get());
  1354. }
  1355. case StringTag: {
  1356. CachedStringRef cachedString;
  1357. if (!readStringData(cachedString))
  1358. return JSValue();
  1359. return cachedString->jsString(m_exec);
  1360. }
  1361. case EmptyStringTag:
  1362. return jsEmptyString(&m_exec->vm());
  1363. case StringObjectTag: {
  1364. CachedStringRef cachedString;
  1365. if (!readStringData(cachedString))
  1366. return JSValue();
  1367. StringObject* obj = constructString(m_exec, m_globalObject, cachedString->jsString(m_exec));
  1368. m_gcBuffer.append(obj);
  1369. return obj;
  1370. }
  1371. case EmptyStringObjectTag: {
  1372. StringObject* obj = constructString(m_exec, m_globalObject, jsEmptyString(&m_exec->vm()));
  1373. m_gcBuffer.append(obj);
  1374. return obj;
  1375. }
  1376. case RegExpTag: {
  1377. CachedStringRef pattern;
  1378. if (!readStringData(pattern))
  1379. return JSValue();
  1380. CachedStringRef flags;
  1381. if (!readStringData(flags))
  1382. return JSValue();
  1383. RegExpFlags reFlags = regExpFlags(flags->string());
  1384. ASSERT(reFlags != InvalidFlags);
  1385. RegExp* regExp = RegExp::create(m_exec->vm(), pattern->string(), reFlags);
  1386. return RegExpObject::create(m_exec, m_exec->lexicalGlobalObject(), m_globalObject->regExpStructure(), regExp);
  1387. }
  1388. case ObjectReferenceTag: {
  1389. unsigned index = 0;
  1390. if (!readConstantPoolIndex(m_gcBuffer, index)) {
  1391. fail();
  1392. return JSValue();
  1393. }
  1394. return m_gcBuffer.at(index);
  1395. }
  1396. case MessagePortReferenceTag: {
  1397. uint32_t index;
  1398. bool indexSuccessfullyRead = read(index);
  1399. if (!indexSuccessfullyRead || !m_messagePorts || index >= m_messagePorts->size()) {
  1400. fail();
  1401. return JSValue();
  1402. }
  1403. return getJSValue(m_messagePorts->at(index).get());
  1404. }
  1405. case ArrayBufferTag: {
  1406. RefPtr<ArrayBuffer> arrayBuffer;
  1407. if (!readArrayBuffer(arrayBuffer)) {
  1408. fail();
  1409. return JSValue();
  1410. }
  1411. JSValue result = getJSValue(arrayBuffer.get());
  1412. m_gcBuffer.append(result);
  1413. return result;
  1414. }
  1415. case ArrayBufferTransferTag: {
  1416. uint32_t index;
  1417. bool indexSuccessfullyRead = read(index);
  1418. if (!indexSuccessfullyRead || index >= m_arrayBuffers.size()) {
  1419. fail();
  1420. return JSValue();
  1421. }
  1422. if (!m_arrayBuffers[index])
  1423. m_arrayBuffers[index] = ArrayBuffer::create(m_arrayBufferContents->at(index));
  1424. return getJSValue(m_arrayBuffers[index].get());
  1425. }
  1426. case ArrayBufferViewTag: {
  1427. JSValue arrayBufferView;
  1428. if (!readArrayBufferView(arrayBufferView)) {
  1429. fail();
  1430. return JSValue();
  1431. }
  1432. m_gcBuffer.append(arrayBufferView);
  1433. return arrayBufferView;
  1434. }
  1435. default:
  1436. m_ptr--; // Push the tag back
  1437. return JSValue();
  1438. }
  1439. }
  1440. JSGlobalObject* m_globalObject;
  1441. bool m_isDOMGlobalObject;
  1442. const uint8_t* m_ptr;
  1443. const uint8_t* m_end;
  1444. unsigned m_version;
  1445. Vector<CachedString> m_constantPool;
  1446. MessagePortArray* m_messagePorts;
  1447. ArrayBufferContentsArray* m_arrayBufferContents;
  1448. ArrayBufferArray m_arrayBuffers;
  1449. };
  1450. DeserializationResult CloneDeserializer::deserialize()
  1451. {
  1452. Vector<uint32_t, 16> indexStack;
  1453. Vector<Identifier, 16> propertyNameStack;
  1454. Vector<JSObject*, 32> outputObjectStack;
  1455. Vector<WalkerState, 16> stateStack;
  1456. WalkerState state = StateUnknown;
  1457. JSValue outValue;
  1458. while (1) {
  1459. switch (state) {
  1460. arrayStartState:
  1461. case ArrayStartState: {
  1462. uint32_t length;
  1463. if (!read(length)) {
  1464. fail();
  1465. goto error;
  1466. }
  1467. JSArray* outArray = constructEmptyArray(m_exec, 0, m_globalObject, length);
  1468. m_gcBuffer.append(outArray);
  1469. outputObjectStack.append(outArray);
  1470. // fallthrough
  1471. }
  1472. arrayStartVisitMember:
  1473. case ArrayStartVisitMember: {
  1474. uint32_t index;
  1475. if (!read(index)) {
  1476. fail();
  1477. goto error;
  1478. }
  1479. if (index == TerminatorTag) {
  1480. JSObject* outArray = outputObjectStack.last();
  1481. outValue = outArray;
  1482. outputObjectStack.removeLast();
  1483. break;
  1484. } else if (index == NonIndexPropertiesTag) {
  1485. goto objectStartVisitMember;
  1486. }
  1487. if (JSValue terminal = readTerminal()) {
  1488. putProperty(outputObjectStack.last(), index, terminal);
  1489. goto arrayStartVisitMember;
  1490. }
  1491. if (m_failed)
  1492. goto error;
  1493. indexStack.append(index);
  1494. stateStack.append(ArrayEndVisitMember);
  1495. goto stateUnknown;
  1496. }
  1497. case ArrayEndVisitMember: {
  1498. JSObject* outArray = outputObjectStack.last();
  1499. putProperty(outArray, indexStack.last(), outValue);
  1500. indexStack.removeLast();
  1501. goto arrayStartVisitMember;
  1502. }
  1503. objectStartState:
  1504. case ObjectStartState: {
  1505. if (outputObjectStack.size() > maximumFilterRecursion)
  1506. return make_pair(JSValue(), StackOverflowError);
  1507. JSObject* outObject = constructEmptyObject(m_exec, m_globalObject->objectPrototype());
  1508. m_gcBuffer.append(outObject);
  1509. outputObjectStack.append(outObject);
  1510. // fallthrough
  1511. }
  1512. objectStartVisitMember:
  1513. case ObjectStartVisitMember: {
  1514. CachedStringRef cachedString;
  1515. bool wasTerminator = false;
  1516. if (!readStringData(cachedString, wasTerminator)) {
  1517. if (!wasTerminator)
  1518. goto error;
  1519. JSObject* outObject = outputObjectStack.last();
  1520. outValue = outObject;
  1521. outputObjectStack.removeLast();
  1522. break;
  1523. }
  1524. if (JSValue terminal = readTerminal()) {
  1525. putProperty(outputObjectStack.last(), Identifier(m_exec, cachedString->string()), terminal);
  1526. goto objectStartVisitMember;
  1527. }
  1528. stateStack.append(ObjectEndVisitMember);
  1529. propertyNameStack.append(Identifier(m_exec, cachedString->string()));
  1530. goto stateUnknown;
  1531. }
  1532. case ObjectEndVisitMember: {
  1533. putProperty(outputObjectStack.last(), propertyNameStack.last(), outValue);
  1534. propertyNameStack.removeLast();
  1535. goto objectStartVisitMember;
  1536. }
  1537. stateUnknown:
  1538. case StateUnknown:
  1539. if (JSValue terminal = readTerminal()) {
  1540. outValue = terminal;
  1541. break;
  1542. }
  1543. SerializationTag tag = readTag();
  1544. if (tag == ArrayTag)
  1545. goto arrayStartState;
  1546. if (tag == ObjectTag)
  1547. goto objectStartState;
  1548. goto error;
  1549. }
  1550. if (stateStack.isEmpty())
  1551. break;
  1552. state = stateStack.last();
  1553. stateStack.removeLast();
  1554. }
  1555. ASSERT(outValue);
  1556. ASSERT(!m_failed);
  1557. return make_pair(outValue, SuccessfullyCompleted);
  1558. error:
  1559. fail();
  1560. return make_pair(JSValue(), ValidationError);
  1561. }
  1562. void SerializedScriptValue::addBlobURL(const String& string)
  1563. {
  1564. m_blobURLs.append(Vector<uint16_t>());
  1565. m_blobURLs.last().reserveCapacity(string.length());
  1566. for (size_t i = 0; i < string.length(); i++)
  1567. m_blobURLs.last().append(string.characterAt(i));
  1568. m_blobURLs.last().resize(m_blobURLs.last().size());
  1569. }
  1570. SerializedScriptValue::~SerializedScriptValue()
  1571. {
  1572. }
  1573. SerializedScriptValue::SerializedScriptValue(const Vector<uint8_t>& buffer)
  1574. : m_data(buffer)
  1575. {
  1576. }
  1577. SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>& buffer)
  1578. {
  1579. m_data.swap(buffer);
  1580. }
  1581. SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>& buffer, Vector<String>& blobURLs)
  1582. {
  1583. m_data.swap(buffer);
  1584. for (auto& string : blobURLs)
  1585. addBlobURL(string);
  1586. }
  1587. SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>& buffer, Vector<String>& blobURLs, PassOwnPtr<ArrayBufferContentsArray> arrayBufferContentsArray)
  1588. : m_arrayBufferContentsArray(arrayBufferContentsArray)
  1589. {
  1590. m_data.swap(buffer);
  1591. for (auto& string : blobURLs)
  1592. addBlobURL(string);
  1593. }
  1594. static void neuterView(JSCell* jsView)
  1595. {
  1596. if (!jsView)
  1597. return;
  1598. switch (jsView->classInfo()->typedArrayStorageType) {
  1599. case TypedArrayNone:
  1600. // This could be a DataView, for example. Assume that there are views that the
  1601. // DFG doesn't care about.
  1602. return;
  1603. case TypedArrayInt8:
  1604. jsCast<JSInt8Array*>(jsView)->m_storageLength = 0;
  1605. return;
  1606. case TypedArrayInt16:
  1607. jsCast<JSInt16Array*>(jsView)->m_storageLength = 0;
  1608. return;
  1609. case TypedArrayInt32:
  1610. jsCast<JSInt32Array*>(jsView)->m_storageLength = 0;
  1611. return;
  1612. case TypedArrayUint8:
  1613. jsCast<JSUint8Array*>(jsView)->m_storageLength = 0;
  1614. return;
  1615. case TypedArrayUint8Clamped:
  1616. jsCast<JSUint8ClampedArray*>(jsView)->m_storageLength = 0;
  1617. return;
  1618. case TypedArrayUint16:
  1619. jsCast<JSUint16Array*>(jsView)->m_storageLength = 0;
  1620. return;
  1621. case TypedArrayUint32:
  1622. jsCast<JSUint32Array*>(jsView)->m_storageLength = 0;
  1623. return;
  1624. case TypedArrayFloat32:
  1625. jsCast<JSFloat32Array*>(jsView)->m_storageLength = 0;
  1626. return;
  1627. case TypedArrayFloat64:
  1628. jsCast<JSFloat64Array*>(jsView)->m_storageLength = 0;
  1629. return;
  1630. }
  1631. RELEASE_ASSERT_NOT_REACHED();
  1632. }
  1633. PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValue::transferArrayBuffers(
  1634. ExecState* exec, ArrayBufferArray& arrayBuffers, SerializationReturnCode& code)
  1635. {
  1636. for (size_t i = 0; i < arrayBuffers.size(); i++) {
  1637. if (arrayBuffers[i]->isNeutered()) {
  1638. code = ValidationError;
  1639. return nullptr;
  1640. }
  1641. }
  1642. OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContentsArray(arrayBuffers.size()));
  1643. Vector<RefPtr<DOMWrapperWorld> > worlds;
  1644. static_cast<WebCoreJSClientData*>(exec->vm().clientData)->getAllWorlds(worlds);
  1645. HashSet<WTF::ArrayBuffer*> visited;
  1646. for (size_t arrayBufferIndex = 0; arrayBufferIndex < arrayBuffers.size(); arrayBufferIndex++) {
  1647. Vector<RefPtr<ArrayBufferView> > neuteredViews;
  1648. if (visited.contains(arrayBuffers[arrayBufferIndex].get()))
  1649. continue;
  1650. visited.add(arrayBuffers[arrayBufferIndex].get());
  1651. bool result = arrayBuffers[arrayBufferIndex]->transfer(contents->at(arrayBufferIndex), neuteredViews);
  1652. if (!result) {
  1653. code = ValidationError;
  1654. return nullptr;
  1655. }
  1656. // The views may have been neutered, but their wrappers also need to be neutered, too.
  1657. for (size_t viewIndex = neuteredViews.size(); viewIndex--;) {
  1658. ArrayBufferView* view = neuteredViews[viewIndex].get();
  1659. for (size_t worldIndex = worlds.size(); worldIndex--;) {
  1660. DOMWrapperWorld* world = worlds[worldIndex].get();
  1661. neuterView(getCachedWrapper(world, view));
  1662. }
  1663. }
  1664. }
  1665. return contents.release();
  1666. }
  1667. PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(ExecState* exec, JSValue value,
  1668. MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers,
  1669. SerializationErrorMode throwExceptions)
  1670. {
  1671. Vector<uint8_t> buffer;
  1672. Vector<String> blobURLs;
  1673. SerializationReturnCode code = CloneSerializer::serialize(exec, value, messagePorts, arrayBuffers, blobURLs, buffer);
  1674. OwnPtr<ArrayBufferContentsArray> arrayBufferContentsArray;
  1675. if (arrayBuffers && serializationDidCompleteSuccessfully(code))
  1676. arrayBufferContentsArray = transferArrayBuffers(exec, *arrayBuffers, code);
  1677. if (throwExceptions == Throwing)
  1678. maybeThrowExceptionIfSerializationFailed(exec, code);
  1679. if (!serializationDidCompleteSuccessfully(code))
  1680. return 0;
  1681. return adoptRef(new SerializedScriptValue(buffer, blobURLs, arrayBufferContentsArray.release()));
  1682. }
  1683. PassRefPtr<SerializedScriptValue> SerializedScriptValue::create()
  1684. {
  1685. Vector<uint8_t> buffer;
  1686. return adoptRef(new SerializedScriptValue(buffer));
  1687. }
  1688. PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const String& string)
  1689. {
  1690. Vector<uint8_t> buffer;
  1691. if (!CloneSerializer::serialize(string, buffer))
  1692. return 0;
  1693. return adoptRef(new SerializedScriptValue(buffer));
  1694. }
  1695. #if ENABLE(INDEXED_DATABASE)
  1696. PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(JSC::ExecState* exec, JSC::JSValue value)
  1697. {
  1698. return SerializedScriptValue::create(exec, value, 0, 0);
  1699. }
  1700. PassRefPtr<SerializedScriptValue> SerializedScriptValue::numberValue(double value)
  1701. {
  1702. Vector<uint8_t> buffer;
  1703. CloneSerializer::serializeNumber(value, buffer);
  1704. return adoptRef(new SerializedScriptValue(buffer));
  1705. }
  1706. JSValue SerializedScriptValue::deserialize(JSC::ExecState* exec, JSC::JSGlobalObject* globalObject)
  1707. {
  1708. return deserialize(exec, globalObject, 0);
  1709. }
  1710. #endif
  1711. PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(JSContextRef originContext, JSValueRef apiValue,
  1712. MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers,
  1713. JSValueRef* exception)
  1714. {
  1715. ExecState* exec = toJS(originContext);
  1716. APIEntryShim entryShim(exec);
  1717. JSValue value = toJS(exec, apiValue);
  1718. RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(exec, value, messagePorts, arrayBuffers);
  1719. if (exec->hadException()) {
  1720. if (exception)
  1721. *exception = toRef(exec, exec->exception());
  1722. exec->clearException();
  1723. return 0;
  1724. }
  1725. ASSERT(serializedValue);
  1726. return serializedValue.release();
  1727. }
  1728. PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(JSContextRef originContext, JSValueRef apiValue,
  1729. JSValueRef* exception)
  1730. {
  1731. return create(originContext, apiValue, 0, 0, exception);
  1732. }
  1733. String SerializedScriptValue::toString()
  1734. {
  1735. return CloneDeserializer::deserializeString(m_data);
  1736. }
  1737. JSValue SerializedScriptValue::deserialize(ExecState* exec, JSGlobalObject* globalObject,
  1738. MessagePortArray* messagePorts, SerializationErrorMode throwExceptions)
  1739. {
  1740. DeserializationResult result = CloneDeserializer::deserialize(exec, globalObject, messagePorts,
  1741. m_arrayBufferContentsArray.get(), m_data);
  1742. if (throwExceptions == Throwing)
  1743. maybeThrowExceptionIfSerializationFailed(exec, result.second);
  1744. return result.first;
  1745. }
  1746. #if ENABLE(INSPECTOR)
  1747. ScriptValue SerializedScriptValue::deserializeForInspector(ScriptState* scriptState)
  1748. {
  1749. JSValue value = deserialize(scriptState, scriptState->lexicalGlobalObject(), 0);
  1750. return ScriptValue(scriptState->vm(), value);
  1751. }
  1752. #endif
  1753. JSValueRef SerializedScriptValue::deserialize(JSContextRef destinationContext, JSValueRef* exception, MessagePortArray* messagePorts)
  1754. {
  1755. ExecState* exec = toJS(destinationContext);
  1756. APIEntryShim entryShim(exec);
  1757. JSValue value = deserialize(exec, exec->lexicalGlobalObject(), messagePorts);
  1758. if (exec->hadException()) {
  1759. if (exception)
  1760. *exception = toRef(exec, exec->exception());
  1761. exec->clearException();
  1762. return 0;
  1763. }
  1764. ASSERT(value);
  1765. return toRef(exec, value);
  1766. }
  1767. JSValueRef SerializedScriptValue::deserialize(JSContextRef destinationContext, JSValueRef* exception)
  1768. {
  1769. return deserialize(destinationContext, exception, 0);
  1770. }
  1771. PassRefPtr<SerializedScriptValue> SerializedScriptValue::nullValue()
  1772. {
  1773. return SerializedScriptValue::create();
  1774. }
  1775. PassRefPtr<SerializedScriptValue> SerializedScriptValue::undefinedValue()
  1776. {
  1777. Vector<uint8_t> buffer;
  1778. CloneSerializer::serializeUndefined(buffer);
  1779. return adoptRef(new SerializedScriptValue(buffer));
  1780. }
  1781. PassRefPtr<SerializedScriptValue> SerializedScriptValue::booleanValue(bool value)
  1782. {
  1783. Vector<uint8_t> buffer;
  1784. CloneSerializer::serializeBoolean(value, buffer);
  1785. return adoptRef(new SerializedScriptValue(buffer));
  1786. }
  1787. void SerializedScriptValue::maybeThrowExceptionIfSerializationFailed(ExecState* exec, SerializationReturnCode code)
  1788. {
  1789. if (code == SuccessfullyCompleted)
  1790. return;
  1791. switch (code) {
  1792. case StackOverflowError:
  1793. throwError(exec, createStackOverflowError(exec));
  1794. break;
  1795. case ValidationError:
  1796. throwError(exec, createTypeError(exec, "Unable to deserialize data."));
  1797. break;
  1798. case DataCloneError:
  1799. setDOMException(exec, DATA_CLONE_ERR);
  1800. break;
  1801. case ExistingExceptionError:
  1802. break;
  1803. case UnspecifiedError:
  1804. break;
  1805. default:
  1806. ASSERT_NOT_REACHED();
  1807. }
  1808. }
  1809. bool SerializedScriptValue::serializationDidCompleteSuccessfully(SerializationReturnCode code)
  1810. {
  1811. return (code == SuccessfullyCompleted);
  1812. }
  1813. uint32_t SerializedScriptValue::wireFormatVersion()
  1814. {
  1815. return CurrentVersion;
  1816. }
  1817. }